From 4e35d6e5bf51863888324316d9f7e80f1f227057 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 16 Nov 2020 22:45:24 +0400 Subject: [PATCH] Tune outgoing photo resizing & compression --- .../FetchPhotoLibraryImageResource.swift | 96 +++++++++++++++++-- .../MozjpegBinding/Sources/MozjpegBinding.m | 2 +- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/submodules/LocalMediaResources/Sources/FetchPhotoLibraryImageResource.swift b/submodules/LocalMediaResources/Sources/FetchPhotoLibraryImageResource.swift index bf04a0038e..2e7a8b2e89 100644 --- a/submodules/LocalMediaResources/Sources/FetchPhotoLibraryImageResource.swift +++ b/submodules/LocalMediaResources/Sources/FetchPhotoLibraryImageResource.swift @@ -4,12 +4,84 @@ import Photos import Postbox import SwiftSignalKit import ImageCompression +import Accelerate.vImage private final class RequestId { var id: PHImageRequestID? var invalidated: Bool = false } +private func resizedImage(_ image: UIImage, for size: CGSize) -> UIImage? { + guard let cgImage = image.cgImage else { + return nil + } + + var format = vImage_CGImageFormat(bitsPerComponent: 8, + bitsPerPixel: 32, + colorSpace: nil, + bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue), + version: 0, + decode: nil, + renderingIntent: .defaultIntent) + + var error: vImage_Error + var sourceBuffer = vImage_Buffer() + defer { sourceBuffer.data.deallocate() } + error = vImageBuffer_InitWithCGImage(&sourceBuffer, + &format, + nil, + cgImage, + vImage_Flags(kvImageNoFlags)) + guard error == kvImageNoError else { return nil } + + var destinationBuffer = vImage_Buffer() + error = vImageBuffer_Init(&destinationBuffer, + vImagePixelCount(size.height), + vImagePixelCount(size.width), + format.bitsPerPixel, + vImage_Flags(kvImageNoFlags)) + guard error == kvImageNoError else { + return nil + } + + error = vImageScale_ARGB8888(&sourceBuffer, + &destinationBuffer, + nil, + vImage_Flags(kvImageHighQualityResampling)) + guard error == kvImageNoError else { + return nil + } + + guard let resizedImage = + vImageCreateCGImageFromBuffer(&destinationBuffer, + &format, + nil, + nil, + vImage_Flags(kvImageNoAllocate), + &error)?.takeRetainedValue(), + error == kvImageNoError + else { + return nil + } + + return UIImage(cgImage: resizedImage) +} + +extension UIImage.Orientation { + init(_ cgOrientation: CGImagePropertyOrientation) { + switch cgOrientation { + case .up: self = .up + case .upMirrored: self = .upMirrored + case .down: self = .down + case .downMirrored: self = .downMirrored + case .left: self = .left + case .leftMirrored: self = .leftMirrored + case .right: self = .right + case .rightMirrored: self = .rightMirrored + } + } +} + public func fetchPhotoLibraryResource(localIdentifier: String) -> Signal { return Signal { subscriber in let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil) @@ -28,7 +100,9 @@ public func fetchPhotoLibraryResource(localIdentifier: String) -> Signal Void in + let startTime = CACurrentMediaTime() + + let requestIdValue = PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: option, resultHandler: { (image, info) -> Void in Queue.concurrentDefaultQueue().async { requestId.with { current -> Void in if !current.invalidated { @@ -42,17 +116,24 @@ public func fetchPhotoLibraryResource(localIdentifier: String) -> Signal } } } + diff --git a/submodules/MozjpegBinding/Sources/MozjpegBinding.m b/submodules/MozjpegBinding/Sources/MozjpegBinding.m index e3952205cc..fa2dd964e2 100644 --- a/submodules/MozjpegBinding/Sources/MozjpegBinding.m +++ b/submodules/MozjpegBinding/Sources/MozjpegBinding.m @@ -125,7 +125,7 @@ NSData * _Nullable compressJPEGData(UIImage * _Nonnull sourceImage) { cinfo.arith_code = FALSE; cinfo.dct_method = JDCT_ISLOW; cinfo.optimize_coding = TRUE; - jpeg_set_quality(&cinfo, 78, 1); + jpeg_set_quality(&cinfo, 72, 1); jpeg_simple_progression(&cinfo); jpeg_start_compress(&cinfo, 1);