Referencia de API
Referencia técnica para desarrolladores que desean integrar o extender la funcionalidad de Image Cropper.
El componente principal de Vue que proporciona la interfaz para recortar imágenes.
<template>
<ImageCropper
:aspect-ratio="aspectRatio"
:output-format="format"
:quality="quality"
@crop-complete="handleCropComplete"
/>
</template>
| Prop | Tipo | Por defecto | Descripción |
|---|
aspectRatio | number | 'free' | 'free' | Restricción de relación de aspecto de recorte |
outputFormat | 'png' | 'jpeg' | 'webp' | 'png' | Formato de imagen de salida |
quality | number[] | [85] | Calidad de JPEG (10-100) |
maxWidth | number | undefined | Ancho de salida máximo |
maxHeight | number | undefined | Altura de salida máxima |
| Evento | Payload | Descripción |
|---|
crop-complete | CropResult | Se dispara cuando se completa el recorte |
image-loaded | ImageInfo | Se dispara cuando se carga la imagen de origen |
error | Error | Se dispara cuando ocurre un error |
interface CropResult {
url: string; // URL Blob de la imagen recortada
blob: Blob; // Datos blob de la imagen
canvas: HTMLCanvasElement; // Elemento canvas
info: {
width: number; // Ancho de salida en píxeles
height: number; // Altura de salida en píxeles
size: number; // Tamaño del archivo en bytes
format: string; // Formato de salida
};
}
interface ImageInfo {
width: number; // Ancho original
height: number; // Altura original
size: number; // Tamaño del archivo en bytes
type: string; // Tipo MIME
name: string; // Nombre de archivo original
}
interface CropSettings {
aspectRatio: number | "free";
outputFormat: "png" | "jpeg" | "webp";
quality: number;
outputWidth?: number;
outputHeight?: number;
}
const cropperOptions = {
aspectRatio: NaN, // Relación de aspecto libre
viewMode: 1, // Restringe la caja de recorte al canvas
responsive: true, // Recortador adaptable
restore: false, // No restaurar después de cambiar el tamaño
guides: true, // Mostrar líneas punteadas
center: true, // Mostrar indicador central
highlight: false, // No resaltar el área de recorte
cropBoxMovable: true, // Permitir mover la caja de recorte
cropBoxResizable: true, // Permitir cambiar el tamaño de la caja de recorte
toggleDragModeOnDblclick: false, // Desactivar el doble clic
};
| Método | Parámetros | Retorno | Descripción |
|---|
getCroppedCanvas() | options? | HTMLCanvasElement | Obtener área recortada como canvas |
setAspectRatio() | ratio: number | void | Cambiar la relación de aspecto |
reset() | - | void | Restablecer al estado original |
destroy() | - | void | Destruir la instancia del recortador |
// Cargar imagen desde archivo
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);
});
}
// Descargar blob como archivo
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);
}
// Convertir canvas a blob
function canvasToBlob(canvas: HTMLCanvasElement, format: string, quality?: number): Promise<Blob> {
return new Promise((resolve) => {
canvas.toBlob(resolve, `image/${format}`, quality);
});
}
// Obtener dimensiones de la imagen
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;
});
}
// Formatear el tamaño del archivo para mostrar
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];
}
// Validar archivo de imagen
function isValidImageFile(file: File): boolean {
return file.type.startsWith("image/");
}
- Canvas API: Para la manipulación de imágenes
- File API: Para el manejo de carga de archivos
- Blob API: Para la generación de resultados
- URL.createObjectURL: Para la vista previa de la imagen
- Clipboard API: Para la funcionalidad de copia (opcional)
| Característica | Chrome | Firefox | Safari | Edge |
|---|
| Funcionalidad base | ✅ 50+ | ✅ 52+ | ✅ 10+ | ✅ 79+ |
| Salida WebP | ✅ 32+ | ✅ 65+ | ✅ 14+ | ✅ 79+ |
| Clipboard API | ✅ 66+ | ✅ 63+ | ✅ 13.1+ | ✅ 79+ |
// Errores de validación de archivos
class InvalidFileTypeError extends Error {
constructor() {
super("Tipo de archivo inválido. Por favor, seleccione un archivo de imagen.");
}
}
// Errores de memoria
class ImageTooLargeError extends Error {
constructor() {
super("La imagen es demasiado grande para ser procesada en este navegador.");
}
}
// Errores de procesamiento
class CropProcessingError extends Error {
constructor(message: string) {
super(`El procesamiento del recorte falló: ${message}`);
}
}
// Manejo elegante de errores
function handleCropError(error: Error): void {
if (error instanceof InvalidFileTypeError) {
// Mostrar mensaje de error de tipo de archivo
showErrorMessage("Por favor, seleccione un archivo de imagen válido");
} else if (error instanceof ImageTooLargeError) {
// Sugerir reducción de tamaño de imagen
showErrorMessage("Imagen demasiado grande. Por favor, use una imagen más pequeña");
} else {
// Manejo genérico de errores
showErrorMessage("Ocurrió un error. Por favor, inténtelo de nuevo");
}
}
// Limpiar recursos
function cleanup(): void {
// Revocar URLs blob
blobUrls.forEach((url) => URL.revokeObjectURL(url));
// Destruir la instancia del recortador
if (cropper) {
cropper.destroy();
cropper = null;
}
// Borrar referencias del canvas
canvasRefs.length = 0;
}
// Procesar imágenes grandes eficientemente
function processLargeImage(canvas: HTMLCanvasElement): HTMLCanvasElement {
const maxDimension = 4096; // Límite del navegador
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;
}