我有一个我正在制作的博客应用程序。要撰写新条目,可以使用“撰写条目”视图,用户可以在其中选择照片和输入文本。对于照片,有一个UIImageView占位符,点击此按钮后,会出现一个自定义ImagePicker,用户最多可以选择3张照片。
这就是问题所在。我不需要来自ALAsset的全分辨率照片,但同时缩略图的分辨率太低,我无法使用。
所以我现在正在做的是将fullResolution照片调整到更小的尺寸。但是,这需要一些时间,特别是在将最多3张照片调整为较小尺寸时。
这是一段代码剪切,以显示我正在做的事情:
ALAssetRepresentation *rep = [[dict objectForKey:@"assetObject"] defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref)
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIImage *previewImage;
UIImage *largeImage;
if([rep orientation] == ALAssetOrientationUp) //landscape image
{
largeImage = [[UIImage imageWithCGImage:iref] scaledToWidth:screenBounds.size.width];
previewImage = [[UIImage imageWithCGImage:iref] scaledToWidth:300];
}
else // portrait image
{
previewImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:300] imageRotatedByDegrees:90];
largeImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:screenBounds.size.height] imageRotatedByDegrees:90];
}
}
在这里,从全分辨率图像,我创建了两个图像:预览图像(长端最大300px)和大图像(长端最大960px或640px)。预览图像是应用程序本身在“新条目”预览中显示的内容。大图像是上传到服务器时使用的图像。
我用来调整大小的实际代码,我从这里抓住了一些地方:
-(UIImage*)scaledToWidth:(float)i_width
{
float oldWidth = self.size.width;
float scaleFactor = i_width / oldWidth;
float newHeight = self.size.height * scaleFactor;
float newWidth = oldWidth * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
[self drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
我在这里做错了吗?就目前而言,ALAsset缩略图的清晰度太低,同时,我不需要整个全分辨率。它现在都在工作,但调整大小需要一些时间。这只是一个必然结果吗?
谢谢!
答案 0 :(得分:3)
调整图像大小的必要结果是需要花费一些时间。多少取决于设备,资产的分辨率和资产的格式。但是你没有任何控制权。但是你可以控制调整大小的位置。我怀疑你现在正在调整主线程中的图像大小,这会导致UI在你调整大小时停止运行。做足够的图像,你的应用程序将显示为挂起足够长的时间,以便用户只是去做其他事情(也许可以查看App Store中的竞争应用程序)。
你应该做的是从主线程执行调整大小。使用iOS 4及更高版本,这变得更加简单,因为您可以使用Grand Central Dispatch进行大小调整。您可以从上面获取原始代码块并将其包装在以下块中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
ALAssetRepresentation *rep = [[dict objectForKey:@"assetObject"] defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref)
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
__block UIImage *previewImage;
__block UIImage *largeImage;
if([rep orientation] == ALAssetOrientationUp) //landscape image
{
largeImage = [[UIImage imageWithCGImage:iref] scaledToWidth:screenBounds.size.width];
previewImage = [[UIImage imageWithCGImage:iref] scaledToWidth:300];
}
else // portrait image
{
previewImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:300] imageRotatedByDegrees:90];
largeImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:screenBounds.size.height] imageRotatedByDegrees:90];
}
dispatch_async(dispatch_get_main_queue(), ^{
// do what ever you need to do in the main thread here once your image is resized.
// this is going to be things like setting the UIImageViews to show your new images
// or adding new views to your view hierarchy
});
}
});
你必须以这种方式稍微改变一些事情。例如,您现在已经将过去的一步分解为多个步骤。之后运行的代码将在图像调整大小完成之前或实际对图像执行任何操作之前结束运行,因此您需要确保您对这些图像没有任何依赖性,否则您可能会崩溃。
答案 1 :(得分:2)
答案较晚,但对于那些对此问题抱怨的人,您可能需要考虑使用fullScreenImage
而不是fullResolutionImage
的{{1}}。它通常要小得多,但仍然足够大,可以保持较大缩略图的质量。