@capgo/capacitor-file-compressor 8.0.33 → 8.1.0
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.
- package/README.md +44 -18
- package/android/src/main/java/io/capgo/filecompressor/FileCompressorPlugin.java +115 -45
- package/dist/docs.json +21 -13
- package/dist/esm/definitions.d.ts +40 -20
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +5 -0
- package/dist/esm/web.js +50 -23
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +50 -23
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +50 -23
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/FileCompressorPlugin/FileCompressorPlugin.swift +202 -47
- package/ios/Tests/FileCompressorPluginTests/FileCompressorPluginTests.swift +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,15 +6,16 @@
|
|
|
6
6
|
<h2><a href="https://capgo.app/consulting/?ref=plugin_file-compressor"> Missing a feature? We'll build the plugin for you 💪</a></h2>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
Capacitor plugin for efficient image compression
|
|
9
|
+
Capacitor plugin for efficient image compression and **format conversion** across iOS, Android, and Web.
|
|
10
10
|
|
|
11
11
|
## Why File Compressor?
|
|
12
12
|
|
|
13
13
|
A free, open-source alternative for **client-side image compression**:
|
|
14
14
|
|
|
15
|
-
- **
|
|
15
|
+
- **Format conversion** - Convert HEIF, PNG, WebP, GIF, and more to JPEG, PNG, WebP, or HEIF
|
|
16
|
+
- **Multiple formats** - Broad input support with platform-specific output formats
|
|
16
17
|
- **Quality control** - Adjustable compression quality (0.0 - 1.0)
|
|
17
|
-
- **Smart resizing** - Automatic aspect ratio preservation
|
|
18
|
+
- **Smart resizing** - Automatic aspect ratio preservation without upscaling
|
|
18
19
|
- **Cross-platform** - Consistent API across iOS, Android, and Web
|
|
19
20
|
- **Zero backend** - All compression happens on the device
|
|
20
21
|
|
|
@@ -56,13 +57,28 @@ npm install @capgo/capacitor-file-compressor
|
|
|
56
57
|
npx cap sync
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
##
|
|
60
|
+
## Format Conversion
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
|
62
|
+
The plugin accepts common image formats as input and converts them to the `mimeType` you request.
|
|
63
|
+
|
|
64
|
+
| Platform | Input formats | Output formats |
|
|
65
|
+
|----------|---------------|----------------|
|
|
66
|
+
| iOS | JPEG, PNG, WebP, GIF, BMP, TIFF, HEIF/HEIC | JPEG, PNG, HEIF/HEIC, WebP (iOS 14+) |
|
|
67
|
+
| Android | JPEG, PNG, WebP, GIF, BMP, HEIF/HEIC (API 28+) | JPEG, PNG, WebP |
|
|
68
|
+
| Web | Any format the browser can decode | JPEG, PNG, WebP |
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { FileCompressor } from '@capgo/capacitor-file-compressor';
|
|
72
|
+
|
|
73
|
+
// Convert an iPhone HEIF photo to JPEG before upload
|
|
74
|
+
const result = await FileCompressor.compressImage({
|
|
75
|
+
path: heifFileUri,
|
|
76
|
+
width: 1920,
|
|
77
|
+
height: 1080,
|
|
78
|
+
quality: 0.7,
|
|
79
|
+
mimeType: 'image/jpeg',
|
|
80
|
+
});
|
|
81
|
+
```
|
|
66
82
|
|
|
67
83
|
Note: EXIF metadata is removed during compression on all platforms.
|
|
68
84
|
|
|
@@ -90,12 +106,22 @@ compressImage(options: CompressImageOptions) => Promise<CompressImageResult>
|
|
|
90
106
|
Compresses an image file with specified dimensions and quality settings.
|
|
91
107
|
|
|
92
108
|
This method compresses images to reduce file size while maintaining acceptable quality.
|
|
93
|
-
It supports resizing and format conversion
|
|
109
|
+
It supports resizing and format conversion across common image formats.
|
|
110
|
+
|
|
111
|
+
**Supported input formats (platform decoder dependent):**
|
|
112
|
+
JPEG, PNG, WebP, GIF, BMP, TIFF, HEIF/HEIC
|
|
113
|
+
|
|
114
|
+
**Supported output formats:**
|
|
115
|
+
- **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+)
|
|
116
|
+
- **Android:** `image/jpeg`, `image/png`, `image/webp`
|
|
117
|
+
- **Web:** `image/jpeg`, `image/png`, `image/webp`
|
|
94
118
|
|
|
95
119
|
**Important Notes:**
|
|
96
120
|
- EXIF metadata is removed during compression on all platforms
|
|
97
121
|
- Aspect ratio is automatically maintained if only one dimension is provided
|
|
122
|
+
- When both width and height are provided, the image fits inside that box without upscaling
|
|
98
123
|
- Compressed files are saved to temporary directories on native platforms
|
|
124
|
+
- If the encoded output would be larger than the source file, quality is reduced automatically while keeping the requested output format
|
|
99
125
|
|
|
100
126
|
| Param | Type | Description |
|
|
101
127
|
| ------------- | --------------------------------------------------------------------- | --------------------------------------------- |
|
|
@@ -149,13 +175,13 @@ Options for compressing an image.
|
|
|
149
175
|
Configure the compression behavior including quality, dimensions, and output format.
|
|
150
176
|
Platform-specific options are available for path (native) and blob (web).
|
|
151
177
|
|
|
152
|
-
| Prop | Type | Description
|
|
153
|
-
| -------------- | ------------------- |
|
|
154
|
-
| **`path`** | <code>string</code> | The file path of the image to compress. **Platform:** Android, iOS only (not supported on Web) Accepts various path formats: - iOS: `file://` URLs or absolute paths - Android: `content://` URIs, `file://` URLs, or absolute paths
|
|
155
|
-
| **`blob`** | <code>Blob</code> | The file blob of the image to compress. **Platform:** Web only (not supported on iOS/Android) Use this when compressing images from file inputs, fetch responses, or any other Blob source in web applications.
|
|
156
|
-
| **`quality`** | <code>number</code> | The quality of the compressed image. **Range:** 0.0 to 1.0 - `0.0` = Maximum compression (lowest quality, smallest file) - `1.0` = Minimum compression (highest quality, largest file) - `0.6` = Default balanced compression **Platform:** All platforms Higher quality values result in larger files but better visual quality. The actual compression ratio depends on the image content and format. | <code>0.6</code> | 7.0.0 |
|
|
157
|
-
| **`width`** | <code>number</code> | The width of the compressed image in pixels. **Platform:** All platforms If only width is specified, height is calculated automatically to maintain the original aspect ratio. If both width and height are specified, the image is
|
|
158
|
-
| **`height`** | <code>number</code> | The height of the compressed image in pixels. **Platform:** All platforms If only height is specified, width is calculated automatically to maintain the original aspect ratio. If both width and height are specified, the image is
|
|
159
|
-
| **`mimeType`** | <code>string</code> | The MIME type of the compressed output image. **Platform Support:** - **iOS:** `image/jpeg`
|
|
178
|
+
| Prop | Type | Description | Default | Since |
|
|
179
|
+
| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ----- |
|
|
180
|
+
| **`path`** | <code>string</code> | The file path of the image to compress. **Platform:** Android, iOS only (not supported on Web) Accepts various path formats: - iOS: `file://` URLs or absolute paths - Android: `content://` URIs, `file://` URLs, or absolute paths Common input formats include JPEG, PNG, WebP, GIF, BMP, TIFF, and HEIF/HEIC. | | 7.0.0 |
|
|
181
|
+
| **`blob`** | <code>Blob</code> | The file blob of the image to compress. **Platform:** Web only (not supported on iOS/Android) Use this when compressing images from file inputs, fetch responses, or any other Blob source in web applications. | | 7.0.0 |
|
|
182
|
+
| **`quality`** | <code>number</code> | The quality of the compressed image. **Range:** 0.0 to 1.0 - `0.0` = Maximum compression (lowest quality, smallest file) - `1.0` = Minimum compression (highest quality, largest file) - `0.6` = Default balanced compression **Platform:** All platforms Higher quality values result in larger files but better visual quality. The actual compression ratio depends on the image content and format. PNG output ignores quality because it is lossless. | <code>0.6</code> | 7.0.0 |
|
|
183
|
+
| **`width`** | <code>number</code> | The width of the compressed image in pixels. **Platform:** All platforms If only width is specified, height is calculated automatically to maintain the original aspect ratio. If both width and height are specified, the image is scaled to fit inside that box while preserving aspect ratio. Images are never upscaled. | | 7.0.0 |
|
|
184
|
+
| **`height`** | <code>number</code> | The height of the compressed image in pixels. **Platform:** All platforms If only height is specified, width is calculated automatically to maintain the original aspect ratio. If both width and height are specified, the image is scaled to fit inside that box while preserving aspect ratio. Images are never upscaled. | | 7.0.0 |
|
|
185
|
+
| **`mimeType`** | <code>string</code> | The MIME type of the compressed output image. **Platform Support:** - **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+) - **Android:** `image/jpeg`, `image/png`, `image/webp` - **Web:** `image/jpeg`, `image/png`, `image/webp` Use this option to convert the source image to another format while compressing. **Format Characteristics:** - **JPEG:** Universal support, good for photos, no transparency - **PNG:** Lossless, supports transparency - **WebP:** Better compression, supports transparency - **HEIF/HEIC:** Efficient photo format on iOS | <code>"image/jpeg"</code> | 7.0.0 |
|
|
160
186
|
|
|
161
187
|
</docgen-api>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
package io.capgo.filecompressor;
|
|
2
2
|
|
|
3
|
+
import android.content.res.AssetFileDescriptor;
|
|
3
4
|
import android.graphics.Bitmap;
|
|
4
5
|
import android.graphics.BitmapFactory;
|
|
5
6
|
import android.net.Uri;
|
|
6
|
-
import android.webkit.MimeTypeMap;
|
|
7
7
|
import com.getcapacitor.JSObject;
|
|
8
8
|
import com.getcapacitor.Plugin;
|
|
9
9
|
import com.getcapacitor.PluginCall;
|
|
@@ -13,12 +13,17 @@ import java.io.File;
|
|
|
13
13
|
import java.io.FileOutputStream;
|
|
14
14
|
import java.io.IOException;
|
|
15
15
|
import java.io.InputStream;
|
|
16
|
+
import java.util.Arrays;
|
|
17
|
+
import java.util.List;
|
|
16
18
|
import java.util.UUID;
|
|
17
19
|
|
|
18
20
|
@CapacitorPlugin(name = "FileCompressor")
|
|
19
21
|
public class FileCompressorPlugin extends Plugin {
|
|
20
22
|
|
|
21
|
-
private final String pluginVersion = "8.0
|
|
23
|
+
private final String pluginVersion = "8.1.0";
|
|
24
|
+
private static final float MIN_QUALITY = 0.1f;
|
|
25
|
+
private static final float QUALITY_STEP = 0.05f;
|
|
26
|
+
private static final List<String> SUPPORTED_OUTPUT_MIME_TYPES = Arrays.asList("image/jpeg", "image/png", "image/webp");
|
|
22
27
|
|
|
23
28
|
@PluginMethod
|
|
24
29
|
public void compressImage(PluginCall call) {
|
|
@@ -31,56 +36,45 @@ public class FileCompressorPlugin extends Plugin {
|
|
|
31
36
|
float quality = call.getFloat("quality", 0.6f);
|
|
32
37
|
Integer width = call.getInt("width");
|
|
33
38
|
Integer height = call.getInt("height");
|
|
34
|
-
String mimeType = call.getString("mimeType", "image/jpeg");
|
|
39
|
+
String mimeType = call.getString("mimeType", "image/jpeg").toLowerCase();
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
call.reject("Only image/jpeg and image/webp are supported on Android");
|
|
41
|
+
if (!SUPPORTED_OUTPUT_MIME_TYPES.contains(mimeType)) {
|
|
42
|
+
call.reject("Unsupported output mimeType: " + mimeType + ". Supported: " + String.join(", ", SUPPORTED_OUTPUT_MIME_TYPES));
|
|
39
43
|
return;
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
// Validate quality range
|
|
43
46
|
if (quality < 0.0f || quality > 1.0f) {
|
|
44
47
|
call.reject("quality must be between 0.0 and 1.0");
|
|
45
48
|
return;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
try {
|
|
49
|
-
|
|
52
|
+
long maxBytes = getOriginalFileSize(path);
|
|
53
|
+
OutputFormat outputFormat = OutputFormat.fromMimeType(mimeType);
|
|
54
|
+
|
|
50
55
|
Bitmap bitmap = loadBitmapFromPath(path);
|
|
51
56
|
if (bitmap == null) {
|
|
52
57
|
call.reject("Failed to load image from path");
|
|
53
58
|
return;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
int[] targetDimensions = calculateTargetDimensions(bitmap, width, height);
|
|
57
62
|
Bitmap processedBitmap = bitmap;
|
|
58
|
-
if (
|
|
59
|
-
processedBitmap = Bitmap.createScaledBitmap(bitmap,
|
|
60
|
-
} else if (width != null) {
|
|
61
|
-
float aspectRatio = (float) bitmap.getHeight() / bitmap.getWidth();
|
|
62
|
-
int targetHeight = (int) (width * aspectRatio);
|
|
63
|
-
processedBitmap = Bitmap.createScaledBitmap(bitmap, width, targetHeight, true);
|
|
64
|
-
} else if (height != null) {
|
|
65
|
-
float aspectRatio = (float) bitmap.getWidth() / bitmap.getHeight();
|
|
66
|
-
int targetWidth = (int) (height * aspectRatio);
|
|
67
|
-
processedBitmap = Bitmap.createScaledBitmap(bitmap, targetWidth, height, true);
|
|
63
|
+
if (targetDimensions[0] != bitmap.getWidth() || targetDimensions[1] != bitmap.getHeight()) {
|
|
64
|
+
processedBitmap = Bitmap.createScaledBitmap(bitmap, targetDimensions[0], targetDimensions[1], true);
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
File compressedFile = compressBitmap(processedBitmap, quality, mimeType);
|
|
67
|
+
File compressedFile = compressBitmap(processedBitmap, quality, outputFormat, maxBytes);
|
|
72
68
|
if (compressedFile == null) {
|
|
73
69
|
call.reject("Failed to compress image");
|
|
74
70
|
return;
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
// Clean up
|
|
78
73
|
if (processedBitmap != bitmap) {
|
|
79
74
|
processedBitmap.recycle();
|
|
80
75
|
}
|
|
81
76
|
bitmap.recycle();
|
|
82
77
|
|
|
83
|
-
// Return result
|
|
84
78
|
JSObject result = new JSObject();
|
|
85
79
|
result.put("path", compressedFile.getAbsolutePath());
|
|
86
80
|
call.resolve(result);
|
|
@@ -89,9 +83,54 @@ public class FileCompressorPlugin extends Plugin {
|
|
|
89
83
|
}
|
|
90
84
|
}
|
|
91
85
|
|
|
86
|
+
private int[] calculateTargetDimensions(Bitmap bitmap, Integer maxWidth, Integer maxHeight) {
|
|
87
|
+
int sourceWidth = bitmap.getWidth();
|
|
88
|
+
int sourceHeight = bitmap.getHeight();
|
|
89
|
+
|
|
90
|
+
if (maxWidth == null && maxHeight == null) {
|
|
91
|
+
return new int[] { sourceWidth, sourceHeight };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
float ratio = 1f;
|
|
95
|
+
|
|
96
|
+
if (maxWidth != null && maxHeight != null) {
|
|
97
|
+
ratio = Math.min((float) maxWidth / sourceWidth, (float) maxHeight / sourceHeight);
|
|
98
|
+
} else if (maxWidth != null) {
|
|
99
|
+
ratio = (float) maxWidth / sourceWidth;
|
|
100
|
+
} else if (maxHeight != null) {
|
|
101
|
+
ratio = (float) maxHeight / sourceHeight;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
ratio = Math.min(ratio, 1f);
|
|
105
|
+
|
|
106
|
+
return new int[] { Math.round(sourceWidth * ratio), Math.round(sourceHeight * ratio) };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private long getOriginalFileSize(String path) {
|
|
110
|
+
try {
|
|
111
|
+
if (path.startsWith("content://")) {
|
|
112
|
+
Uri uri = Uri.parse(path);
|
|
113
|
+
try (AssetFileDescriptor descriptor = getContext().getContentResolver().openAssetFileDescriptor(uri, "r")) {
|
|
114
|
+
if (descriptor != null) {
|
|
115
|
+
return descriptor.getLength();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
String filePath = path.startsWith("file://") ? path.substring(7) : path;
|
|
120
|
+
File file = new File(filePath);
|
|
121
|
+
if (file.exists()) {
|
|
122
|
+
return file.length();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (Exception e) {
|
|
126
|
+
e.printStackTrace();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return -1;
|
|
130
|
+
}
|
|
131
|
+
|
|
92
132
|
private Bitmap loadBitmapFromPath(String path) {
|
|
93
133
|
try {
|
|
94
|
-
// Handle content:// URIs
|
|
95
134
|
if (path.startsWith("content://")) {
|
|
96
135
|
Uri uri = Uri.parse(path);
|
|
97
136
|
InputStream inputStream = getContext().getContentResolver().openInputStream(uri);
|
|
@@ -100,13 +139,10 @@ public class FileCompressorPlugin extends Plugin {
|
|
|
100
139
|
inputStream.close();
|
|
101
140
|
return bitmap;
|
|
102
141
|
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
else if (path.startsWith("file://")) {
|
|
106
|
-
path = path.substring(7); // Remove "file://" prefix
|
|
142
|
+
} else if (path.startsWith("file://")) {
|
|
143
|
+
path = path.substring(7);
|
|
107
144
|
}
|
|
108
145
|
|
|
109
|
-
// Try loading as file path
|
|
110
146
|
File file = new File(path);
|
|
111
147
|
if (file.exists()) {
|
|
112
148
|
return BitmapFactory.decodeFile(file.getAbsolutePath());
|
|
@@ -117,29 +153,38 @@ public class FileCompressorPlugin extends Plugin {
|
|
|
117
153
|
return null;
|
|
118
154
|
}
|
|
119
155
|
|
|
120
|
-
private File compressBitmap(Bitmap bitmap, float quality,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
Bitmap.CompressFormat format;
|
|
124
|
-
String extension;
|
|
156
|
+
private File compressBitmap(Bitmap bitmap, float quality, OutputFormat outputFormat, long maxBytes) {
|
|
157
|
+
float currentQuality = quality;
|
|
158
|
+
File lastFile = null;
|
|
125
159
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
format = Bitmap.CompressFormat.JPEG;
|
|
131
|
-
extension = ".jpg";
|
|
160
|
+
while (true) {
|
|
161
|
+
File compressedFile = writeCompressedBitmap(bitmap, outputFormat, currentQuality);
|
|
162
|
+
if (compressedFile == null) {
|
|
163
|
+
return lastFile;
|
|
132
164
|
}
|
|
133
165
|
|
|
134
|
-
|
|
166
|
+
if (lastFile != null && lastFile != compressedFile) {
|
|
167
|
+
lastFile.delete();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (maxBytes <= 0 || compressedFile.length() <= maxBytes || currentQuality <= MIN_QUALITY || !outputFormat.supportsQuality) {
|
|
171
|
+
return compressedFile;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
lastFile = compressedFile;
|
|
175
|
+
currentQuality = Math.max(MIN_QUALITY, currentQuality - QUALITY_STEP);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private File writeCompressedBitmap(Bitmap bitmap, OutputFormat outputFormat, float quality) {
|
|
180
|
+
try {
|
|
135
181
|
File tempDir = getContext().getCacheDir();
|
|
136
|
-
String fileName = "compressed_" + UUID.randomUUID().toString() + extension;
|
|
182
|
+
String fileName = "compressed_" + UUID.randomUUID().toString() + outputFormat.extension;
|
|
137
183
|
File compressedFile = new File(tempDir, fileName);
|
|
138
184
|
|
|
139
|
-
// Compress and save
|
|
140
185
|
FileOutputStream outputStream = new FileOutputStream(compressedFile);
|
|
141
|
-
int qualityInt = (
|
|
142
|
-
bitmap.compress(format, qualityInt, outputStream);
|
|
186
|
+
int qualityInt = Math.round(quality * 100);
|
|
187
|
+
bitmap.compress(outputFormat.format, qualityInt, outputStream);
|
|
143
188
|
outputStream.flush();
|
|
144
189
|
outputStream.close();
|
|
145
190
|
|
|
@@ -160,4 +205,29 @@ public class FileCompressorPlugin extends Plugin {
|
|
|
160
205
|
call.reject("Could not get plugin version", e);
|
|
161
206
|
}
|
|
162
207
|
}
|
|
208
|
+
|
|
209
|
+
private static final class OutputFormat {
|
|
210
|
+
|
|
211
|
+
private final Bitmap.CompressFormat format;
|
|
212
|
+
private final String extension;
|
|
213
|
+
private final boolean supportsQuality;
|
|
214
|
+
|
|
215
|
+
private OutputFormat(Bitmap.CompressFormat format, String extension, boolean supportsQuality) {
|
|
216
|
+
this.format = format;
|
|
217
|
+
this.extension = extension;
|
|
218
|
+
this.supportsQuality = supportsQuality;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private static OutputFormat fromMimeType(String mimeType) {
|
|
222
|
+
switch (mimeType) {
|
|
223
|
+
case "image/webp":
|
|
224
|
+
return new OutputFormat(Bitmap.CompressFormat.WEBP, ".webp", true);
|
|
225
|
+
case "image/png":
|
|
226
|
+
return new OutputFormat(Bitmap.CompressFormat.PNG, ".png", false);
|
|
227
|
+
case "image/jpeg":
|
|
228
|
+
default:
|
|
229
|
+
return new OutputFormat(Bitmap.CompressFormat.JPEG, ".jpg", true);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
163
233
|
}
|
package/dist/docs.json
CHANGED
|
@@ -44,18 +44,18 @@
|
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"name": "example",
|
|
47
|
-
"text": "```typescript\n// iOS -
|
|
47
|
+
"text": "```typescript\n// iOS - Convert HEIF iPhone photo to JPEG\nconst result = await FileCompressor.compressImage({\n path: heifFileUri,\n quality: 0.7,\n width: 1920,\n height: 1080,\n mimeType: 'image/jpeg'\n});\nconsole.log('Converted to JPEG:', result.path);\n```"
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
"name": "example",
|
|
51
|
-
"text": "```typescript\n// Android -
|
|
51
|
+
"text": "```typescript\n// Android - Convert PNG to WebP\nconst result = await FileCompressor.compressImage({\n path: 'content://downloads/document/123',\n quality: 0.6,\n width: 800,\n height: 600,\n mimeType: 'image/webp'\n});\nconsole.log('Compressed to:', result.path);\n```"
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"name": "example",
|
|
55
|
-
"text": "```typescript\n// Maintain aspect ratio - only specify width\nconst result = await FileCompressor.compressImage({\n path: imagePath,\n quality: 0.75,\n width: 1920
|
|
55
|
+
"text": "```typescript\n// Maintain aspect ratio - only specify width\nconst result = await FileCompressor.compressImage({\n path: imagePath,\n quality: 0.75,\n width: 1920,\n mimeType: 'image/jpeg'\n});\n```"
|
|
56
56
|
}
|
|
57
57
|
],
|
|
58
|
-
"docs": "Compresses an image file with specified dimensions and quality settings.\n\nThis method compresses images to reduce file size while maintaining acceptable quality.\nIt supports resizing and format conversion (
|
|
58
|
+
"docs": "Compresses an image file with specified dimensions and quality settings.\n\nThis method compresses images to reduce file size while maintaining acceptable quality.\nIt supports resizing and format conversion across common image formats.\n\n**Supported input formats (platform decoder dependent):**\nJPEG, PNG, WebP, GIF, BMP, TIFF, HEIF/HEIC\n\n**Supported output formats:**\n- **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+)\n- **Android:** `image/jpeg`, `image/png`, `image/webp`\n- **Web:** `image/jpeg`, `image/png`, `image/webp`\n\n**Important Notes:**\n- EXIF metadata is removed during compression on all platforms\n- Aspect ratio is automatically maintained if only one dimension is provided\n- When both width and height are provided, the image fits inside that box without upscaling\n- Compressed files are saved to temporary directories on native platforms\n- If the encoded output would be larger than the source file, quality is reduced automatically while keeping the requested output format",
|
|
59
59
|
"complexTypes": [
|
|
60
60
|
"CompressImageResult",
|
|
61
61
|
"CompressImageOptions"
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"name": "example"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
|
-
"text": "\"/data/user/0/com.app/cache/compressed_xyz789.
|
|
120
|
+
"text": "\"/data/user/0/com.app/cache/compressed_xyz789.webp\" // Android",
|
|
121
121
|
"name": "example"
|
|
122
122
|
}
|
|
123
123
|
],
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"name": "since"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
|
-
"text": "\"file:///var/mobile/Containers/Data/Application/
|
|
172
|
+
"text": "\"file:///var/mobile/Containers/Data/Application/photo.heic\" // iOS HEIF",
|
|
173
173
|
"name": "example"
|
|
174
174
|
},
|
|
175
175
|
{
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"name": "example"
|
|
182
182
|
}
|
|
183
183
|
],
|
|
184
|
-
"docs": "The file path of the image to compress.\n\n**Platform:** Android, iOS only (not supported on Web)\n\nAccepts various path formats:\n- iOS: `file://` URLs or absolute paths\n- Android: `content://` URIs, `file://` URLs, or absolute paths",
|
|
184
|
+
"docs": "The file path of the image to compress.\n\n**Platform:** Android, iOS only (not supported on Web)\n\nAccepts various path formats:\n- iOS: `file://` URLs or absolute paths\n- Android: `content://` URIs, `file://` URLs, or absolute paths\n\nCommon input formats include JPEG, PNG, WebP, GIF, BMP, TIFF, and HEIF/HEIC.",
|
|
185
185
|
"complexTypes": [],
|
|
186
186
|
"type": "string | undefined"
|
|
187
187
|
},
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
"name": "example"
|
|
232
232
|
}
|
|
233
233
|
],
|
|
234
|
-
"docs": "The quality of the compressed image.\n\n**Range:** 0.0 to 1.0\n- `0.0` = Maximum compression (lowest quality, smallest file)\n- `1.0` = Minimum compression (highest quality, largest file)\n- `0.6` = Default balanced compression\n\n**Platform:** All platforms\n\nHigher quality values result in larger files but better visual quality.\nThe actual compression ratio depends on the image content and format.",
|
|
234
|
+
"docs": "The quality of the compressed image.\n\n**Range:** 0.0 to 1.0\n- `0.0` = Maximum compression (lowest quality, smallest file)\n- `1.0` = Minimum compression (highest quality, largest file)\n- `0.6` = Default balanced compression\n\n**Platform:** All platforms\n\nHigher quality values result in larger files but better visual quality.\nThe actual compression ratio depends on the image content and format.\nPNG output ignores quality because it is lossless.",
|
|
235
235
|
"complexTypes": [],
|
|
236
236
|
"type": "number | undefined"
|
|
237
237
|
},
|
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
"name": "example"
|
|
256
256
|
}
|
|
257
257
|
],
|
|
258
|
-
"docs": "The width of the compressed image in pixels.\n\n**Platform:** All platforms\n\nIf only width is specified, height is calculated automatically\nto maintain the original aspect ratio.\n\nIf both width and height are specified, the image is
|
|
258
|
+
"docs": "The width of the compressed image in pixels.\n\n**Platform:** All platforms\n\nIf only width is specified, height is calculated automatically\nto maintain the original aspect ratio.\n\nIf both width and height are specified, the image is scaled to fit inside\nthat box while preserving aspect ratio. Images are never upscaled.",
|
|
259
259
|
"complexTypes": [],
|
|
260
260
|
"type": "number | undefined"
|
|
261
261
|
},
|
|
@@ -279,7 +279,7 @@
|
|
|
279
279
|
"name": "example"
|
|
280
280
|
}
|
|
281
281
|
],
|
|
282
|
-
"docs": "The height of the compressed image in pixels.\n\n**Platform:** All platforms\n\nIf only height is specified, width is calculated automatically\nto maintain the original aspect ratio.\n\nIf both width and height are specified, the image is
|
|
282
|
+
"docs": "The height of the compressed image in pixels.\n\n**Platform:** All platforms\n\nIf only height is specified, width is calculated automatically\nto maintain the original aspect ratio.\n\nIf both width and height are specified, the image is scaled to fit inside\nthat box while preserving aspect ratio. Images are never upscaled.",
|
|
283
283
|
"complexTypes": [],
|
|
284
284
|
"type": "number | undefined"
|
|
285
285
|
},
|
|
@@ -295,15 +295,23 @@
|
|
|
295
295
|
"name": "default"
|
|
296
296
|
},
|
|
297
297
|
{
|
|
298
|
-
"text": "\"image/jpeg\" // JPEG format
|
|
298
|
+
"text": "\"image/jpeg\" // JPEG format",
|
|
299
299
|
"name": "example"
|
|
300
300
|
},
|
|
301
301
|
{
|
|
302
|
-
"text": "\"image/
|
|
302
|
+
"text": "\"image/png\" // PNG format",
|
|
303
|
+
"name": "example"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"text": "\"image/webp\" // WebP format",
|
|
307
|
+
"name": "example"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"text": "\"image/heif\" // HEIF format (iOS output)",
|
|
303
311
|
"name": "example"
|
|
304
312
|
}
|
|
305
313
|
],
|
|
306
|
-
"docs": "The MIME type of the compressed output image.\n\n**Platform Support:**\n- **iOS:** `image/jpeg`
|
|
314
|
+
"docs": "The MIME type of the compressed output image.\n\n**Platform Support:**\n- **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+)\n- **Android:** `image/jpeg`, `image/png`, `image/webp`\n- **Web:** `image/jpeg`, `image/png`, `image/webp`\n\nUse this option to convert the source image to another format while compressing.\n\n**Format Characteristics:**\n- **JPEG:** Universal support, good for photos, no transparency\n- **PNG:** Lossless, supports transparency\n- **WebP:** Better compression, supports transparency\n- **HEIF/HEIC:** Efficient photo format on iOS",
|
|
307
315
|
"complexTypes": [],
|
|
308
316
|
"type": "string | undefined"
|
|
309
317
|
}
|
|
@@ -8,12 +8,22 @@ export interface FileCompressorPlugin {
|
|
|
8
8
|
* Compresses an image file with specified dimensions and quality settings.
|
|
9
9
|
*
|
|
10
10
|
* This method compresses images to reduce file size while maintaining acceptable quality.
|
|
11
|
-
* It supports resizing and format conversion
|
|
11
|
+
* It supports resizing and format conversion across common image formats.
|
|
12
|
+
*
|
|
13
|
+
* **Supported input formats (platform decoder dependent):**
|
|
14
|
+
* JPEG, PNG, WebP, GIF, BMP, TIFF, HEIF/HEIC
|
|
15
|
+
*
|
|
16
|
+
* **Supported output formats:**
|
|
17
|
+
* - **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+)
|
|
18
|
+
* - **Android:** `image/jpeg`, `image/png`, `image/webp`
|
|
19
|
+
* - **Web:** `image/jpeg`, `image/png`, `image/webp`
|
|
12
20
|
*
|
|
13
21
|
* **Important Notes:**
|
|
14
22
|
* - EXIF metadata is removed during compression on all platforms
|
|
15
23
|
* - Aspect ratio is automatically maintained if only one dimension is provided
|
|
24
|
+
* - When both width and height are provided, the image fits inside that box without upscaling
|
|
16
25
|
* - Compressed files are saved to temporary directories on native platforms
|
|
26
|
+
* - If the encoded output would be larger than the source file, quality is reduced automatically while keeping the requested output format
|
|
17
27
|
*
|
|
18
28
|
* @param options - Configuration options for image compression
|
|
19
29
|
* @returns Promise that resolves with the compressed image path or blob
|
|
@@ -34,18 +44,19 @@ export interface FileCompressorPlugin {
|
|
|
34
44
|
* ```
|
|
35
45
|
* @example
|
|
36
46
|
* ```typescript
|
|
37
|
-
* // iOS -
|
|
47
|
+
* // iOS - Convert HEIF iPhone photo to JPEG
|
|
38
48
|
* const result = await FileCompressor.compressImage({
|
|
39
|
-
* path:
|
|
49
|
+
* path: heifFileUri,
|
|
40
50
|
* quality: 0.7,
|
|
41
|
-
* width:
|
|
42
|
-
*
|
|
51
|
+
* width: 1920,
|
|
52
|
+
* height: 1080,
|
|
53
|
+
* mimeType: 'image/jpeg'
|
|
43
54
|
* });
|
|
44
|
-
* console.log('
|
|
55
|
+
* console.log('Converted to JPEG:', result.path);
|
|
45
56
|
* ```
|
|
46
57
|
* @example
|
|
47
58
|
* ```typescript
|
|
48
|
-
* // Android -
|
|
59
|
+
* // Android - Convert PNG to WebP
|
|
49
60
|
* const result = await FileCompressor.compressImage({
|
|
50
61
|
* path: 'content://downloads/document/123',
|
|
51
62
|
* quality: 0.6,
|
|
@@ -61,7 +72,7 @@ export interface FileCompressorPlugin {
|
|
|
61
72
|
* const result = await FileCompressor.compressImage({
|
|
62
73
|
* path: imagePath,
|
|
63
74
|
* quality: 0.75,
|
|
64
|
-
* width: 1920,
|
|
75
|
+
* width: 1920,
|
|
65
76
|
* mimeType: 'image/jpeg'
|
|
66
77
|
* });
|
|
67
78
|
* ```
|
|
@@ -104,8 +115,10 @@ export interface CompressImageOptions {
|
|
|
104
115
|
* - iOS: `file://` URLs or absolute paths
|
|
105
116
|
* - Android: `content://` URIs, `file://` URLs, or absolute paths
|
|
106
117
|
*
|
|
118
|
+
* Common input formats include JPEG, PNG, WebP, GIF, BMP, TIFF, and HEIF/HEIC.
|
|
119
|
+
*
|
|
107
120
|
* @since 7.0.0
|
|
108
|
-
* @example "file:///var/mobile/Containers/Data/Application/
|
|
121
|
+
* @example "file:///var/mobile/Containers/Data/Application/photo.heic" // iOS HEIF
|
|
109
122
|
* @example "content://com.android.providers.downloads.documents/document/msf%3A1000000485" // Android
|
|
110
123
|
* @example "/storage/emulated/0/Download/photo.png" // Android absolute path
|
|
111
124
|
*/
|
|
@@ -145,6 +158,7 @@ export interface CompressImageOptions {
|
|
|
145
158
|
*
|
|
146
159
|
* Higher quality values result in larger files but better visual quality.
|
|
147
160
|
* The actual compression ratio depends on the image content and format.
|
|
161
|
+
* PNG output ignores quality because it is lossless.
|
|
148
162
|
*
|
|
149
163
|
* @since 7.0.0
|
|
150
164
|
* @default 0.6
|
|
@@ -161,8 +175,8 @@ export interface CompressImageOptions {
|
|
|
161
175
|
* If only width is specified, height is calculated automatically
|
|
162
176
|
* to maintain the original aspect ratio.
|
|
163
177
|
*
|
|
164
|
-
* If both width and height are specified, the image is
|
|
165
|
-
*
|
|
178
|
+
* If both width and height are specified, the image is scaled to fit inside
|
|
179
|
+
* that box while preserving aspect ratio. Images are never upscaled.
|
|
166
180
|
*
|
|
167
181
|
* @since 7.0.0
|
|
168
182
|
* @example 1920 // Full HD width
|
|
@@ -178,8 +192,8 @@ export interface CompressImageOptions {
|
|
|
178
192
|
* If only height is specified, width is calculated automatically
|
|
179
193
|
* to maintain the original aspect ratio.
|
|
180
194
|
*
|
|
181
|
-
* If both width and height are specified, the image is
|
|
182
|
-
*
|
|
195
|
+
* If both width and height are specified, the image is scaled to fit inside
|
|
196
|
+
* that box while preserving aspect ratio. Images are never upscaled.
|
|
183
197
|
*
|
|
184
198
|
* @since 7.0.0
|
|
185
199
|
* @example 1080 // Full HD height
|
|
@@ -191,18 +205,24 @@ export interface CompressImageOptions {
|
|
|
191
205
|
* The MIME type of the compressed output image.
|
|
192
206
|
*
|
|
193
207
|
* **Platform Support:**
|
|
194
|
-
* - **iOS:** `image/jpeg`
|
|
195
|
-
* - **Android:** `image/jpeg`, `image/webp`
|
|
196
|
-
* - **Web:** `image/jpeg`, `image/webp`
|
|
208
|
+
* - **iOS:** `image/jpeg`, `image/png`, `image/heif`, `image/heic`, `image/webp` (iOS 14+)
|
|
209
|
+
* - **Android:** `image/jpeg`, `image/png`, `image/webp`
|
|
210
|
+
* - **Web:** `image/jpeg`, `image/png`, `image/webp`
|
|
211
|
+
*
|
|
212
|
+
* Use this option to convert the source image to another format while compressing.
|
|
197
213
|
*
|
|
198
214
|
* **Format Characteristics:**
|
|
199
215
|
* - **JPEG:** Universal support, good for photos, no transparency
|
|
200
|
-
* - **
|
|
216
|
+
* - **PNG:** Lossless, supports transparency
|
|
217
|
+
* - **WebP:** Better compression, supports transparency
|
|
218
|
+
* - **HEIF/HEIC:** Efficient photo format on iOS
|
|
201
219
|
*
|
|
202
220
|
* @since 7.0.0
|
|
203
221
|
* @default "image/jpeg"
|
|
204
|
-
* @example "image/jpeg" // JPEG format
|
|
205
|
-
* @example "image/
|
|
222
|
+
* @example "image/jpeg" // JPEG format
|
|
223
|
+
* @example "image/png" // PNG format
|
|
224
|
+
* @example "image/webp" // WebP format
|
|
225
|
+
* @example "image/heif" // HEIF format (iOS output)
|
|
206
226
|
*/
|
|
207
227
|
mimeType?: string;
|
|
208
228
|
}
|
|
@@ -229,7 +249,7 @@ export interface CompressImageResult {
|
|
|
229
249
|
*
|
|
230
250
|
* @since 7.0.0
|
|
231
251
|
* @example "/var/mobile/Containers/Data/tmp/compressed_abc123.jpg" // iOS
|
|
232
|
-
* @example "/data/user/0/com.app/cache/compressed_xyz789.
|
|
252
|
+
* @example "/data/user/0/com.app/cache/compressed_xyz789.webp" // Android
|
|
233
253
|
*/
|
|
234
254
|
path?: string;
|
|
235
255
|
/**
|