有谁知道如何从PHImageManager获取方形拇指?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; }];
Josh Heald.. 20
更新:
看起来错误仍然存在并且包括iOS 8.4,我可以重现他们使用标准的iPhone 6s后置摄像头图像,采用全尺寸方形裁剪.它们在iOS 9.0中得到了适当的修复,即使是6300万像素全景的大型作物也能正常工作.PHImageManager
在iOS 8.3中修复了从中检索图像时出错的错误,因此对于那个版本的iOS及更高版本,我的原始示例有效,如下所示:
Apple定义的方法是CGRect
在图像的坐标空间中传递a ,其中原点为(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)以外的其他值,因为您通常希望裁剪方块沿着正在裁剪的图像轴居中,但我会将其作为练习留给读者.:-)
原答案:
约翰的回答让我大部分都在那里,但是使用他的代码我得到了拉伸和压扁的图像.这是我如何imageView
显示从PHImageManager获取的方形缩略图.
首先,确保将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,并通过以下两行设置clipsToBounds = YES:
imageView.contentMode=UIViewContentModeScaleAspectFill; imageView.clipsToBounds=YES;
编辑以添加normalizedCropRect用法示例
警告 - 这不起作用,但应根据Apple的文档.
Apple定义的方法是CGRect
在图像的坐标空间中传递a ,其中原点为(0,0),最大值为(1,1).你在传递这个RECT PHImageRequestOptions
对象,有一起resizeMode
的PHImageRequestOptionsResizeModeExact
,然后你应该得到一个裁剪后的图像.问题是你没有,它以原始宽高比和完整图像的形式返回.
我已经验证了裁剪矩形是在图像的坐标空间中正确创建的,并且遵循了要使用的指令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提出雷达要求他们修复它!
更新:
看起来错误仍然存在并且包括iOS 8.4,我可以重现他们使用标准的iPhone 6s后置摄像头图像,采用全尺寸方形裁剪.它们在iOS 9.0中得到了适当的修复,即使是6300万像素全景的大型作物也能正常工作.PHImageManager
在iOS 8.3中修复了从中检索图像时出错的错误,因此对于那个版本的iOS及更高版本,我的原始示例有效,如下所示:
Apple定义的方法是CGRect
在图像的坐标空间中传递a ,其中原点为(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)以外的其他值,因为您通常希望裁剪方块沿着正在裁剪的图像轴居中,但我会将其作为练习留给读者.:-)
原答案:
约翰的回答让我大部分都在那里,但是使用他的代码我得到了拉伸和压扁的图像.这是我如何imageView
显示从PHImageManager获取的方形缩略图.
首先,确保将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,并通过以下两行设置clipsToBounds = YES:
imageView.contentMode=UIViewContentModeScaleAspectFill; imageView.clipsToBounds=YES;
编辑以添加normalizedCropRect用法示例
警告 - 这不起作用,但应根据Apple的文档.
Apple定义的方法是CGRect
在图像的坐标空间中传递a ,其中原点为(0,0),最大值为(1,1).你在传递这个RECT PHImageRequestOptions
对象,有一起resizeMode
的PHImageRequestOptionsResizeModeExact
,然后你应该得到一个裁剪后的图像.问题是你没有,它以原始宽高比和完整图像的形式返回.
我已经验证了裁剪矩形是在图像的坐标空间中正确创建的,并且遵循了要使用的指令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]; }];