File size: 2,243 Bytes
2bc6d22 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import { useCallback } from 'react';
import type { ImageFile, OutputType, CompressionOptions } from '../types';
import { decode, encode, getFileType } from '../utils/imageProcessing';
export function useImageProcessing(
options: CompressionOptions,
outputType: OutputType,
setImages: React.Dispatch<React.SetStateAction<ImageFile[]>>
) {
const processImageFile = useCallback(async (image: ImageFile) => {
try {
setImages((prev) =>
prev.map((img) =>
img.id === image.id
? { ...img, status: 'processing' as const }
: img
)
);
const fileBuffer = await image.file.arrayBuffer();
const sourceType = getFileType(image.file);
if (!fileBuffer.byteLength) {
throw new Error('Empty file');
}
// Decode the image
const imageData = await decode(sourceType, fileBuffer);
if (!imageData || !imageData.width || !imageData.height) {
throw new Error('Invalid image data');
}
// Encode to the target format
const compressedBuffer = await encode(outputType, imageData, options);
if (!compressedBuffer.byteLength) {
throw new Error('Failed to compress image');
}
const blob = new Blob([compressedBuffer], { type: `image/${outputType}` });
const preview = URL.createObjectURL(blob);
setImages((prev) =>
prev.map((img) =>
img.id === image.id
? {
...img,
status: 'complete' as const,
preview,
blob,
compressedSize: compressedBuffer.byteLength,
outputType,
}
: img
)
);
} catch (error) {
console.error('Error processing image:', error);
setImages((prev) =>
prev.map((img) =>
img.id === image.id
? {
...img,
status: 'error' as const,
error: error instanceof Error
? error.message
: 'Failed to process image',
}
: img
)
);
}
}, [options, outputType, setImages]);
return { processImage: processImageFile };
} |