fix(mobile): retry with exact resize when fast resize overshoots the texture bound

This commit is contained in:
Santo Shakil
2026-07-23 15:29:47 +06:00
parent e5c3395b3a
commit bec63b40cc
+35 -11
View File
@@ -20,7 +20,7 @@ class LocalImageApiImpl: LocalImageApi {
requestOptions.version = .current
return requestOptions
}()
private static let maxOriginalPixelSize: CGFloat = 16384
private static let maxPixelSize: CGFloat = 16384
private static let registry = RequestRegistry<ImageRequest>()
@@ -109,18 +109,16 @@ class LocalImageApiImpl: LocalImageApi {
]))
}
// PHImageManagerMaximumSize returns a distorted aspect ratio for images too large to render
// (extreme panoramas / long screenshots). Bound the long edge to 16384 (the GPU max texture
// size) with aspectFit so the true ratio is kept and the buffer stays renderable. .fast resize
// is enough, we only need the long edge under the limit.
let isOriginal = !(width > 0 && height > 0)
let targetSize = isOriginal
? CGSize(width: Self.maxPixelSize, height: Self.maxPixelSize)
: CGSize(width: Double(width), height: Double(height))
let contentMode: PHImageContentMode = isOriginal ? .aspectFit : .aspectFill
var image: UIImage?
Self.imageManager.requestImage(
for: asset,
targetSize: isOriginal
? CGSize(width: Self.maxOriginalPixelSize, height: Self.maxOriginalPixelSize)
: CGSize(width: Double(width), height: Double(height)),
contentMode: isOriginal ? .aspectFit : .aspectFill,
targetSize: targetSize,
contentMode: contentMode,
options: Self.requestOptions,
resultHandler: { (_image, info) -> Void in
image = _image
@@ -131,12 +129,38 @@ class LocalImageApiImpl: LocalImageApi {
return request.completion(ImageProcessing.cancelledResult)
}
guard let image = image,
let cgImage = image.cgImage else {
guard let fastImage = image,
var cgImage = fastImage.cgImage else {
Self.registry.remove(requestId: requestId)
return request.completion(.failure(PigeonError(code: "", message: "Could not get pixel data for \(assetId)", details: nil)))
}
// .fast can return larger than the target, so retry with .exact to guarantee the bound.
if max(cgImage.width, cgImage.height) > Int(Self.maxPixelSize) {
let exactOptions = Self.requestOptions.copy() as! PHImageRequestOptions
exactOptions.resizeMode = .exact
image = nil
Self.imageManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: contentMode,
options: exactOptions,
resultHandler: { (_image, info) -> Void in
image = _image
}
)
if request.isCancelled {
return request.completion(ImageProcessing.cancelledResult)
}
guard let exactImage = image?.cgImage else {
Self.registry.remove(requestId: requestId)
return request.completion(.failure(PigeonError(code: "", message: "Could not resize image for \(assetId)", details: nil)))
}
cgImage = exactImage
}
if request.isCancelled {
return request.completion(ImageProcessing.cancelledResult)
}