在显示在UITableViewCells之前调整大小和裁剪图像
我在我的应用程序中有一个UITableView,我必须加载一些固定宽度但高度不同的图像。我使用NSOperationQueue下载图像异步,并调整大小和裁剪我尝试使用Jane Sales在此帖子link text提供的解决方案。在显示在UITableViewCells之前调整大小和裁剪图像
我做了一个自定义的UITableViewCell类,并在其中有一个方法,当排队的操作完成下载图像时调用。该方法被正确调用并显示图像。当我尝试使用Jane提出的方法调整图像大小时,会出现问题。当它到达[sourceImage drawInRect:thumbnailRect];我收到一个exec访问错误,我找不出原因。我所说的方法是这样的:
- (void) setupImage:(UIImage *) anImage{
UIImage *resized = [anImage imageByScalingAndCroppingForSize:CGSizeMake(64, 59)];
if(resized == nil)
resized = [UIImage newImageFromResource:@"thumb2.png"];
[thumbnailView setImage:resized];
}
setupImage是调用的函数时NSOperationQueue完成anImage的下载操作。
有人能给我一个线索,为什么当我尝试调整大小和裁剪图像时,为什么我收到执行不良访问错误?我尝试在表格视图外使用相同的功能。 80%的情况下,但有些情况下,当我收到相同的执行不良访问错误。
谢谢你在前进, 索林
这是我使用的调整和croping的UIImages(代码是从Jane Sales solution)
@implementation UIImage (Extras)
#pragma mark -
#pragma mark Scale and crop image
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO)
{
CGFloat widthFactor = targetWidth/width;
CGFloat heightFactor = targetHeight/height;
if (widthFactor > heightFactor)
scaleFactor = widthFactor; // scale to fit height
else
scaleFactor = heightFactor; // scale to fit width
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor > heightFactor)
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
else
if (widthFactor < heightFactor)
{
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize); // this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if(newImage == nil)
NSLog(@"could not scale image");
//pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
什么我调用上述功能等我以前说过:
- (void) setupImage:(UIImage *) anImage
{
UIImage *resized = [anImage imageByScalingAndCroppingForSize:CGSizeMake(64, 59)];
[thumbnailView setImage:resized];
}
的图像下载异步时被显示在表视图的细胞。 setupImage函数从NSOperation接收图像,并将其下载到异步。问题是,就像我上面所说的,当它到达[sourceImage drawInRect:thumbnailRect];
thumbnailView是一个UIImageView,它是我自定义的TableViewCell的子视图。
希望这可以清楚我在代码中使用的内容。 谢谢你的帮助。 Sorin
尝试下面的代码。 createImage:image:width:height方法需要一个源CGImageRef和将返回的最终UIImage的新宽度和高度。当使用作为源的UIImage的,就可以得到相应的CGImageRef如下:
UIImage *sourceImage;
CGImageRef *sourceRef = [sourceImage CGImage];
// Draw the image into a pixelsWide x pixelsHigh bitmap and use that bitmap to
// create a new UIImage
- (UIImage *) createImage: (CGImageRef) image width: (int) pixelWidth height: (int) pixelHeight
{
// Set the size of the output image
CGRect aRect = CGRectMake(0.0f, 0.0f, pixelWidth, pixelHeight);
// Create a bitmap context to store the new thumbnail
CGContextRef context = MyCreateBitmapContext(pixelWidth, pixelHeight);
// Clear the context and draw the image into the rectangle
CGContextClearRect(context, aRect);
CGContextDrawImage(context, aRect, image);
// Return a UIImage populated with the new resized image
CGImageRef myRef = CGBitmapContextCreateImage (context);
UIImage *img = [UIImage imageWithCGImage:myRef];
free(CGBitmapContextGetData(context));
CGContextRelease(context);
CGImageRelease(myRef);
return img;
}
// MyCreateBitmapContext: Source based on Apple Sample Code
CGContextRef MyCreateBitmapContext (int pixelsWide,
int pixelsHigh)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateDeviceRGB();
bitmapData = malloc(bitmapByteCount);
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease(colorSpace);
return NULL;
}
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
if (context== NULL)
{
free (bitmapData);
CGColorSpaceRelease(colorSpace);
fprintf (stderr, "Context not created!");
return NULL;
}
CGColorSpaceRelease(colorSpace);
return context;
}
我会试试看看它是否有效。谢谢,我会回复一个反馈。 Sorin – 2009-09-02 21:23:15
它适合你吗? – 2009-09-11 09:51:09
好奇的是,当我在模拟器中测试应用程序时,不会引发exec访问错误。当我在iPhone 3G上测试时,它会在尝试调整大小和裁剪时引发错误。 – 2009-09-02 12:29:46
无法真正帮助您调整大小和裁剪代码.. – Daniel 2009-09-02 13:39:39
我建议您将图像保存在应用程序的沙箱中。我认为在UITableViewCell中动态地裁剪图像是相当昂贵的。 – runmad 2009-09-02 15:31:29