Browse Source

Merge pull request #495 from deltachat/paste_images_fix_compression

Paste images, fix compression
bjoern 5 years ago
parent
commit
681d671933

+ 16 - 3
deltachat-ios/Controller/ChatViewController.swift

@@ -874,7 +874,13 @@ extension ChatViewController: MessagesDataSource {
         })
     }
 
-    private func sendImage(_ image: UIImage) {
+    private func sendTextMessage(message: String) {
+        DispatchQueue.global().async {
+            self.dcContext.sendTextInChat(id: self.chatId, message: message)
+        }
+    }
+
+    private func sendImage(_ image: UIImage, message: String? = nil) {
         DispatchQueue.global().async {
             if let compressedImage = image.dcCompress() {
                 // at this point image is compressed by 85% by default
@@ -883,6 +889,7 @@ extension ChatViewController: MessagesDataSource {
                 let msg = DcMsg(viewType: DC_MSG_IMAGE)
                 msg.setFile(filepath: path, mimeType: "image/jpeg")
                 msg.setDimension(width: pixelSize.width, height: pixelSize.height)
+                msg.text = (message ?? "").isEmpty ? nil : message
                 msg.sendInChat(id: self.chatId)
             }
         }
@@ -1276,10 +1283,16 @@ extension ChatViewController: MessageLabelDelegate {
 // MARK: - MessageInputBarDelegate
 extension ChatViewController: InputBarAccessoryViewDelegate {
     func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {
-        DispatchQueue.global().async {
-            dc_send_text_msg(mailboxPointer, UInt32(self.chatId), text)
+        if inputBar.inputTextView.images.isEmpty {
+            self.sendTextMessage(message: text.trimmingCharacters(in: .whitespacesAndNewlines))
+        } else {
+            let trimmedText = text.replacingOccurrences(of: "\u{FFFC}", with: "", options: .literal, range: nil)
+                .trimmingCharacters(in: .whitespacesAndNewlines)
+            // only 1 attachment allowed for now, thus it takes the first one
+            self.sendImage(inputBar.inputTextView.images[0], message: trimmedText)
         }
         inputBar.inputTextView.text = String()
+        inputBar.inputTextView.attributedText = nil
     }
 }
 

+ 5 - 1
deltachat-ios/DC/Wrapper.swift

@@ -112,6 +112,10 @@ class DcContext {
         dc_forward_msgs(contextPointer, [UInt32(msgId)], 1, UInt32(chat))
     }
 
+    func sendTextInChat(id: Int, message: String) {
+        dc_send_text_msg(contextPointer, UInt32(id), message)
+    }
+
     func initiateKeyTransfer() -> String? {
         if let cString = dc_initiate_key_transfer(self.contextPointer) {
             let swiftString = String(cString: cString)
@@ -785,7 +789,7 @@ class DcMsg: MessageType {
     }
 
     func setDimension(width: CGFloat, height: CGFloat) {
-        dc_msg_set_dimension(messagePointer, Int32(exactly: width)!, Int32(exactly: height)!)
+        dc_msg_set_dimension(messagePointer, Int32(width), Int32(height))
     }
 
     var filesize: Int {

+ 19 - 6
deltachat-ios/Extensions/UIImage+Extension.swift

@@ -71,18 +71,31 @@ extension UIImage {
         return newImage
     }
 
-    // source: https://stackoverflow.com/questions/29137488/how-do-i-resize-the-uiimage-to-reduce-upload-image-size // slightly changed
+    // if an image has an alpha channel we try to keep it, using PNG formatting instead of JPEG
+    // PNGs are less compressed than JPEGs - to keep the message sizes small,
+    // the size of PNG imgaes will be scaled down
     func scaleDownAndCompress(toMax: Float) -> UIImage? {
-        let rect = getResizedRectangle(toMax: toMax)
-        //50 percent compression
-        let compressionQuality: Float = 0.5
-        UIGraphicsBeginImageContext(rect.size)
+        let rect = getResizedRectangle(toMax: self.isTransparent() ?
+            min(Float(self.size.width) / 2, toMax / 2) :
+            toMax)
+
+        UIGraphicsBeginImageContextWithOptions(rect.size, !self.isTransparent(), 0.0)
         draw(in: rect)
         let img = UIGraphicsGetImageFromCurrentImageContext()
-        let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality))
+
+        let imageData = self.isTransparent() ?
+            img?.pngData() :
+            img?.jpegData(compressionQuality: 0.85)
+
         UIGraphicsEndImageContext()
         return UIImage(data: imageData!)
     }
+
+    public func isTransparent() -> Bool {
+        guard let alpha: CGImageAlphaInfo = self.cgImage?.alphaInfo else { return false }
+        return alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast
+      }
+
 }
 
 public enum ImageType: String {

+ 2 - 15
deltachat-ios/Helper/Utils.swift

@@ -119,27 +119,14 @@ struct Utils {
         return addressParts.joined(separator: ", ")
     }
 
+    // compression needs to be done before in UIImage.dcCompress()
     static func saveImage(image: UIImage) -> String? {
         guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask,
             appropriateFor: nil, create: false) as NSURL else {
             return nil
         }
 
-        let size = image.size.applying(CGAffineTransform(scaleX: 0.2, y: 0.2))
-        let hasAlpha = false
-        let scale: CGFloat = 0.0
-
-        UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
-        image.draw(in: CGRect(origin: CGPoint.zero, size: size))
-
-        let scaledImageI = UIGraphicsGetImageFromCurrentImageContext()
-        UIGraphicsEndImageContext()
-
-        guard let scaledImage = scaledImageI else {
-            return nil
-        }
-
-        guard let data = scaledImage.jpegData(compressionQuality: 0.9) else {
+        guard let data = image.isTransparent() ? image.pngData() : image.jpegData(compressionQuality: 1.0) else {
             return nil
         }