diff --git a/apps/ios/SimpleXChat/ImageUtils.swift b/apps/ios/SimpleXChat/ImageUtils.swift index 9702408c27..9bf15992db 100644 --- a/apps/ios/SimpleXChat/ImageUtils.swift +++ b/apps/ios/SimpleXChat/ImageUtils.swift @@ -101,17 +101,12 @@ public func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64, hasAlpha } public func resizeImageToStrSizeSync(_ image: UIImage, maxDataSize: Int64) -> String? { - var img = image - let hasAlpha = imageHasAlpha(image) - var str = compressImageStr(img, hasAlpha: hasAlpha) - var dataSize = str?.count ?? 0 - while dataSize != 0 && dataSize > maxDataSize { - let ratio = sqrt(Double(dataSize) / Double(maxDataSize)) - let clippedRatio = min(ratio, 2.0) - img = reduceSize(img, ratio: clippedRatio, hasAlpha: hasAlpha) - str = compressImageStr(img, hasAlpha: hasAlpha) - dataSize = str?.count ?? 0 - } + // XXX: only needed when the original encoding isn't available + let tmpFile = generateNewFileName(getTempFilesDirectory().path + "/" + "resize", "png", fullPath: true) + saveFile(image.pngData(), tmpFile) // encode as png and let the backend deal with alpha and formats + let str = chat_resize_image_to_str_size(filePath, maxDataSize) + removeFile(tmpFile) + guard let dataSize = str?.count > 0 else { return nil } logger.debug("resizeImageToStrSize final \(dataSize)") return str } diff --git a/src/Simplex/Chat/Mobile.hs b/src/Simplex/Chat/Mobile.hs index 5d55b21fa6..87b7302177 100644 --- a/src/Simplex/Chat/Mobile.hs +++ b/src/Simplex/Chat/Mobile.hs @@ -21,6 +21,7 @@ import qualified Data.ByteString.Base64.URL as U import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as LB +import Data.Either (fromRight) import Data.Functor (($>)) import Data.List (find) import qualified Data.List.NonEmpty as L @@ -198,7 +199,10 @@ cChatJsonLength s = fromIntegral . subtract 2 . LB.length . J.encode . safeDecod -- cChatResizeImageToDataSize :: CString -> CInt -> IO CString -- cChatResizeImageToDataSize path maxSize = error "todo" --- | Downscale image at path until its data-uri encoding fits into specified size +-- | Downscale image at path until its data-uri encoding fits into specified size. +-- Returns data-uri/base64 encoded image as 0-terminated string. +-- Empty result string means operation failure. +-- The caller must free the result ptr. cChatResizeImageToStrSize :: CString -> CInt -> IO CString cChatResizeImageToStrSize fp' maxSize = do fp <- peekCString fp' @@ -206,7 +210,7 @@ cChatResizeImageToStrSize fp' maxSize = do (ri, _) <- liftIOEither $ readResizeable fp let resized = resizeImageToStrSize (fromIntegral maxSize) ri if LB.length resized > fromIntegral maxSize then throwError "unable to fit" else pure resized - either (const $ pure nullPtr) newCStringFromLazyBS res + newCStringFromLazyBS $ fromRight "" res -- -- | Strip EXIF etc metadata from image, inlplace -- cChatStripImageMetadata :: CString -> IO CBool