瀏覽代碼

Merge pull request #105 from deltachat/PhotoCompress

integrated photo compression before sending
nayooti 6 年之前
父節點
當前提交
cd672fec74

+ 4 - 34
deltachat-ios/Controller/ChatViewController.swift

@@ -5,7 +5,6 @@
 //  Created by Bastian van de Wetering on 08.11.17.
 //  Copyright © 2017 Jonas Reinsch. All rights reserved.
 //
-import ALCameraViewController
 import MapKit
 import MessageKit
 import QuickLook
@@ -769,48 +768,19 @@ extension ChatViewController: MessagesLayoutDelegate {
 		showClipperOptions()
 	}
 
-	private func photoButtonPressed() {
-		if UIImagePickerController.isSourceTypeAvailable(.camera) {
-			let cameraViewController = CameraViewController { [weak self] image, _ in
-				self?.dismiss(animated: true, completion: nil)
-
-				DispatchQueue.global().async {
-					if let pickedImage = image {
-						let width = Int32(exactly: pickedImage.size.width)!
-						let height = Int32(exactly: pickedImage.size.height)!
-						let path = Utils.saveImage(image: pickedImage)
-						let msg = dc_msg_new(mailboxPointer, DC_MSG_IMAGE)
-						dc_msg_set_file(msg, path, "image/jpeg")
-						dc_msg_set_dimension(msg, width, height)
-						dc_send_msg(mailboxPointer, UInt32(self!.chatId), msg)
-						// cleanup
-						dc_msg_unref(msg)
-					}
-				}
-			}
-
-			present(cameraViewController, animated: true, completion: nil)
-		} else {
-			let alert = UIAlertController(title: "Camera is not available", message: nil, preferredStyle: .alert)
-			alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
-				self.dismiss(animated: true, completion: nil)
-			}))
-			present(alert, animated: true, completion: nil)
-		}
-	}
-
 	private func showClipperOptions() {
 		let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
 
-		let photoAction = PhotoPickerAlertAction(title: "Photo", style: .default, handler: photoActionPressed(_:))
+		let photoAction = PhotoPickerAlertAction(title: "Photo", style: .default, handler: photoButtonPressed(_:))
 		alert.addAction(photoAction)
 		alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
 		self.present(alert, animated: true, completion: nil)
 	}
 
-	private func photoActionPressed(_ action: UIAlertAction) {
-		photoButtonPressed()
+	private func photoButtonPressed(_ action: UIAlertAction) {
+		coordinator?.showCameraViewController()
 	}
+
 }
 
 // MARK: - MessageCellDelegate

+ 57 - 7
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -7,6 +7,8 @@
 //
 
 import UIKit
+import ALCameraViewController
+
 
 class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 	private let window: UIWindow
@@ -138,7 +140,7 @@ class ContactListCoordinator: Coordinator {
 
 	func showChat(chatId: Int) {
 		let chatVC = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatVC.coordinator = coordinator
 		navigationController.pushViewController(chatVC, animated: true)
@@ -147,9 +149,18 @@ class ContactListCoordinator: Coordinator {
 
 // since mailbox and chatView -tab both use ChatViewController we want to be able to assign different functionality via coordinators -> therefore we override unneeded functions such as showChatDetail -> maybe find better solution in longterm
 class MailboxCoordinator: ChatViewCoordinator {
+
+	init(navigationController: UINavigationController) {
+		super.init(navigationController: navigationController, chatId: -1)
+	}
+
 	override func showChatDetail(chatId _: Int) {
 		// ignore for now
 	}
+
+	override func showCameraViewController() {
+		// ignore
+	}
 }
 
 class ProfileCoordinator: Coordinator {
@@ -179,7 +190,7 @@ class ChatListCoordinator: Coordinator {
 
 	func showChat(chatId: Int) {
 		let chatVC = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatVC.coordinator = coordinator
 		navigationController.pushViewController(chatVC, animated: true)
@@ -319,7 +330,7 @@ class NewChatCoordinator: Coordinator {
 
 	func showChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatViewController.coordinator = coordinator
 		navigationController.pushViewController(chatViewController, animated: true)
@@ -360,11 +371,13 @@ class GroupChatDetailCoordinator: Coordinator {
 
 class ChatViewCoordinator: Coordinator {
 	let navigationController: UINavigationController
+	let chatId: Int
 
 	var childCoordinators: [Coordinator] = []
 
-	init(navigationController: UINavigationController) {
+	init(navigationController: UINavigationController, chatId: Int) {
 		self.navigationController = navigationController
+		self.chatId = chatId
 	}
 
 	func showChatDetail(chatId: Int) {
@@ -397,6 +410,43 @@ class ChatViewCoordinator: Coordinator {
 		navigationController.pushViewController(contactDetailController, animated: true)
 		// navigationController.present(nav, animated: true, completion: nil)
 	}
+
+	func showCameraViewController() {
+		if UIImagePickerController.isSourceTypeAvailable(.camera) {
+			let cameraViewController = CameraViewController { [weak self] image, _ in
+				self?.navigationController.dismiss(animated: true, completion: nil)
+
+				DispatchQueue.global().async {
+					if let compressedImage = image?.dcCompress() {
+						// at this point image is compressed by 85% by default
+						let pixelSize = compressedImage.imageSizeInPixel()
+						let width = Int32(exactly: pixelSize.width)!
+						let height =  Int32(exactly: pixelSize.height)!
+//						let width = Int32(exactly: compressedImage.size.width)!
+//						let height = Int32(exactly: compressedImage.size.height)!
+						print("CompressImage width: \(width)")
+						print("CompressImage height: \(height)")
+						let path = Utils.saveImage(image: compressedImage)
+						let msg = dc_msg_new(mailboxPointer, DC_MSG_IMAGE)
+						dc_msg_set_file(msg, path, "image/jpeg")
+						dc_msg_set_dimension(msg, width, height)
+						dc_send_msg(mailboxPointer, UInt32(self!.chatId), msg)
+						// cleanup
+						dc_msg_unref(msg)
+					}
+				}
+			}
+
+			navigationController.present(cameraViewController, animated: true, completion: nil)
+		} else {
+			let alert = UIAlertController(title: "Camera is not available", message: nil, preferredStyle: .alert)
+			alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
+				self.navigationController.dismiss(animated: true, completion: nil)
+			}))
+			navigationController.present(alert, animated: true, completion: nil)
+		}
+
+	}
 }
 
 class NewGroupCoordinator: Coordinator {
@@ -428,7 +478,7 @@ class GroupNameCoordinator: Coordinator {
 
 	func showGroupChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatViewController.coordinator = coordinator
 		navigationController.popToRootViewController(animated: false)
@@ -447,7 +497,7 @@ class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
 
 	func showChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatViewController.coordinator = coordinator
 		navigationController.popToRootViewController(animated: false)
@@ -491,7 +541,7 @@ class EditContactCoordinator: Coordinator, EditContactCoordinatorProtocol {
 
 	func showChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
-		let coordinator = ChatViewCoordinator(navigationController: navigationController)
+		let coordinator = ChatViewCoordinator(navigationController: navigationController, chatId: chatId)
 		childCoordinators.append(coordinator)
 		chatViewController.coordinator = coordinator
 		navigationController.popToRootViewController(animated: false)

+ 51 - 0
deltachat-ios/Helper/Extensions.swift

@@ -135,3 +135,54 @@ extension MRContact {
     }
   }
 }
+
+extension UIImage {
+
+	func dcCompress(toMax target: Float = 1280) -> UIImage? {
+		return resize(toMax: target)
+	}
+
+	func imageSizeInPixel() -> CGSize {
+		let heightInPoints = size.height
+		let heightInPixels = heightInPoints * scale
+		let widthInPoints = size.width
+		let widthInPixels = widthInPoints * scale
+		return CGSize(width: widthInPixels, height: heightInPixels)
+	}
+
+	// source: https://stackoverflow.com/questions/29137488/how-do-i-resize-the-uiimage-to-reduce-upload-image-size // slightly changed
+	func resize(toMax: Float) -> UIImage? {
+		var actualHeight = Float(size.height)
+		var actualWidth = Float(size.width)
+		let maxHeight: Float = toMax
+		let maxWidth: Float = toMax
+		var imgRatio: Float = actualWidth / actualHeight
+		let maxRatio: Float = maxWidth / maxHeight
+		let compressionQuality: Float = 0.5
+		//50 percent compression
+		if actualHeight > maxHeight || actualWidth > maxWidth {
+			if imgRatio < maxRatio {
+				//adjust width according to maxHeight
+				imgRatio = maxHeight / actualHeight
+				actualWidth = imgRatio * actualWidth
+				actualHeight = maxHeight
+			} else if imgRatio > maxRatio {
+				//adjust height according to maxWidth
+				imgRatio = maxWidth / actualWidth
+				actualHeight = imgRatio * actualHeight
+				actualWidth = maxWidth
+			} else {
+				actualHeight = maxHeight
+				actualWidth = maxWidth
+			}
+		}
+
+		let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
+		UIGraphicsBeginImageContext(rect.size)
+		draw(in: rect)
+		let img = UIGraphicsGetImageFromCurrentImageContext()
+		let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality))
+		UIGraphicsEndImageContext()
+		return UIImage(data: imageData!)
+	}
+}