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 };
}