6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHAssetから元画像を出力したかったのにクソ画質になった時のメモ

Posted at

前のやつ

前に投稿した、UICollectionViewで画像一覧を出した時のメモの続きです。

前回は、Photosを使い写真appから取得してCollectionViewで並べました。

今回はそのサムネイルをタップした時に画像を画面いっぱいに表示しようとしたのにクソ画質しか出てこなくて悩んだ時のメモです。

PHAsset -> UIImage

PHAssetからUIImageを出力することは、サムネを出すところでも使用していました。

以下UICollectionViewのCellにサムネ画像を出力する部分のコードです。(一部省略)

ThumbnailListViewCointroller.swift
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = thumbnailCollectionView.dequeueReusableCell(withReuseIdentifier: "ThumbnailCell", for: indexPath) as? ThumbnailCell else {
        return UICollectionViewCell()
    }
    // cellを使い回す前に前の画像を削除
    cell.thumbnailImageView.image = nil
    let item = photoAssets[indexPath.row]
    // サムネにはこのオプションがいいらしい
    let options = PHImageRequestOptions()
    options.deliveryMode = .opportunistic
    options.resizeMode = .fast
    let targetSize: CGSize = CGSize(width: 200, height: 200)
    cell.requestId = imageManager.requestImage(for: item,
                              targetSize: targetSize,
                              contentMode: .aspectFit,
                              options: options) { (image, info) in
                                cell.thumbnailImageView.image = image
    }
    return cell
}

PHAssetから元画像と同じサイズの画像を…

ここまではうまくできました。

では次に画面いっぱいにUIImageViewを貼り付けたUIViewControllerを作成して、Cellをタップした時に表示するようにしてみます。

(せっかくなのでImageEditorViewControllerを使い、StoryboardでイニシャライザでDIしてます)

ThumbnailListViewCointroller.swift
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let asset = photoAssets[indexPath.row]
    imageManager.requestImage(for: asset,
                              targetSize: PHImageManagerMaximumSize,
                              contentMode: .aspectFit,
                              options: nil) { (image, info) in
                                guard let selectedImage = image else { return }
                                let storyboard = UIStoryboard(name: "ImageEditor", bundle: nil)
                                let viewController = storyboard.instantiateInitialViewController { (coder) in
                                    ImageEditorViewController(coder: coder, image: selectedImage)
                                }
                                if let imageEditorViewController = viewController {
                                    self.present(imageEditorViewController, animated: true, completion: nil)
                                }
    }
}

結果画像。(ドラクエウォークにハマったものの末路)

Screen Shot 2019-09-21 at 20.53.01.png

ク、クソ画質だっ…!

なんということでしょう、僕が頑張って書いたスライム君がぼけぼけになってしましました。

PHImageManagerMaximumSizeでオリジナルサイズになるように指定したのになんでだ…。

解決

どうやらPHImageRequestは自動で速度と画質の兼ね合いをごにょごにょしていい感じに帳尻をとっているようです。

その設定を手動で行えるのがPHImageRequestOptionsDeliveryModeのようで、highQualityFormatに指定することで解決しました。

case highQualityFormat
Photos provides only the highest-quality image available, regardless of how much time it takes to load.
(写真は、読み込みにかかる時間に関係なく、利用可能な最高品質の画像のみを提供します。)

以下のように設定します。

ThumbnailListViewCointroller.swift
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let asset = photoAssets[indexPath.row]
    // オリジナル画像を取得するためのオプション
    let options = PHImageRequestOptions()
    options.deliveryMode = .highQualityFormat
    imageManager.requestImage(for: asset,
                              targetSize: PHImageManagerMaximumSize,
                              contentMode: .aspectFit,
                              options: options) { (image, info) in
                                guard let selectedImage = image else { return }
                                let storyboard = UIStoryboard(name: "ImageEditor", bundle: nil)
                                let viewController = storyboard.instantiateInitialViewController { (coder) in
                                    ImageEditorViewController(coder: coder, image: selectedImage)
                                }
                                if let imageEditorViewController = viewController {
                                    self.present(imageEditorViewController, animated: true, completion: nil)
                                }
    }
}

結果画像。

Screen Shot 2019-09-21 at 20.53.30.png

やったぜ。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?