API Reference
Technical reference for developers who want to integrate or extend the Image Cropper functionality.
The main Vue component that provides the image cropping interface.
<template>
<ImageCropper
:aspect-ratio="aspectRatio"
:output-format="format"
:quality="quality"
@crop-complete="handleCropComplete"
/>
</template>
Prop | Type | Default | Description |
---|
aspectRatio | number | 'free' | 'free' | Crop aspect ratio constraint |
outputFormat | 'png' | 'jpeg' | 'webp' | 'png' | Output image format |
quality | number[] | [85] | JPEG quality (10-100) |
maxWidth | number | undefined | Maximum output width |
maxHeight | number | undefined | Maximum output height |
Event | Payload | Description |
---|
crop-complete | CropResult | Fired when cropping is completed |
image-loaded | ImageInfo | Fired when source image is loaded |
error | Error | Fired when an error occurs |
interface CropResult {
url: string; // Blob URL of cropped image
blob: Blob; // Image blob data
canvas: HTMLCanvasElement; // Canvas element
info: {
width: number; // Output width in pixels
height: number; // Output height in pixels
size: number; // File size in bytes
format: string; // Output format
};
}
interface ImageInfo {
width: number; // Original width
height: number; // Original height
size: number; // File size in bytes
type: string; // MIME type
name: string; // Original filename
}
interface CropSettings {
aspectRatio: number | 'free';
outputFormat: 'png' | 'jpeg' | 'webp';
quality: number;
outputWidth?: number;
outputHeight?: number;
}
const cropperOptions = {
aspectRatio: NaN, // Free aspect ratio
viewMode: 1, // Restrict crop box to canvas
responsive: true, // Responsive cropper
restore: false, // Don't restore after resize
guides: true, // Show dashed lines
center: true, // Show center indicator
highlight: false, // Don't highlight crop area
cropBoxMovable: true, // Allow moving crop box
cropBoxResizable: true, // Allow resizing crop box
toggleDragModeOnDblclick: false, // Disable double-click
};
Method | Parameters | Return | Description |
---|
getCroppedCanvas() | options? | HTMLCanvasElement | Get cropped area as canvas |
setAspectRatio() | ratio: number | void | Change aspect ratio |
reset() | - | void | Reset to original state |
destroy() | - | void | Destroy cropper instance |
// Load image from file
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);
});
}
// Download blob as file
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);
}
// Convert canvas to blob
function canvasToBlob(canvas: HTMLCanvasElement, format: string, quality?: number): Promise<Blob> {
return new Promise((resolve) => {
canvas.toBlob(resolve, `image/${format}`, quality);
});
}
// Get image dimensions
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;
});
}
// Format file size for display
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];
}
// Validate image file
function isValidImageFile(file: File): boolean {
return file.type.startsWith('image/');
}
- Canvas API: For image manipulation
- File API: For file upload handling
- Blob API: For result generation
- URL.createObjectURL: For image preview
- Clipboard API: For copy functionality (optional)
Feature | Chrome | Firefox | Safari | Edge |
---|
Core functionality | ✅ 50+ | ✅ 52+ | ✅ 10+ | ✅ 79+ |
WebP output | ✅ 32+ | ✅ 65+ | ✅ 14+ | ✅ 79+ |
Clipboard API | ✅ 66+ | ✅ 63+ | ✅ 13.1+ | ✅ 79+ |
// File validation errors
class InvalidFileTypeError extends Error {
constructor() {
super('Invalid file type. Please select an image file.');
}
}
// Memory errors
class ImageTooLargeError extends Error {
constructor() {
super('Image is too large to process in this browser.');
}
}
// Processing errors
class CropProcessingError extends Error {
constructor(message: string) {
super(`Crop processing failed: ${message}`);
}
}
// Graceful error handling
function handleCropError(error: Error): void {
if (error instanceof InvalidFileTypeError) {
// Show file type error message
showErrorMessage('Please select a valid image file');
} else if (error instanceof ImageTooLargeError) {
// Suggest image size reduction
showErrorMessage('Image too large. Please use a smaller image');
} else {
// Generic error handling
showErrorMessage('An error occurred. Please try again');
}
}
// Clean up resources
function cleanup(): void {
// Revoke blob URLs
blobUrls.forEach((url) => URL.revokeObjectURL(url));
// Destroy cropper instance
if (cropper) {
cropper.destroy();
cropper = null;
}
// Clear canvas references
canvasRefs.length = 0;
}
// Process large images efficiently
function processLargeImage(canvas: HTMLCanvasElement): HTMLCanvasElement {
const maxDimension = 4096; // Browser limit
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;
}