向PHImageManager请求图像会导致iOS 8.3中出现错误图像



上下文

我正在使用照片框架在我正在开发的iOS应用程序中显示用户图片。

作为参考,我上传了一些图像到imgur,在那里你可以找到我正在测试的原始图像,以及我拍摄的粉色背景UIImageView的屏幕截图,显示了"Aspect Fit"配置的提取图像。链接如下:https://i.stack.imgur.com/beugu.jpg

我使用两个测试场景:第一,一个横向图像,其imageOrientationUIImageOrientation.Up(0(;第二,肖像图像,用UIImageOrientation.Right(3(。你可以查看文档(我会把链接放在这里,但我没有足够的声誉,对不起(。

问题

正如预期的那样,iPhone 4S(iOS 8.1.2(在粉色UIImageView中以横向布局显示横向图像,并以纵向布局显示纵向图像。但iPhone 5和6 Plus(均为iOS 8.3(都以横向布局显示这两幅图像。

代码

这是我用来请求图像的代码:

var targetSize = CGSizeMake(1000, (CGFloat(asset.pixelHeight) / CGFloat(asset.pixelWidth)) * 1000)
var options = PHImageRequestOptions()
options.version = PHImageRequestOptionsVersion.Current
options.deliveryMode =  PHImageRequestOptionsDeliveryMode.HighQualityFormat
options.resizeMode = PHImageRequestOptionsResizeMode.Exact
options.networkAccessAllowed = true
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: PHImageContentMode.AspectFill, options: options) { (result: UIImage!, info) -> Void in
    if !info[PHImageResultIsDegradedKey]!.boolValue {
        println("asset.pixelWidth: (asset.pixelWidth)")
        println("asset.pixelHeight: (asset.pixelHeight)")
        println("targetSize: (targetSize)")
        println("result.size: (result.size)")
        println("result.imageOrientation: (result.imageOrientation.rawValue)")
        completion(result)
    }
}

测试

以下是我使用这两个图像执行测试时得到的日志:

案例1:iPhone 4S(8.1.2(

横向:

asset.pixelWidth: 3264
asset.pixelHeight: 2448
targetSize: (1000.0, 750.0)
result.size: (1000.0, 750.0)
result.imageOrientation: 0

纵向:

asset.pixelWidth: 2448
asset.pixelHeight: 3264
targetSize: (1000.0, 1333.33)
result.size: (1000.0, 1332.0)
result.imageOrientation: 3

案例2:iPhone 5(8.3(

横向:

asset.pixelWidth: 3264
asset.pixelHeight: 2448
targetSize: (1000.0, 750.0)
result.size: (1000.0, 750.0)
result.imageOrientation: 0

纵向:

asset.pixelWidth: 2448
asset.pixelHeight: 3264
targetSize: (1000.0, 1333.33)
result.size: (1334.0, 1000.0)
result.imageOrientation: 3

案例3:iPhone 6 Plus(8.3(

横向:

asset.pixelWidth: 3264
asset.pixelHeight: 2448
targetSize: (1000.0, 750.0)
result.size: (1000.0, 750.0)
result.imageOrientation: 0

纵向:

asset.pixelWidth: 2448
asset.pixelHeight: 3264
targetSize: (1000.0, 1333.33333333333)
result.size: (1334.0, 1000.0)
result.imageOrientation: 3

结论

您可以从日志中看到,iOS 8.1.2版本尊重为两个图像指定的targetSize,但8.3版本正在获取维度相反的图像(请求(1000.0, 1333.33),但收到(1334.0, 1000.0)(。

现在,我唯一的选择似乎是检查哪个iOS版本正在运行,然后在请求具有旋转方向的图像时反转参数(我只测试了UIImageOrientation.Right,但也有.Left.LeftMirrored.RightMirrored(。

不幸的是,PHAsset不包含图像的方向。我只能在向PHImageManager请求图像后才能知道,所以我必须对这些图像进行两次请求,一次是为了获得方向,另一次是为获得正确的图像。

问题

这是我的逻辑问题吗?或者这是iOS中的一个错误?如果这是一个错误,iOS 8.3的错误和旧版本的错误哪个是正确的行为?有人能为处理这个问题提供其他选择吗?

很抱歉发了这么长的邮件,也很抱歉英语不好。提前感谢!

我做了一个奇怪的变通方法:

func getAssetImage(asset: PHAsset, completion: (UIImage?) -> Void) {
    getAssetImage(asset, firstTry: true, completion: completion)
}
private func getAssetImage(asset: PHAsset, firstTry: Bool, completion: (UIImage?) -> Void) {
    let targetSize = CGSizeMake(1000, (CGFloat(asset.pixelHeight) / CGFloat(asset.pixelWidth)) * 1000)
    let options = PHImageRequestOptions()
    options.version = PHImageRequestOptionsVersion.Current
    options.deliveryMode =  PHImageRequestOptionsDeliveryMode.HighQualityFormat
    options.resizeMode = PHImageRequestOptionsResizeMode.Exact
    options.networkAccessAllowed = true
    PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: PHImageContentMode.AspectFill, options: options) { (result: UIImage?, info) -> Void in
        let degraded = info?[PHImageResultIsDegradedKey] as? NSNumber
        if degraded != nil && !degraded!.boolValue {
            print("asset.pixelWidth: (asset.pixelWidth)")
            print("asset.pixelHeight: (asset.pixelHeight)")
            print("targetSize: (targetSize)")
            print("result.size: (result!.size)")
            print("result.imageOrientation: (result!.imageOrientation.rawValue)")
            if (targetSize.width - targetSize.height) * (result!.size.width - result!.size.height) < 0 {
                if firstTry {
                    print("Resulting image's dimensions are not in accordance with target size. Reversing dimensions!")
                    self.getAssetImage(asset, firstTry: false, completion: completion)
                } else {
                    print("Resulting image's dimensions are still not in accordance with target size. Giving up!")
                    completion(nil)
                }
            } else {
                completion(result)
            }
        }
    }
}

这个解决方案的性能相当可疑,但它是处理这个问题的最可靠的方法之一。

相关内容

  • 没有找到相关文章

最新更新