瀏覽代碼

use ImageFormat to load and save images correctly. Saving animated images in their origin file format, non-animated as pngs if images have transparency, jpeg if not - as before. Full support of apng files now

cyberta 4 年之前
父節點
當前提交
0502b4efba

+ 0 - 25
DcCore/DcCore/Helper/DcUtils.swift

@@ -91,31 +91,6 @@ public struct DcUtils {
         return acc
     }
 
-    public static func saveImage(image: UIImage) -> String? {
-        let suffix = image.isTransparent() ? "png" : "jpg"
-        guard let data = image.isTransparent() ? image.pngData() : image.jpegData(compressionQuality: 1.0) else {
-            return nil
-        }
-
-        return saveImage(data: data, suffix: suffix)
-    }
-
-    public static func saveImage(data: Data, suffix: String) -> String? {
-        let timestamp = Double(Date().timeIntervalSince1970)
-        guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask,
-                                                           appropriateFor: nil, create: false) as NSURL,
-            let path = directory.appendingPathComponent("\(timestamp).\(suffix)")
-            else { return nil }
-
-        do {
-            try data.write(to: path)
-            return path.relativePath
-        } catch {
-            DcContext.shared.logger?.info(error.localizedDescription)
-            return nil
-        }
-    }
-
     public static func getMimeTypeForPath(path: String) -> String {
         let url = NSURL(fileURLWithPath: path)
         let pathExtension = url.pathExtension

+ 4 - 7
DcShare/Helper/ShareAttachment.swift

@@ -78,8 +78,8 @@ class ShareAttachment {
             default:
                 self.dcContext.logger?.debug("Unexpected data: \(type(of: data))")
             }
-            if let result = result, let animatedImageData = result.animatedImageData {
-                let path = DcUtils.saveImage(data: animatedImageData, suffix: "gif")
+            if let result = result {
+                let path = ImageFormat.saveImage(image: result)
                 let msg = DcMsg(viewType: DC_MSG_GIF)
                 msg.setFile(filepath: path)
                 self.messages.append(msg)
@@ -110,14 +110,11 @@ class ShareAttachment {
                 result = nil
             }
             if let result = result {
+                let path: String? = ImageFormat.saveImage(image: result)
                 var msg: DcMsg
-                var path: String?
-                if result.sd_imageFormat == .webP,
-                   let imageData = result.sd_imageData() {
-                    path = DcUtils.saveImage(data: imageData, suffix: "webp")
+                if result.sd_imageFormat == .webP {
                     msg = DcMsg(viewType: DC_MSG_STICKER)
                 } else {
-                    path = DcUtils.saveImage(image: result)
                     msg = DcMsg(viewType: DC_MSG_IMAGE)
                 }
 

+ 11 - 23
deltachat-ios/Chat/ChatViewController.swift

@@ -1222,34 +1222,22 @@ class ChatViewController: UITableViewController {
 
     private func stageImage(url: NSURL) {
         keepKeyboard = true
-        if url.pathExtension == "gif" {
-            stageAnimatedImage(url: url)
-        } else if let data = try? Data(contentsOf: url as URL),
-                  let image = UIImage(data: data) {
-            stageImage(image)
-        }
-    }
-
-    private func stageAnimatedImage(url: NSURL) {
-        DispatchQueue.global().async {
-            if let path = url.path,
-               let result = SDAnimatedImage(contentsOfFile: path),
-               let animatedImageData = result.animatedImageData,
-               let pathInDocDir = DcUtils.saveImage(data: animatedImageData, suffix: "gif") {
-                DispatchQueue.main.async {
-                    self.draft.setAttachment(viewType: DC_MSG_GIF, path: pathInDocDir)
-                    self.configureDraftArea(draft: self.draft)
-                    self.messageInputBar.inputTextView.becomeFirstResponder()
-                }
+        DispatchQueue.global().async { [weak self] in
+            if let image = ImageFormat.loadImageFrom(url: url as URL) {
+                self?.stageImage(image)
             }
         }
     }
 
     private func stageImage(_ image: UIImage) {
         DispatchQueue.global().async {
-            if let pathInDocDir = DcUtils.saveImage(image: image) {
+            if let pathInDocDir = ImageFormat.saveImage(image: image) {
                 DispatchQueue.main.async {
-                    self.draft.setAttachment(viewType: DC_MSG_IMAGE, path: pathInDocDir)
+                    if pathInDocDir.suffix(4).contains(".gif") {
+                        self.draft.setAttachment(viewType: DC_MSG_GIF, path: pathInDocDir)
+                    } else {
+                        self.draft.setAttachment(viewType: DC_MSG_IMAGE, path: pathInDocDir)
+                    }
                     self.configureDraftArea(draft: self.draft)
                     self.messageInputBar.inputTextView.becomeFirstResponder()
                 }
@@ -1259,7 +1247,7 @@ class ChatViewController: UITableViewController {
 
     private func sendImage(_ image: UIImage, message: String? = nil) {
         DispatchQueue.global().async {
-            if let path = DcUtils.saveImage(image: image) {
+            if let path = ImageFormat.saveImage(image: image) {
                 self.sendAttachmentMessage(viewType: DC_MSG_IMAGE, filePath: path, message: message)
             }
         }
@@ -1267,7 +1255,7 @@ class ChatViewController: UITableViewController {
 
     private func sendSticker(_ image: UIImage) {
         DispatchQueue.global().async {
-            if let path = DcUtils.saveImage(image: image) {
+            if let path = ImageFormat.saveImage(image: image) {
                 self.sendAttachmentMessage(viewType: DC_MSG_STICKER, filePath: path, message: nil)
             }
         }

+ 32 - 0
deltachat-ios/Helper/ImageFormat.swift

@@ -1,6 +1,7 @@
 import Foundation
 import UIKit
 import SDWebImage
+import DcCore
 
 enum ImageFormat: String {
     case png, jpg, gif, tiff, webp, heic, bmp, unknown
@@ -67,4 +68,35 @@ extension ImageFormat {
         return loadImageFrom(data: imageData)
     }
 
+    public static func saveImage(image: UIImage) -> String? {
+        if image.sd_isAnimated,
+           let data = image.sd_imageData() {
+            let format = ImageFormat.get(from: data)
+            if format != .unknown {
+                return ImageFormat.saveImage(data: data, suffix: format.rawValue)
+            }
+        }
+        let suffix = image.isTransparent() ? "png" : "jpg"
+        guard let data = image.isTransparent() ? image.pngData() : image.jpegData(compressionQuality: 1.0) else {
+            return nil
+        }
+
+        return saveImage(data: data, suffix: suffix)
+    }
+
+    public static func saveImage(data: Data, suffix: String) -> String? {
+        let timestamp = Double(Date().timeIntervalSince1970)
+        guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask,
+                                                           appropriateFor: nil, create: false) as NSURL,
+            let path = directory.appendingPathComponent("\(timestamp).\(suffix)")
+            else { return nil }
+
+        do {
+            try data.write(to: path)
+            return path.relativePath
+        } catch {
+            DcContext.shared.logger?.info(error.localizedDescription)
+            return nil
+        }
+    }
 }