首页
归档
笔记
树洞
搜索
友言

文章详情

Interesting People Record Interesting.

/ JavaScript / 文章详情

适合个人用的前端下载图片跨域解决方案

Sonder
2024-11-28
2946字
7分钟
浏览 (194)

复制代码
/**
 * 图片下载器类 - 保持原图下载
 */
class ImageDownloader {
  /**
   * @param {Object} options - 配置选项
   * @param {string} options.proxyUrl - 代理服务器URL(可选)
   */
  constructor(options = {}) {
    this.image = new Image();
    this.proxyUrl =
      options.proxyUrl || "https://api.codetabs.com/v1/proxy?quest=";
    this.canvas = document.createElement("canvas");
    this.ctx = this.canvas.getContext("2d");
  }

  /**
   * 加载图片
   * @param {string} url - 图片URL
   * @returns {Promise} - 返回Promise
   */
  loadImage(url) {
    return new Promise((resolve, reject) => {
      this.image.crossOrigin = "anonymous";

      this.image.onload = () => {
        // 设置canvas尺寸为图片原始尺寸
        this.canvas.width = this.image.width;
        this.canvas.height = this.image.height;
        resolve(this.image);
      };

      this.image.onerror = () => reject(new Error("图片加载失败"));

      // 如果提供了代理URL,则使用代理
      const imageUrl = this.proxyUrl
        ? `${this.proxyUrl}${encodeURIComponent(url)}`
        : url;

      // 添加时间戳防止缓存
      this.image.src = `${imageUrl}${imageUrl.includes("?") ? "&" : "?"}t=${Date.now()}`;
    });
  }

  /**
   * 在画布上绘制原始尺寸的图片
   */
  drawImage() {
    // 清空画布并填充白色背景
    this.ctx.beginPath();
    this.ctx.rect(0, 0, this.canvas.width, this.canvas.height);
    this.ctx.fillStyle = "white";
    this.ctx.fill();

    // 绘制原始尺寸的图片
    this.ctx.drawImage(this.image, 0, 0);
  }

  /**
   * 下载画布上的图片
   * @param {string} filename - 文件名
   * @param {Object} options - 下载选项
   * @param {string} options.type - 图片类型,默认 'image/jpeg'
   * @param {number} options.quality - 图片质量,0-1之间,默认1.0保持最佳质量
   */
  downloadImage(filename, options = {}) {
    const { type = "image/jpeg", quality = 1.0 } = options;
    const link = document.createElement("a");
    link.download = filename || "image.jpg";
    link.href = this.canvas.toDataURL(type, quality);

    // 创建并触发点击事件
    const event = new MouseEvent("click", {
      view: window,
      bubbles: true,
      cancelable: true
    });
    link.dispatchEvent(event);
  }

  /**
   * 加载并下载原始图片的便捷方法
   * @param {string} url - 图片URL
   * @param {string} filename - 保存的文件名
   * @param {Object} options - 下载选项
   * @returns {Promise}
   */
  async loadAndDownload(url, filename, options = {}) {
    try {
      await this.loadImage(url);
      this.drawImage();
      this.downloadImage(filename, options);
      return true;
    } catch (error) {
      console.error("下载图片失败:", error);
      throw error;
    }
  }
}

// 使用示例:
/*
const downloader = new ImageDownloader({
  proxyUrl: 'https://api.codetabs.com/v1/proxy?quest=' // 可选的代理服务
});

// 使用方式:
downloader.loadAndDownload(
  'https://example.com/image.jpg',
  'original-image.jpg',
  { 
    type: 'image/jpeg',
    quality: 1.0  // 使用最高质量
  }
).catch(console.error);
*/

export default ImageDownloader;
下一篇 / 解决:electron Unable to load preload script: \dist-electron\preload\index.js (anonymous) @ node:electron/js2c/renderer_init:2

🎯 相关文章

💡 推荐文章

🕵️‍♂️ 评论 (0)