From 2c7661628bba24ab31b3f28f55666600adf262d8 Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Sat, 3 Aug 2024 01:40:28 +0200 Subject: [PATCH] send images as sticker not only when they have the 140x140 dimensions, but also when they have transparent corner(s) also add the send as sticker logic to darg and droping an image into a chat, this makes it super convinient to create stickers from images with iOS's AI selection feature. (long press to select your favorite pet or person then hold the object and use a second finger to navigate to the chat you want to send it to.) --- .../Extensions/UIImage+Extensions.swift | 35 +++++++++++++++++++ deltachat-ios/Chat/ChatViewController.swift | 10 ++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/DcCore/DcCore/Extensions/UIImage+Extensions.swift b/DcCore/DcCore/Extensions/UIImage+Extensions.swift index 530224ecb..a68a2efba 100644 --- a/DcCore/DcCore/Extensions/UIImage+Extensions.swift +++ b/DcCore/DcCore/Extensions/UIImage+Extensions.swift @@ -53,5 +53,40 @@ public extension UIImage { guard let alpha: CGImageAlphaInfo = self.cgImage?.alphaInfo else { return false } return alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast } + + func hasTransparentCorner() -> Bool { + if !self.isTransparent() { + return false + } + guard let cgImage = self.cgImage, + let data = cgImage.dataProvider?.data as Data?, + let dataPtr = data.withUnsafeBytes({ $0.bindMemory(to: UInt8.self).baseAddress }), + !data.isEmpty else { + return false // Unable to get the CGImage or image data + } + + let width = cgImage.width + let height = cgImage.height + let bytesPerRow = cgImage.bytesPerRow + + // Check the alpha values of the pixels at the corners + let topLeftIndex = 0 + let topRightIndex = max(0, width - 1) + let bottomLeftIndex = max(0, bytesPerRow * (height - 1)) + let bottomRightIndex = max(0, bytesPerRow * (height - 1) + width - 1) + var hasTransparentCorner = false + if dataPtr[topLeftIndex] < 255 { + hasTransparentCorner = true + } else if dataPtr[topRightIndex] < 255 { + hasTransparentCorner = true + } else if dataPtr[bottomLeftIndex] < 255 { + hasTransparentCorner = true + } else if dataPtr[min(data.count - 1, bottomRightIndex)] < 255 { + hasTransparentCorner = true + } + + return hasTransparentCorner + } + } diff --git a/deltachat-ios/Chat/ChatViewController.swift b/deltachat-ios/Chat/ChatViewController.swift index 70ae4370e..9cad165d0 100644 --- a/deltachat-ios/Chat/ChatViewController.swift +++ b/deltachat-ios/Chat/ChatViewController.swift @@ -2760,8 +2760,7 @@ extension ChatViewController: UITextViewDelegate { // MARK: - ChatInputTextViewPasteDelegate extension ChatViewController: ChatInputTextViewPasteDelegate { func onImagePasted(image: UIImage) { - let isSticker = image.size.equalTo(CGSize(width: 140, height: 140)) - + let isSticker = image.size.equalTo(CGSize(width: 140, height: 140)) || image.hasTransparentCorner() if isSticker { sendSticker(image) } else { @@ -2800,7 +2799,12 @@ extension ChatViewController: WebxdcSelectorDelegate { // MARK: - ChatDropInteractionDelegate extension ChatViewController: ChatDropInteractionDelegate { func onImageDragAndDropped(image: UIImage) { - stageImage(image) + let isSticker = image.size.equalTo(CGSize(width: 140, height: 140)) || image.hasTransparentCorner() + if isSticker { + sendSticker(image) + } else { + stageImage(image) + } } func onVideoDragAndDropped(url: NSURL) {