Skip to content

Commit ac7827d

Browse files
[Fix]: Properly handle base64 image compression for iOS (#374)
* [fix]: Properly handle base64 image compression * [fix]: Change fileSize typing to Int instead of Double
1 parent 90d03d2 commit ac7827d

File tree

3 files changed

+86
-48
lines changed

3 files changed

+86
-48
lines changed

ios/Image/ImageCompressor.swift

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,33 @@ class ImageCompressor {
101101
return UIImage()
102102
}
103103

104-
static func isCompressedSizeLessThanActualFile(sourceFileUrl: String,compressedFileUrl: String)-> Bool {
105-
let sourceVideoURL = URL(string: sourceFileUrl)
106-
let sourcefileSize:Double=Utils.getfileSizeInBytes(forURL:sourceVideoURL!)
104+
static func isCompressedSizeLessThanActualFile(sourceFileUrl: String?, sourceData: Data?, compressedFileUrl: String)-> Bool {
105+
var sourcefileSize: Int = 0
107106

108-
let compressedVideoURL = URL(string: compressedFileUrl)
109-
let compressedfileSize:Double=Utils.getfileSizeInBytes(forURL:compressedVideoURL!)
107+
if let _sourceFileUrl = sourceFileUrl {
108+
let sourceVideoURL = URL(string: _sourceFileUrl)
109+
sourcefileSize = Utils.getfileSizeInBytes(forURL: sourceVideoURL!)
110+
}
111+
112+
if let _sourceData = sourceData {
113+
sourcefileSize = _sourceData.count
114+
}
115+
116+
let compressedFileURL = URL(string: compressedFileUrl)
117+
let compressedfileSize = Utils.getfileSizeInBytes(forURL: compressedFileURL!)
110118

111-
if(compressedfileSize<=sourcefileSize)
112-
{
113-
return true
119+
if compressedfileSize <= sourcefileSize {
120+
return true
114121
}
122+
115123
return false
116124
}
117125

118126
static func isPNG(_ data: Data) -> Bool {
119127
return data.starts(with: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
120128
}
121129

122-
static func copyExifInfo(actualImagePath:String, image: UIImage, data: Data) -> Data {
130+
static func copyExifInfo(actualImagePath: String, image: UIImage, data: Data) -> Data {
123131
let fileURL = URL(string: actualImagePath)!
124132
let filePath = fileURL.path
125133

@@ -156,46 +164,45 @@ class ImageCompressor {
156164
return destinationData as Data
157165
}
158166

159-
static func writeImage(_ image: UIImage, output: Int, quality: Float, outputExtension: String, isBase64: Bool,disablePngTransparency:Bool,isEnableAutoCompress:Bool,actualImagePath:String)-> String{
167+
static func writeImage(_ image: UIImage, output: Int, quality: Float, outputExtension: String, isBase64: Bool, disablePngTransparency: Bool, isEnableAutoCompress: Bool, actualImagePath: String?)-> String {
160168
var data: Data
161169
var exception: NSException?
170+
162171
switch OutputType(rawValue: output)! {
163172
case .jpg:
164173
data = image.jpegData(compressionQuality: CGFloat(quality))!
165174
case .png:
166-
if(disablePngTransparency)
167-
{
175+
if disablePngTransparency {
168176
data = image.jpegData(compressionQuality: CGFloat(quality))!
169177
let compressedImage = UIImage(data: data)
170178
data = compressedImage!.pngData()!
179+
} else {
180+
data = image.pngData()!
171181
}
172-
else
173-
{
174-
data=image.pngData()!
175-
}
176-
177182
}
178183

179-
data=copyExifInfo(actualImagePath: actualImagePath, image: UIImage(data: data) ?? image, data: data)
180-
184+
if let _actualImagePath = actualImagePath {
185+
data = copyExifInfo(actualImagePath: _actualImagePath, image: UIImage(data: data) ?? image, data: data)
186+
}
181187

182188
if isBase64 {
183189
return data.base64EncodedString(options: [])
184190
} else {
185191
let filePath = Utils.generateCacheFilePath(outputExtension)
192+
186193
do {
187194
try data.write(to: URL(fileURLWithPath: filePath), options: .atomic)
188195
let returnablePath = makeValidUri(filePath)
189-
if(isEnableAutoCompress==true)
190-
{
191-
if(self.isCompressedSizeLessThanActualFile(sourceFileUrl: actualImagePath,compressedFileUrl: returnablePath))
192-
{
196+
197+
if isEnableAutoCompress == true {
198+
if self.isCompressedSizeLessThanActualFile(sourceFileUrl: actualImagePath, sourceData: data, compressedFileUrl: returnablePath) {
193199
return returnablePath
194-
}
195-
else
196-
{
197-
MediaCache.deleteFile(atPath:returnablePath)
198-
return actualImagePath
200+
} else {
201+
MediaCache.deleteFile(atPath: returnablePath)
202+
203+
if let _actualImagePath = actualImagePath {
204+
return _actualImagePath
205+
}
199206
}
200207
}
201208

@@ -210,8 +217,8 @@ class ImageCompressor {
210217
}
211218

212219

213-
static func manualCompress(_ image: UIImage, output: Int, quality: Float, outputExtension: String, isBase64: Bool,disablePngTransparency:Bool,actualImagePath:String) -> String {
214-
return writeImage(image, output: output, quality: quality, outputExtension: outputExtension, isBase64: isBase64, disablePngTransparency: disablePngTransparency,isEnableAutoCompress: false,actualImagePath: actualImagePath)
220+
static func manualCompress(_ image: UIImage, output: Int, quality: Float, outputExtension: String, isBase64: Bool, disablePngTransparency: Bool, actualImagePath: String?) -> String {
221+
return writeImage(image, output: output, quality: quality, outputExtension: outputExtension, isBase64: isBase64, disablePngTransparency: disablePngTransparency, isEnableAutoCompress: false, actualImagePath: actualImagePath)
215222
}
216223

217224

@@ -280,23 +287,27 @@ class ImageCompressor {
280287
}
281288

282289

283-
static func manualCompressHandler(_ imagePath: String, options: ImageCompressorOptions) -> String {
290+
static func manualCompressHandler(imagePath: String?, base64: String?, options: ImageCompressorOptions) -> String {
284291
var exception: NSException?
285292
var image: UIImage?
286293

287294
switch options.input {
288295
case .base64:
289-
image = ImageCompressor.decodeImage(imagePath)
296+
if let _base64 = base64 {
297+
image = ImageCompressor.decodeImage(_base64)
298+
}
290299
case .uri:
291-
image = ImageCompressor.loadImage(imagePath)
300+
if let _imagePath = imagePath {
301+
image = ImageCompressor.loadImage(_imagePath)
302+
}
292303
}
293304

294305
if let _image = image {
295306
image = ImageCompressor.scaleAndRotateImage(_image)
296307
let outputExtension = ImageCompressorOptions.getOutputInString(options.output)
297308
let resizedImage = ImageCompressor.manualResize(image!, maxWidth: options.maxWidth, maxHeight: options.maxHeight)
298309
let isBase64 = options.returnableOutputType == .rbase64
299-
return ImageCompressor.manualCompress(resizedImage, output: options.output.rawValue, quality: options.quality, outputExtension: outputExtension, isBase64: isBase64,disablePngTransparency: options.disablePngTransparency,actualImagePath: imagePath)
310+
return ImageCompressor.manualCompress(resizedImage, output: options.output.rawValue, quality: options.quality, outputExtension: outputExtension, isBase64: isBase64,disablePngTransparency: options.disablePngTransparency, actualImagePath: imagePath)
300311
} else {
301312
exception = NSException(name: NSExceptionName(rawValue: "unsupported_value"), reason: "Unsupported value type.", userInfo: nil)
302313
exception?.raise()
@@ -306,9 +317,20 @@ class ImageCompressor {
306317
}
307318

308319

309-
static func autoCompressHandler(_ imagePath: String, options: ImageCompressorOptions) -> String {
320+
static func autoCompressHandler(imagePath: String?, base64: String?, options: ImageCompressorOptions) -> String {
310321
var exception: NSException?
311-
var image = ImageCompressor.loadImage(imagePath)
322+
var image: UIImage?
323+
324+
switch options.input {
325+
case .base64:
326+
if let _base64 = base64 {
327+
image = ImageCompressor.decodeImage(_base64)
328+
}
329+
case .uri:
330+
if let _imagePath = imagePath {
331+
image = ImageCompressor.loadImage(_imagePath)
332+
}
333+
}
312334

313335
if var image = image {
314336
image = ImageCompressor.scaleAndRotateImage(image)
@@ -343,9 +365,13 @@ class ImageCompressor {
343365
let isBase64 = options.returnableOutputType == .rbase64
344366

345367
if let img = UIGraphicsGetImageFromCurrentImageContext() {
346-
return writeImage(img, output: options.output.rawValue, quality: Float(compressionQuality), outputExtension: outputExtension, isBase64: isBase64, disablePngTransparency: options.disablePngTransparency,isEnableAutoCompress: true,actualImagePath: imagePath)
368+
return writeImage(img, output: options.output.rawValue, quality: Float(compressionQuality), outputExtension: outputExtension, isBase64: isBase64, disablePngTransparency: options.disablePngTransparency, isEnableAutoCompress: true, actualImagePath: imagePath)
347369
}
370+
} else {
371+
exception = NSException(name: NSExceptionName(rawValue: "unsupported_value"), reason: "Unsupported value type.", userInfo: nil)
372+
exception?.raise()
348373
}
374+
349375
return ""
350376
}
351377

ios/Image/ImageMain.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,29 @@
77

88
import Foundation
99
class ImageMain {
10-
static func image_compress(_ imagePath: String, optionMap: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
10+
static func image_compress(_ value: String, optionMap: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
1111
do {
1212
let options = ImageCompressorOptions.fromDictionary(optionMap as! [String : Any])
13-
ImageCompressor.getAbsoluteImagePath(imagePath, options: options) { absoluteImagePath in
13+
14+
if options.input != InputType.base64 {
15+
ImageCompressor.getAbsoluteImagePath(value, options: options) { absoluteImagePath in
16+
if options.autoCompress {
17+
let result = ImageCompressor.autoCompressHandler(imagePath: absoluteImagePath, base64: nil, options: options)
18+
resolve(result)
19+
} else {
20+
let result = ImageCompressor.manualCompressHandler(imagePath: absoluteImagePath, base64: nil, options: options)
21+
resolve(result)
22+
}
23+
MediaCache.removeCompletedImagePath(absoluteImagePath)
24+
}
25+
} else {
1426
if options.autoCompress {
15-
let result = ImageCompressor.autoCompressHandler(absoluteImagePath, options: options)
27+
let result = ImageCompressor.autoCompressHandler(imagePath: nil, base64: value, options: options)
1628
resolve(result)
1729
} else {
18-
let result = ImageCompressor.manualCompressHandler(absoluteImagePath, options: options)
30+
let result = ImageCompressor.manualCompressHandler(imagePath: nil, base64: value, options: options)
1931
resolve(result)
2032
}
21-
MediaCache.removeCompletedImagePath(absoluteImagePath)
2233
}
2334
} catch {
2435
reject(error.localizedDescription, error.localizedDescription, nil)

ios/Utils/Utils.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ class Utils {
106106
}
107107
}
108108

109-
static func getfileSizeInBytes(forURL url: Any) -> Double {
109+
static func getfileSizeInBytes(forURL url: Any) -> Int {
110110
var fileURL: URL?
111-
var fileSize: Double = 0.0
111+
var fileSize: Int = 0
112112

113113
if (url is URL) {
114114
let urlWithSlash = Utils.slashifyFilePath(path: (url as? URL)?.absoluteString)
@@ -120,11 +120,12 @@ class Utils {
120120
return fileSize
121121
}
122122

123-
var fileSizeValue = 0.0
123+
var fileSizeValue = 0
124124

125-
try? fileSizeValue = (fileURL?.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).allValues.first?.value as! Double?)!
126-
if fileSizeValue > 0.0 {
127-
fileSize = Double(fileSizeValue)
125+
try? fileSizeValue = (fileURL?.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).allValues.first?.value as! Int)
126+
127+
if fileSizeValue > 0 {
128+
fileSize = fileSizeValue
128129
}
129130

130131
return fileSize

0 commit comments

Comments
 (0)