w

API 參考

為希望整合或擴展圖片裁剪器 (Image Cropper) 功能的開發者提供的技術參考。

核心組件

ImageCropper 組件

提供圖片裁剪介面的主 Vue 組件。

<template>
  <ImageCropper
    :aspect-ratio="aspectRatio"
    :output-format="format"
    :quality="quality"
    @crop-complete="handleCropComplete"
  />
</template>

屬性 (Props)

屬性類型預設值描述
aspectRationumber | 'free''free'裁剪長寬比限制
outputFormat'png' | 'jpeg' | 'webp''png'輸出圖片格式
qualitynumber[][85]JPEG 質量 (10-100)
maxWidthnumberundefined最大輸出寬度
maxHeightnumberundefined最大輸出高度

事件 (Events)

事件載荷描述
crop-completeCropResult裁剪完成時觸發
image-loadedImageInfo來源圖片加載完成時觸發
errorError發生錯誤時觸發

類型定義

CropResult

interface CropResult {
  url: string; // 裁剪後圖片的 Blob URL
  blob: Blob; // 圖片 Blob 數據
  canvas: HTMLCanvasElement; // Canvas 元素
  info: {
    width: number; // 輸出寬度 (像素)
    height: number; // 輸出高度 (像素)
    size: number; // 檔案大小 (位元組)
    format: string; // 輸出格式
  };
}

ImageInfo

interface ImageInfo {
  width: number; // 原始寬度
  height: number; // 原始高度
  size: number; // 檔案大小 (位元組)
  type: string; // MIME 類型
  name: string; // 原始檔案名稱
}

CropSettings

interface CropSettings {
  aspectRatio: number | "free";
  outputFormat: "png" | "jpeg" | "webp";
  quality: number;
  outputWidth?: number;
  outputHeight?: number;
}

Cropper.js 整合

配置選項

const cropperOptions = {
  aspectRatio: NaN, // 自由長寬比
  viewMode: 1, // 將裁剪框限制在畫布內
  responsive: true, // 響應式裁剪器
  restore: false, // 調整大小後不恢復
  guides: true, // 顯示虛線
  center: true, // 顯示中心指示器
  highlight: false, // 不反白裁剪區域
  cropBoxMovable: true, // 允許移動裁剪框
  cropBoxResizable: true, // 允許調整裁剪框大小
  toggleDragModeOnDblclick: false, // 停用雙擊切換
};

方法

方法參數返回值描述
getCroppedCanvas()options?HTMLCanvasElement將裁剪區域作為畫布獲取
setAspectRatio()ratio: numbervoid更改長寬比
reset()-void重置為原始狀態
destroy()-void銷毀裁剪器實例

實用函數

檔案處理

// 從檔案加載圖片
function loadImageFromFile(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => resolve(e.target?.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// 將 blob 下載為檔案
function downloadBlob(blob: Blob, filename: string): void {
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

圖片處理

// 將畫布轉換為 blob
function canvasToBlob(canvas: HTMLCanvasElement, format: string, quality?: number): Promise<Blob> {
  return new Promise((resolve) => {
    canvas.toBlob(resolve, `image/${format}`, quality);
  });
}

// 獲取圖片尺寸
function getImageDimensions(src: string): Promise<{ width: number; height: number }> {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () =>
      resolve({
        width: img.naturalWidth,
        height: img.naturalHeight,
      });
    img.src = src;
  });
}

格式轉換

// 格式化檔案大小以供顯示
function formatFileSize(bytes: number): string {
  const sizes = ["Bytes", "KB", "MB", "GB"];
  if (bytes === 0) return "0 Bytes";
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + " " + sizes[i];
}

// 驗證圖片檔案
function isValidImageFile(file: File): boolean {
  return file.type.startsWith("image/");
}

瀏覽器相容性

所需 API

  • Canvas API: 用於圖片操作
  • File API: 用於處理檔案上傳
  • Blob API: 用於生成結果
  • URL.createObjectURL: 用於圖片預覽
  • Clipboard API: 用於複製功能 (可選)

瀏覽器支援

功能ChromeFirefoxSafariEdge
核心功能✅ 50+✅ 52+✅ 10+✅ 79+
WebP 輸出✅ 32+✅ 65+✅ 14+✅ 79+
剪貼簿 API✅ 66+✅ 63+✅ 13.1+✅ 79+

錯誤處理

常見錯誤類型

// 檔案驗證錯誤
class InvalidFileTypeError extends Error {
  constructor() {
    super("Invalid file type. Please select an image file.");
  }
}

// 記憶體錯誤
class ImageTooLargeError extends Error {
  constructor() {
    super("Image is too large to process in this browser.");
  }
}

// 處理錯誤
class CropProcessingError extends Error {
  constructor(message: string) {
    super(`Crop processing failed: ${message}`);
  }
}

錯誤恢復

// 優雅的錯誤處理
function handleCropError(error: Error): void {
  if (error instanceof InvalidFileTypeError) {
    // 顯示檔案類型錯誤訊息
    showErrorMessage("Please select a valid image file");
  } else if (error instanceof ImageTooLargeError) {
    // 建議減小圖片大小
    showErrorMessage("Image too large. Please use a smaller image");
  } else {
    // 通用錯誤處理
    showErrorMessage("An error occurred. Please try again");
  }
}

性能優化

記憶體管理

// 清理資源
function cleanup(): void {
  // 撤銷 blob URL
  blobUrls.forEach((url) => URL.revokeObjectURL(url));

  // 銷毀裁剪器實例
  if (cropper) {
    cropper.destroy();
    cropper = null;
  }

  // 清除畫布引用
  canvasRefs.length = 0;
}

大圖片處理

// 高效處理大圖片
function processLargeImage(canvas: HTMLCanvasElement): HTMLCanvasElement {
  const maxDimension = 4096; // 瀏覽器限制
  const scale = Math.min(maxDimension / canvas.width, maxDimension / canvas.height, 1);

  if (scale < 1) {
    const scaledCanvas = document.createElement("canvas");
    scaledCanvas.width = canvas.width * scale;
    scaledCanvas.height = canvas.height * scale;

    const ctx = scaledCanvas.getContext("2d");
    ctx.drawImage(canvas, 0, 0, scaledCanvas.width, scaledCanvas.height);

    return scaledCanvas;
  }

  return canvas;
}
這個頁面對您有幫助嗎?