PHImageManagerから2乗された親指をフェッチする方法を誰かが考えていますか? PHImageContentModeAspectFillオプションは無効です。
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)_asset
targetSize:CGSizeMake(80, 80)
contentMode:PHImageContentModeAspectFill
options:nil
resultHandler:^(UIImage *result, NSDictionary *info) {
// sadly result is not a squared image
imageView.image = result;
}];
更新:
バグはまだiOS 8.4までであり、標準のiPhone 6sバックカメラ画像でフルサイズの正方形の切り抜きを使って再現できます。これらはiOS 9.0で適切に修正されており、63メガピクセルのパノラマの大きなクロップでも問題なく機能します。PHImageManager
から取得した画像のトリミングのバグはiOS 8.3で修正されたため、そのバージョンのiOS以降では、私の元の例は次のように動作します。
Apple定義のアプローチは、画像の座標空間でCGRect
を渡すことです。ここで、原点は(0,0)で、最大は(1,1 )このrectをPHImageRequestOptions
オブジェクトでresizeMode
のPHImageRequestOptionsResizeModeExact
とともに渡すと、トリミングされた画像が返されます。
- (void)showSquareImageForAsset:(PHAsset *)asset
{
NSInteger retinaScale = [UIScreen mainScreen].scale;
CGSize retinaSquare = CGSizeMake(100*retinaScale, 100*retinaScale);
PHImageRequestOptions *cropToSquare = [[PHImageRequestOptions alloc] init];
cropToSquare.resizeMode = PHImageRequestOptionsResizeModeExact;
CGFloat cropSideLength = MIN(asset.pixelWidth, asset.pixelHeight);
CGRect square = CGRectMake(0, 0, cropSideLength, cropSideLength);
CGRect cropRect = CGRectApplyAffineTransform(square,
CGAffineTransformMakeScale(1.0 / asset.pixelWidth,
1.0 / asset.pixelHeight));
cropToSquare.normalizedCropRect = cropRect;
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)asset
targetSize:retinaSquare
contentMode:PHImageContentModeAspectFit
options:cropToSquare
resultHandler:^(UIImage *result, NSDictionary *info) {
self.imageView.image = result;
}];
}
この例では、辺の長さのcropRect
をアセットの幅と高さの小さい方に等しくしてから、CGRectApplyAffineTransform
を使用して画像の座標空間に変換します。 square
の原点を(0,0)以外に設定すると、トリミングされる画像の軸に沿って中央にトリミングされた正方形が必要になることがよくありますが、それはそのままにしておきます読者のための演習。 :-)
元の回答:
ジョンの答えは、ほとんどの方法で私に届きましたが、彼のコードを使用して、画像を引き伸ばし、押しつぶしていました。これが、PHImageManagerから取得した正方形のサムネイルを表示するimageView
を取得する方法です。
まず、contentMode
のUIImageView
プロパティがScaleAspectFill
に設定されていることを確認します。デフォルトはScaleToFill
です。これはPHImageManager
からの正方形のサムネイルを表示するために正しく機能しないため、コードでUIImageView
をインスタンス化したかどうかにかかわらず、これを必ず変更してくださいストーリーボードで。
//view dimensions are based on points, but we're requesting pixels from PHImageManager
NSInteger retinaMultiplier = [UIScreen mainScreen].scale;
CGSize retinaSquare = CGSizeMake(imageView.bounds.size.width * retinaMultiplier, imageView.bounds.size.height * retinaMultiplier);
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)_asset
targetSize:retinaSquare
contentMode:PHImageContentModeAspectFill
options:nil
resultHandler:^(UIImage *result, NSDictionary *info) {
// The result is not square, but correctly displays as a square using AspectFill
imageView.image = result;
}];
PHImageRequestOptionsResizeModeExact
を指定しない限り、resizeMode
にnormalizedCropRect
を指定する必要はありません。 、それを使用すると、キャッシュされた画像がすぐに返されるという利点が得られません。
UIImage
で返されるresult
は、ソースと同じアスペクト比になりますが、正方形として表示するようにアスペクトフィルに設定されているUIImageView
で使用するために正しくスケーリングされます。表示しているだけなら、これが方法です。アプリの外で印刷またはエクスポートするために画像をトリミングする必要がある場合、これは望ましくありません。そのためのnormalizedCropRect
の使用を検討してください。 (編集-何が機能するかの例については、以下を参照してください...)
これを除いて、UIImageViewのコンテンツモードをUIViewContentModeScaleAspectFillに設定し、次の2行でclipsToBounds = YESを設定していることも確認してください。
imageView.contentMode=UIViewContentModeScaleAspectFill;
imageView.clipsToBounds=YES;
normalizedCropRectの使用例を追加するための編集
警告-これは機能しませんが、 Appleのドキュメントに従っているはずです。
Apple定義のアプローチは、画像の座標空間でCGRect
を渡すことです。ここで、原点は(0,0)で、最大は(1,1このrectをPHImageRequestOptions
オブジェクトでresizeMode
のPHImageRequestOptionsResizeModeExact
とともに渡すと、トリミングされた画像が返されます。問題は、 t、元のアスペクト比とフル画像として戻ってきます。
トリミング四角形が画像の座標空間に正しく作成されていることを確認し、PHImageRequestOptionsResizeModeExact
を使用するための指示に従いましたが、結果ハンドラーには元のアスペクト比で画像が渡されます。これはフレームワークのバグのようです。修正すると、次のコードが機能するはずです。
- (void)showSquareImageForAsset:(PHAsset *)asset
{
NSInteger retinaScale = [UIScreen mainScreen].scale;
CGSize retinaSquare = CGSizeMake(100*retinaScale, 100*retinaScale);
PHImageRequestOptions *cropToSquare = [[PHImageRequestOptions alloc] init];
cropToSquare.resizeMode = PHImageRequestOptionsResizeModeExact;
CGFloat cropSideLength = MIN(asset.pixelWidth, asset.pixelHeight);
CGRect square = CGRectMake(0, 0, cropSideLength, cropSideLength);
CGRect cropRect = CGRectApplyAffineTransform(square,
CGAffineTransformMakeScale(1.0 / asset.pixelWidth,
1.0 / asset.pixelHeight));
cropToSquare.normalizedCropRect = cropRect;
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)asset
targetSize:retinaSquare
contentMode:PHImageContentModeAspectFit
options:cropToSquare
resultHandler:^(UIImage *result, NSDictionary *info) {
self.imageView.image = result;
}];
}
私が提案できることは、あなたがこの問題を抱えているなら、あなたは レーダーを提出する Appleを使って彼らにそれを修正するよう要求することです!
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeExact;
NSInteger retinaMultiplier = [UIScreen mainScreen].scale;
CGSize retinaSquare = CGSizeMake(imageView.bounds.size.width * retinaMultiplier, imageView.bounds.size.height * retinaMultiplier);
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)_asset
targetSize:retinaSquare
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:^(UIImage *result, NSDictionary *info) {
imageView.image =[UIImage imageWithCGImage:result.CGImage scale:retinaMultiplier orientation:result.imageOrientation];
}];
正確な正方形を取得するには、次のようにオプションを渡して、正確なサイズが必要であることを示す必要があります。
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// No, really, we want this exact size
options.resizeMode = PHImageRequestOptionsResizeModeExact
[[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)_asset
targetSize:CGSizeMake(160, 160)
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:^(UIImage *result, NSDictionary *info) {
// Happily, result is now a squared image
imageView.image = result;
}];
これは私にとってはうまくいきます:
__block UIImage* imgThumb;
CGSize size=CGSizeMake(45, 45);// Size for Square image
[self.imageManager requestImageForAsset:<your_current_phAsset>
targetSize:size
contentMode:PHImageContentModeAspectFill
options:nil
resultHandler:^(UIImage *result, NSDictionary *info) {
imgThumb = result;
}];