前のやつ
前に投稿した、UICollectionViewで画像一覧を出した時のメモの続きです。
前回は、Photosを使い写真appから取得してCollectionViewで並べました。
今回はそのサムネイルをタップした時に画像を画面いっぱいに表示しようとしたのにクソ画質しか出てこなくて悩んだ時のメモです。
PHAsset -> UIImage
PHAsset
からUIImage
を出力することは、サムネを出すところでも使用していました。
以下UICollectionView
のCellにサムネ画像を出力する部分のコードです。(一部省略)
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してます)
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)
}
}
}
結果画像。(ドラクエウォークにハマったものの末路)
ク、クソ画質だっ…!
なんということでしょう、僕が頑張って書いたスライム君がぼけぼけになってしましました。
PHImageManagerMaximumSize
でオリジナルサイズになるように指定したのになんでだ…。
解決
どうやらPHImageRequestは自動で速度と画質の兼ね合いをごにょごにょしていい感じに帳尻をとっているようです。
その設定を手動で行えるのがPHImageRequestOptionsDeliveryMode
のようで、highQualityFormat
に指定することで解決しました。
case highQualityFormat
Photos provides only the highest-quality image available, regardless of how much time it takes to load.
(写真は、読み込みにかかる時間に関係なく、利用可能な最高品質の画像のみを提供します。)
以下のように設定します。
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)
}
}
}
結果画像。
やったぜ。