| 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'); |
| } |
|
|
| |
| const imageData = await decode(sourceType, fileBuffer); |
| |
| if (!imageData || !imageData.width || !imageData.height) { |
| throw new Error('Invalid image data'); |
| } |
|
|
| |
| 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 }; |
| } |