@umituz/react-native-image 1.1.5 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Image Infrastructure - Filter Effects
3
+ *
4
+ * Advanced filter effects and color processing
5
+ */
6
+
7
+ export class FilterEffects {
8
+ static applyVintage(imageData: ImageData): ImageData {
9
+ let data = FilterEffects.applySepia(imageData, 0.8);
10
+ const { width, height } = imageData;
11
+ const centerX = width / 2;
12
+ const centerY = height / 2;
13
+ const maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);
14
+
15
+ for (let y = 0; y < height; y++) {
16
+ for (let x = 0; x < width; x++) {
17
+ const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);
18
+ const vignette = 1 - (distance / maxDistance) * 0.7;
19
+ const i = (y * width + x) * 4;
20
+
21
+ data.data[i] *= vignette;
22
+ data.data[i + 1] *= vignette;
23
+ data.data[i + 2] *= vignette;
24
+ }
25
+ }
26
+
27
+ return data;
28
+ }
29
+
30
+ static applySepia(imageData: ImageData, intensity: number = 1): ImageData {
31
+ const data = new Uint8ClampedArray(imageData.data);
32
+ for (let i = 0; i < data.length; i += 4) {
33
+ const r = data[i];
34
+ const g = data[i + 1];
35
+ const b = data[i + 2];
36
+
37
+ data[i] = Math.min(255, (r * (1 - (0.607 * intensity))) + (g * (0.769 * intensity)) + (b * (0.189 * intensity)));
38
+ data[i + 1] = Math.min(255, (r * (0.349 * intensity)) + (g * (1 - (0.314 * intensity))) + (b * (0.168 * intensity)));
39
+ data[i + 2] = Math.min(255, (r * (0.272 * intensity)) + (g * (0.534 * intensity)) + (b * (1 - (0.869 * intensity))));
40
+ }
41
+ return FilterEffects.createCanvasImageData(imageData.width, imageData.height, data);
42
+ }
43
+
44
+ static createCanvasImageData(
45
+ width: number,
46
+ height: number,
47
+ data: Uint8ClampedArray
48
+ ): ImageData {
49
+ return { data, width, height } as ImageData;
50
+ }
51
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Image Infrastructure - Quality Presets
3
+ *
4
+ * Predefined quality settings for different use cases
5
+ */
6
+
7
+ import type { SaveFormat } from '../../domain/entities/ImageTypes';
8
+ import { IMAGE_CONSTANTS } from '../../domain/entities/ImageConstants';
9
+
10
+ export interface QualityPreset {
11
+ format: SaveFormat;
12
+ quality: number;
13
+ maxWidth?: number;
14
+ maxHeight?: number;
15
+ description: string;
16
+ }
17
+
18
+ export interface QualityPresets {
19
+ web: QualityPreset;
20
+ mobile: QualityPreset;
21
+ print: QualityPreset;
22
+ thumbnail: QualityPreset;
23
+ preview: QualityPreset;
24
+ archive: QualityPreset;
25
+ }
26
+
27
+ export const IMAGE_QUALITY_PRESETS: QualityPresets = {
28
+ web: {
29
+ format: 'jpeg',
30
+ quality: 0.8,
31
+ maxWidth: 1920,
32
+ maxHeight: 1080,
33
+ description: 'Optimized for web use with good balance of quality and size',
34
+ },
35
+ mobile: {
36
+ format: 'jpeg',
37
+ quality: 0.7,
38
+ maxWidth: 1080,
39
+ maxHeight: 1920,
40
+ description: 'Optimized for mobile devices with smaller file size',
41
+ },
42
+ print: {
43
+ format: 'png',
44
+ quality: 1.0,
45
+ maxWidth: 3000,
46
+ maxHeight: 3000,
47
+ description: 'High quality for printing with maximum detail',
48
+ },
49
+ thumbnail: {
50
+ format: 'jpeg',
51
+ quality: 0.6,
52
+ maxWidth: IMAGE_CONSTANTS.thumbnailSize,
53
+ maxHeight: IMAGE_CONSTANTS.thumbnailSize,
54
+ description: 'Small thumbnail for preview use',
55
+ },
56
+ preview: {
57
+ format: 'jpeg',
58
+ quality: 0.5,
59
+ maxWidth: 800,
60
+ maxHeight: 600,
61
+ description: 'Quick preview with very small file size',
62
+ },
63
+ archive: {
64
+ format: 'png',
65
+ quality: 0.9,
66
+ description: 'High quality archival storage with lossless compression',
67
+ },
68
+ };
69
+
70
+ export class ImageQualityPresetService {
71
+ static getPreset(name: keyof QualityPresets): QualityPreset {
72
+ return IMAGE_QUALITY_PRESETS[name];
73
+ }
74
+
75
+ static getAllPresets(): QualityPresets {
76
+ return IMAGE_QUALITY_PRESETS;
77
+ }
78
+
79
+ static getCustomPreset(options: {
80
+ format?: SaveFormat;
81
+ quality?: number;
82
+ maxWidth?: number;
83
+ maxHeight?: number;
84
+ }): QualityPreset {
85
+ return {
86
+ format: options.format || 'jpeg',
87
+ quality: options.quality || IMAGE_CONSTANTS.defaultQuality,
88
+ maxWidth: options.maxWidth,
89
+ maxHeight: options.maxHeight,
90
+ description: 'Custom quality preset',
91
+ };
92
+ }
93
+
94
+ static optimizeForUseCase(
95
+ useCase: 'web' | 'mobile' | 'print' | 'thumbnail' | 'preview' | 'archive',
96
+ customOptions?: Partial<QualityPreset>
97
+ ): QualityPreset {
98
+ const preset = IMAGE_QUALITY_PRESETS[useCase];
99
+
100
+ if (!customOptions) {
101
+ return preset;
102
+ }
103
+
104
+ return {
105
+ ...preset,
106
+ ...customOptions,
107
+ description: `${preset.description} (modified)`,
108
+ };
109
+ }
110
+ }
@@ -6,16 +6,47 @@
6
6
 
7
7
  import { useImageTransform } from './useImageTransform';
8
8
  import { useImageConversion } from './useImageConversion';
9
+ import { useImageFilter } from './useImageFilter';
10
+ import { useImageBatch } from './useImageBatch';
11
+ import { useImageAIEnhancement } from './useImageAIEnhancement';
12
+ import { useImageAnnotation } from './useImageAnnotation';
13
+ import { useImageMetadata } from './useImageMetadata';
9
14
 
10
15
  export const useImage = () => {
11
16
  const transform = useImageTransform();
12
17
  const conversion = useImageConversion();
18
+ const filter = useImageFilter();
19
+ const batch = useImageBatch();
20
+ const aiEnhancement = useImageAIEnhancement();
21
+ const annotation = useImageAnnotation();
22
+ const metadata = useImageMetadata();
13
23
 
14
24
  return {
25
+ // Basic operations
15
26
  ...transform,
16
27
  ...conversion,
28
+ // Advanced operations
29
+ ...filter,
30
+ ...batch,
31
+ ...aiEnhancement,
32
+ ...annotation,
33
+ ...metadata,
17
34
  // Combined state
18
- isProcessing: transform.isTransforming || conversion.isConverting,
19
- error: transform.transformError || conversion.conversionError,
35
+ isProcessing:
36
+ transform.isTransforming ||
37
+ conversion.isConverting ||
38
+ filter.isFiltering ||
39
+ batch.isBatchProcessing ||
40
+ aiEnhancement.isEnhancing ||
41
+ annotation.isAnnotating ||
42
+ metadata.isExtracting,
43
+ error:
44
+ transform.transformError ||
45
+ conversion.conversionError ||
46
+ filter.filterError ||
47
+ batch.batchError ||
48
+ aiEnhancement.enhancementError ||
49
+ annotation.annotationError ||
50
+ metadata.metadataError,
20
51
  };
21
52
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Presentation - Image AI Enhancement Hook
3
+ */
4
+
5
+ import { useCallback } from 'react';
6
+ import { useImageOperation } from './useImageOperation';
7
+ import { ImageAIEnhancementService, type AutoEnhancementOptions, type EnhancementResult } from '../../infrastructure/services/ImageAIEnhancementService';
8
+ import { ImageSpecializedEnhancementService } from '../../infrastructure/services/ImageSpecializedEnhancementService';
9
+
10
+ export const useImageAIEnhancement = () => {
11
+ const { isProcessing, error, execute } = useImageOperation();
12
+
13
+ const autoEnhance = useCallback((uri: string, options?: AutoEnhancementOptions) =>
14
+ execute(() => ImageAIEnhancementService.autoEnhance(uri, options), 'Failed to auto enhance'), [execute]);
15
+
16
+ const enhancePortrait = useCallback((uri: string) =>
17
+ execute(() => ImageSpecializedEnhancementService.enhancePortrait(uri), 'Failed to enhance portrait'), [execute]);
18
+
19
+ const enhanceLandscape = useCallback((uri: string) =>
20
+ execute(() => ImageSpecializedEnhancementService.enhanceLandscape(uri), 'Failed to enhance landscape'), [execute]);
21
+
22
+ const analyzeImage = useCallback((uri: string) =>
23
+ execute(() => ImageAIEnhancementService.analyzeImage(uri), 'Failed to analyze image'), [execute]);
24
+
25
+ return {
26
+ autoEnhance,
27
+ enhancePortrait,
28
+ enhanceLandscape,
29
+ analyzeImage,
30
+ isEnhancing: isProcessing,
31
+ enhancementError: error,
32
+ };
33
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Presentation - Image Annotation Hook
3
+ */
4
+
5
+ import { useCallback } from 'react';
6
+ import { useImageOperation } from './useImageOperation';
7
+ import { ImageAnnotationService, type ImageAnnotation, type TextOverlay, type DrawingElement, type WatermarkOptions } from '../../infrastructure/services/ImageAnnotationService';
8
+
9
+ export const useImageAnnotation = () => {
10
+ const { isProcessing, error, execute } = useImageOperation();
11
+
12
+ const addTextOverlay = useCallback((uri: string, overlay: TextOverlay) =>
13
+ execute(() => ImageAnnotationService.addTextOverlay(uri, overlay), 'Failed to add text'), [execute]);
14
+
15
+ const addDrawingElements = useCallback((uri: string, elements: DrawingElement[]) =>
16
+ execute(() => ImageAnnotationService.addDrawingElements(uri, elements), 'Failed to add drawing'), [execute]);
17
+
18
+ const addWatermark = useCallback((uri: string, options: WatermarkOptions) =>
19
+ execute(() => ImageAnnotationService.addWatermark(uri, options), 'Failed to add watermark'), [execute]);
20
+
21
+ const applyAnnotation = useCallback((uri: string, annotation: ImageAnnotation) =>
22
+ execute(() => ImageAnnotationService.applyAnnotation(uri, annotation), 'Failed to apply annotation'), [execute]);
23
+
24
+ return {
25
+ addTextOverlay,
26
+ addDrawingElements,
27
+ addWatermark,
28
+ applyAnnotation,
29
+ isAnnotating: isProcessing,
30
+ annotationError: error,
31
+ };
32
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Presentation - Image Batch Hook
3
+ */
4
+
5
+ import { useCallback } from 'react';
6
+ import { useImageOperation } from './useImageOperation';
7
+ import { ImageBatchService, type BatchOperation, type BatchProcessingOptions } from '../../infrastructure/services/ImageBatchService';
8
+ import type { ImageFilter } from '../../domain/entities/ImageFilterTypes';
9
+
10
+ export const useImageBatch = () => {
11
+ const { isProcessing, error, execute } = useImageOperation();
12
+
13
+ const processBatch = useCallback((operations: BatchOperation[], options?: BatchProcessingOptions) =>
14
+ execute(() => ImageBatchService.processBatch(operations, options), 'Failed to process batch'), [execute]);
15
+
16
+ const resizeBatch = useCallback((uris: string[], width?: number, height?: number, options?: BatchProcessingOptions & { saveOptions?: any }) =>
17
+ execute(() => ImageBatchService.resizeBatch(uris, width, height, options), 'Failed to resize batch'), [execute]);
18
+
19
+ const compressBatch = useCallback((uris: string[], quality?: number, options?: BatchProcessingOptions) =>
20
+ execute(() => ImageBatchService.compressBatch(uris, quality, options), 'Failed to compress batch'), [execute]);
21
+
22
+ const filterBatch = useCallback((uris: string[], filter: ImageFilter, options?: BatchProcessingOptions) =>
23
+ execute(() => ImageBatchService.filterBatch(uris, filter, options), 'Failed to filter batch'), [execute]);
24
+
25
+ return {
26
+ processBatch,
27
+ resizeBatch,
28
+ compressBatch,
29
+ filterBatch,
30
+ isBatchProcessing: isProcessing,
31
+ batchError: error,
32
+ };
33
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Presentation - Image Filter Hook
3
+ */
4
+
5
+ import { useCallback } from 'react';
6
+ import { useImageOperation } from './useImageOperation';
7
+ import { ImageFilterService } from '../../infrastructure/services/ImageFilterService';
8
+ import type {
9
+ ImageFilter,
10
+ ImageColorAdjustment,
11
+ ImageQualityMetrics,
12
+ ImageColorPalette,
13
+ } from '../../domain/entities/ImageFilterTypes';
14
+
15
+ export const useImageFilter = () => {
16
+ const { isProcessing, error, execute } = useImageOperation();
17
+
18
+ const applyFilter = useCallback((uri: string, filter: ImageFilter) =>
19
+ execute(() => ImageFilterService.applyFilter(uri, filter), 'Failed to apply filter'), [execute]);
20
+
21
+ const applyColorAdjustment = useCallback((uri: string, adjustment: ImageColorAdjustment) =>
22
+ execute(() => ImageFilterService.applyColorAdjustment(uri, adjustment), 'Failed to adjust colors'), [execute]);
23
+
24
+ const analyzeQuality = useCallback((uri: string) =>
25
+ execute(() => ImageFilterService.analyzeQuality(uri), 'Failed to analyze quality'), [execute]);
26
+
27
+ const extractColorPalette = useCallback((uri: string, colorCount?: number) =>
28
+ execute(() => ImageFilterService.extractColorPalette(uri, colorCount), 'Failed to extract colors'), [execute]);
29
+
30
+ return {
31
+ applyFilter,
32
+ applyColorAdjustment,
33
+ analyzeQuality,
34
+ extractColorPalette,
35
+ isFiltering: isProcessing,
36
+ filterError: error,
37
+ };
38
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Presentation - Image Metadata Hook
3
+ */
4
+
5
+ import { useCallback } from 'react';
6
+ import { useImageOperation } from './useImageOperation';
7
+ import { ImageMetadataService, type ImageMetadataExtractionOptions } from '../../infrastructure/services/ImageMetadataService';
8
+
9
+ export const useImageMetadata = () => {
10
+ const { isProcessing, error, execute } = useImageOperation();
11
+
12
+ const extractMetadata = useCallback((uri: string, options?: ImageMetadataExtractionOptions) =>
13
+ execute(() => ImageMetadataService.extractMetadata(uri, options), 'Failed to extract metadata'), [execute]);
14
+
15
+ const getBasicInfo = useCallback((uri: string) =>
16
+ execute(() => ImageMetadataService.getBasicInfo(uri), 'Failed to get basic info'), [execute]);
17
+
18
+ const hasMetadata = useCallback((uri: string) =>
19
+ execute(() => ImageMetadataService.hasMetadata(uri), 'Failed to check metadata'), [execute]);
20
+
21
+ return {
22
+ extractMetadata,
23
+ getBasicInfo,
24
+ hasMetadata,
25
+ isExtracting: isProcessing,
26
+ metadataError: error,
27
+ };
28
+ };