我正在使用Photos framework在我正在处理的iOS应用中显示用户图片。
作为参考,我上传了一些图片到imgur,在那里你可以找到我正在测试的原始图像,以及我拍摄的带有粉红色背景的UIImageView的屏幕截图,显示带有“Aspect Fit”配置的获取图像。这是链接:http://imgur.com/a/VPJ9J
我正在使用两种测试场景:首先是一张风景图片,其imageOrientation
是UIImageOrientation.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)
但收到{{1} }})。
现在,似乎我唯一的选择是检查正在运行的iOS版本,然后在请求具有旋转方向的图像时反转参数(我仅使用(1334.0, 1000.0)
进行测试,但也有{{1} }},UIImageOrientation.Right
和.Left
)。
不幸的是,.LeftMirrored
不包含图片的方向。我只能在向.RightMirrored
请求图像后知道它,所以我必须对这些图像发出两个请求,一个用于获取方向,另一个用于获取正确的图像。
这是我的逻辑问题吗?或者这是iOS中的错误?如果它是一个错误,哪一个是正确的行为,iOS 8.3的一个或旧版本?任何人都可以提供其他选项来处理这个问题吗?
对不起,很长的帖子,以及糟糕的英语。提前谢谢!
答案 0 :(得分:1)
我做了一个奇怪的解决方法:
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)
}
}
}
}
此解决方案的性能非常值得怀疑,但它是处理此问题的最可靠方法之一。