From 867ac85b71ef71678e441e83534dceb9ef068af3 Mon Sep 17 00:00:00 2001 From: fanyu Date: Mon, 26 Sep 2022 14:10:35 +0800 Subject: [PATCH] Support live text --- Mixin.xcodeproj/project.pbxproj | 4 ++ .../Chat/GalleryImageItemViewController.swift | 9 ++- .../Chat/Views/LiveTextImageView.swift | 56 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 Mixin/UserInterface/Controllers/Chat/Views/LiveTextImageView.swift diff --git a/Mixin.xcodeproj/project.pbxproj b/Mixin.xcodeproj/project.pbxproj index 7e58df09c4..0b89425102 100644 --- a/Mixin.xcodeproj/project.pbxproj +++ b/Mixin.xcodeproj/project.pbxproj @@ -558,6 +558,7 @@ 7C2475C727795BC100112A30 /* DeleteAccountTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2475C627795BC100112A30 /* DeleteAccountTableHeaderView.swift */; }; 7C2AC42928F2B384005F369A /* DepositNotSupportedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2AC42828F2B384005F369A /* DepositNotSupportedViewController.swift */; }; 7C2ACDAE27D73F7C00E9DDB3 /* LeftAlignedCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2ACDAD27D73F7C00E9DDB3 /* LeftAlignedCollectionViewFlowLayout.swift */; }; + 7C2DE55928DD94D200C00818 /* LiveTextImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2DE55828DD94D200C00818 /* LiveTextImageView.swift */; }; 7C2DEFF12824FCF500758208 /* ic_time_animation_dark@3x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 7C2DEFF02824FCF500758208 /* ic_time_animation_dark@3x.gif */; }; 7C2DEFF32824FF0600758208 /* ic_time_animation@3x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 7C2DEFF22824FF0600758208 /* ic_time_animation@3x.gif */; }; 7C359DCE26A6C15A001D3AE4 /* StickerStorePreviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C359DCD26A6C15A001D3AE4 /* StickerStorePreviewCell.swift */; }; @@ -1567,6 +1568,7 @@ 7C2475C627795BC100112A30 /* DeleteAccountTableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteAccountTableHeaderView.swift; sourceTree = ""; }; 7C2AC42828F2B384005F369A /* DepositNotSupportedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DepositNotSupportedViewController.swift; sourceTree = ""; }; 7C2ACDAD27D73F7C00E9DDB3 /* LeftAlignedCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftAlignedCollectionViewFlowLayout.swift; sourceTree = ""; }; + 7C2DE55828DD94D200C00818 /* LiveTextImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveTextImageView.swift; sourceTree = ""; }; 7C2DEFF02824FCF500758208 /* ic_time_animation_dark@3x.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ic_time_animation_dark@3x.gif"; sourceTree = ""; }; 7C2DEFF22824FF0600758208 /* ic_time_animation@3x.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ic_time_animation@3x.gif"; sourceTree = ""; }; 7C359DCD26A6C15A001D3AE4 /* StickerStorePreviewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerStorePreviewCell.swift; sourceTree = ""; }; @@ -3384,6 +3386,7 @@ 7CB0954E26CCED2E0049F4C7 /* PinMessageBannerView.swift */, 7C14CFC026CA35CF0094AF4A /* StaticMessagesView.xib */, 7C359DCF26A6C173001D3AE4 /* StickerStoreBannerView.swift */, + 7C2DE55828DD94D200C00818 /* LiveTextImageView.swift */, ); path = Views; sourceTree = ""; @@ -4495,6 +4498,7 @@ 7BBC6EA81FA98D1A00DC130A /* AddPeopleViewController.swift in Sources */, 7CB0955926CE69250049F4C7 /* PinMessageViewModel.swift in Sources */, DFD93F1E2111C0030013401A /* UIDeviceExtension.swift in Sources */, + 7C2DE55928DD94D200C00818 /* LiveTextImageView.swift in Sources */, 7B35AF78228AA3BD00E8101D /* MessagesWithUserSearchResult.swift in Sources */, 7B61B9CA2538E1C8001F94A3 /* ScreenHeightCompatibleLayoutConstraint.swift in Sources */, 7B2A115F22C1ECB100AD029C /* RoundedBlurButton.swift in Sources */, diff --git a/Mixin/UserInterface/Controllers/Chat/GalleryImageItemViewController.swift b/Mixin/UserInterface/Controllers/Chat/GalleryImageItemViewController.swift index 78b0951232..7a6b46d25b 100644 --- a/Mixin/UserInterface/Controllers/Chat/GalleryImageItemViewController.swift +++ b/Mixin/UserInterface/Controllers/Chat/GalleryImageItemViewController.swift @@ -6,7 +6,13 @@ import MixinServices final class GalleryImageItemViewController: GalleryItemViewController { let scrollView = UIScrollView() - let imageView = SDAnimatedImageView() + let imageView: SDAnimatedImageView = { + if #available(iOS 16.0, *), LiveTextImageView.isImageAnalyzerSupported { + return LiveTextImageView(frame: .zero) + } else { + return SDAnimatedImageView() + } + }() private(set) var detectedUrl: URL? @@ -151,6 +157,7 @@ final class GalleryImageItemViewController: GalleryItemViewController { } self.detectQRCode(for: item, image: image) self.keepDisplayWakingUpIfNeeded(image: image) + self.imageView.startImageLiveTextAnalysisIfNeeded() } } diff --git a/Mixin/UserInterface/Controllers/Chat/Views/LiveTextImageView.swift b/Mixin/UserInterface/Controllers/Chat/Views/LiveTextImageView.swift new file mode 100644 index 0000000000..add38f5ecc --- /dev/null +++ b/Mixin/UserInterface/Controllers/Chat/Views/LiveTextImageView.swift @@ -0,0 +1,56 @@ +import VisionKit +import MixinServices +import SDWebImage + +@available(iOS 16.0, *) +class LiveTextImageView: SDAnimatedImageView { + + static var isImageAnalyzerSupported: Bool { + ImageAnalyzer.isSupported + } + + private let analyzer = ImageAnalyzer() + private let interaction = ImageAnalysisInteraction() + + override init(frame: CGRect) { + super.init(frame: frame) + addInteraction(interaction) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func startAnalysis() { + interaction.analysis = nil + interaction.preferredInteractionTypes = [] + guard let image = image else { + return + } + Task { + let configuration = ImageAnalyzer.Configuration([.text]) + do { + let analysis = try await analyzer.analyze(image, configuration: configuration) + if image == self.image { + interaction.analysis = analysis + interaction.preferredInteractionTypes = .automatic + } + } catch { + Logger.general.error(category: "LiveTextImageView", message: "Error in live text analysis: \(error.localizedDescription)") + } + } + } + +} + +//MARK: - UIImageView Live Text +extension UIImageView { + + func startImageLiveTextAnalysisIfNeeded() { + guard #available(iOS 16, *), let liveTextImageView = self as? LiveTextImageView else { + return + } + liveTextImageView.startAnalysis() + } + +}