2009-06-25 28 views
3

我是新来的iPhone应用程序开发,所以很可能我做错了什么。多个图像操作崩溃iPhone应用程序

基本上,我从网上加载了一堆图像,然后裁剪它们。我设法找到加载图像异步的例子,并将它们添加到视图中。我设法通过NSData添加一个图像,通过添加到NSOperationQueue中的NSOperation来实现。

然后,因为我不得不做出固定大小的拇指,我需要一种方法来裁剪这张图片,所以我发现它基本上采用UIGraphicsBeginImageContext()UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()绘制裁剪后的图像,与不重要沿净脚本大小计算。

问题是,该方法的工作原理是,但由于它生成的像是这个图像的20个,它在生成它们中的一些之后会随机崩溃,或者有时会在我关闭并重新打开一次或多次应用程序之后再次崩溃。

在这种情况下应该怎么做?我试图让这个方法也以某种方式异步运行,与NSOperationsNSOperationQueue,但没有运气。

如果作物的代码比我想象的更重要,那就是:

UIGraphicsBeginImageContext(CGSizeMake(50, 50)); 
CGRect thumbnailRect = CGRectZero; 
thumbnailRect.origin = CGPointMake(0.0,0.0); //this is actually generated 
              // based on the sourceImage size 
thumbnailRect.size.width = 50; 
thumbnailRect.size.height = 50; 
[sourceImage drawInRect:thumbnailRect]; 
newImage = UIGraphicsGetImageFromCurrentImageContext(); 

谢谢!

+0

调试器在发生崩溃时会说什么?另外,这是在设备上还是在模拟器上运行? – zpesk 2009-06-25 13:47:59

+0

如果你只是同步工作而不是NSOperationQueue,它会不会崩溃?神秘崩溃的常见原因是你释放了一些你不应该释放的东西,尤其是当你崩溃时的堆栈跟踪中有“autorelease”或“pool”字样... – 2009-06-25 16:59:16

回答

5

缩放图像的代码看起来太简单了。 这是我正在使用的一个。正如你所看到的,没有泄漏,当不再需要时释放对象。希望这可以帮助。

// 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; 
} 
+0

嗨,已经有一段时间了但我仍然有这个问题,所以现在我决定检查你的答案。我试图使用你的代码,但我有我的图像作为UIImage,你的功能需要CGImageRef。另外,这个脚本只能缩放图像,对吧?我也需要裁剪它。 – treznik 2009-07-16 14:25:25

0

这确实听起来像是内存不足的崩溃。启动Leaks工具并查看整体内存趋势。

2

您的应用程序崩溃是因为您使用的调用(例如,UIGraphicsBeginImageContext)操纵UIKit的上下文堆栈,您只能从主线程安全地执行上下文堆栈。

unforgiven的解决方案在线程中使用时不会崩溃,因为它不处理上下文堆栈。