3

環境

Photos フレームワークを使用して、作業中の iOS アプリケーションでユーザーの写真を表示しています。

参考までに、いくつかの画像を imgur にアップロードしました。ここで、テストしている元の画像と、「アスペクト フィット」構成でフェッチされた画像を表示するピンクの背景を持つ UIImageView のスクリーンショットを見つけることができます。リンクはこちら:http: //imgur.com/a/VPJ9J

私は 2 つのテスト シナリオを使用していimageOrientationますUIImageOrientation.Up。次に、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)
    }
}

テスト

これら 2 つのイメージを使用してテストを実行したときに取得するログは次のとおりです。

ケース 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ので、それらの画像に対して 2 つのリクエストを行う必要があります。1 つは方向を取得するため、もう 1 つは正しい画像を取得するためです。

質問

それは私の論理の問題ですか?それともiOSのバグですか?バグだとしたら、iOS 8.3 の動作と古いバージョンの動作のどちらが正しいですか? この問題を処理するための他のオプションを提供できる人はいますか?

長い投稿で、下手な英語で申し訳ありません。前もって感謝します!

4

1 に答える 1

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)
            }
        }
    }
}

このソリューションのパフォーマンスは非常に疑わしいですが、この問題に対処するための最も信頼できる方法の 1 つでした。

于 2016-04-06T22:35:17.897 に答える