PDA

View Full Version : CGImage crashing simulator




RossOliver
Apr 27, 2008, 08:17 PM
Hey,

I'm having problems with a CGImage. I have overridden a UIView allowing me to initialize it with an 'underlay' image that originally fills the view. I can then set the overlayImage instance variable to a CGImage and it is draw on top of the 'underlay' image using the drawRect method:


ItemView.m

-( id )initWithItemUnderlay:( UIImage * )itemUnderlay frame:( CGRect )frame
{
if( self = [super initWithFrame:frame] )
{
UIImageView *imageView = [[UIImageView alloc] initWithImage: itemUnderlay];
[self addSubview:imageView];
[imageView release];
overlayImage = NO;
}
return self;
}

-( void )setOverlayImage:( CGImageRef )newOverlayImage
{
overlayImage = newOverlayImage;
}

-( CGImageRef )overlayImage
{
return overlayImage;
}

-( void )drawRect:( CGRect )rect
{
if( overlayImage )
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage( context, rect, overlayImage );
}
}


This view is created with an underlay/overlay image in a different class:


itemView = [[ItemView alloc] initWithItemUnderlay:defaultItemUnderlay
frame:CGRectMake( ITEM_VIEW_X, ITEM_VIEW_Y, ITEM_VIEW_WIDTH, ITEM_VIEW_HEIGHT )];
[itemView setOverlayImage:[UIImage imageNamed:@"MyImage.png"].CGImage];
[customTableView addSubview:itemView];


So far this works fine - the underlay image is set and the overlay image is draw on top of it. I can then change the overlayImage using setOverlayImage and it redraws the overlay image as I would want.

However, the simulator crashes if I use an image I gather from the web. I have an Item class that can hold a CGImageRef. An instance of the Item class is created and the image is set to an image gathered from the web:


NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
[item setImage:[UIImage imageWithData:imageData].CGImage];


This item class gets returned to the class that originally set the overlay/underlay images. I know the image gathered is correct as I have displayed it as a UIImage before. However, if I now set the CGImage from the Item class as the overlay image the simulator crashes:


[itemView setOverlayImage:[item image]]; // doesn't work
// [itemView setOverlayImage:[UIImage imageNamed:@"MyImage.png"].CGImage] // does work.
[itemView setNeedsDisplay];


Is there something special required to retain a CGImage in an instance variable? I've been pulling my hair out over this for days - if anyone can help I would really appreciate it...

In case it helps, this is a chunk of the report from the crash:


Process: MyApp [14803]
Path: /Users/Ross/Library/Application Support/iPhone Simulator/User/Applications/583EAA3F-4E73-4D8C-8928-ACCC6837C773/MyApp.app/MyApp
Identifier: MyApp
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: launchd [89]

Date/Time: 2008-04-28 02:05:18.256 +0100
OS Version: Mac OS X 10.5.2 (9C7010)
Report Version: 6

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000044b2e002
Crashed Thread: 0

Thread 0 Crashed:
0 com.apple.CoreGraphics 0x31062bd6 decode_byte_8bpc_3 + 70
1 com.apple.CoreGraphics 0x30fcb27e decode_data + 4614
2 com.apple.CoreGraphics 0x30fc9f54 img_decode_read + 1641
3 com.apple.CoreGraphics 0x3102fad5 img_interpolate_read + 656
4 com.apple.CoreGraphics 0x30fc7351 img_data_lock + 4996
5 com.apple.CoreGraphics 0x30fc55ef CGSImageDataLock + 168
6 libRIP.A.dylib 0x00289160 ripc_AcquireImage + 3116
7 libRIP.A.dylib 0x002784a0 ripc_DrawImage + 3652
8 com.apple.CoreGraphics 0x30fc53d5 CGContextDrawImage + 397
9 MyApp 0x000060f7 -[ItemView drawRect:] + 73 (ItemView.m:42)
10 UIKit 0x30b4a820 -[UIView(CALayerDelegate) drawLayer:inContext:] + 452
11 QuartzCore 0x32022512 -[CALayer drawInContext:] + 65
12 QuartzCore 0x320224b9 backing_callback + 69
13 QuartzCore 0x320220cd CABackingStoreUpdate + 1938
14 QuartzCore 0x3202176e -[CALayer _display] + 896
15 QuartzCore 0x32015c32 CALayerDisplayIfNeeded + 178
16 QuartzCore 0x32013f77 CAContextCommitTransaction + 191
17 QuartzCore 0x32013c66 CATransactionCommit + 205
18 com.apple.CoreFoundation 0x967e29c2 __CFRunLoopDoObservers + 466
19 com.apple.CoreFoundation 0x967e3c60 CFRunLoopRunSpecific + 656
20 com.apple.CoreFoundation 0x967e4d18 CFRunLoopRunInMode + 88
21 GraphicsServices 0x31670e4a GSEventRunModal + 217
22 GraphicsServices 0x31670f0f GSEventRun + 115
23 UIKit 0x30b2679b -[UIApplication _run] + 441
24 UIKit 0x30b30de0 UIApplicationMain + 1224
25 MyApp 0x00001ee4 main + 102 (main.m:14)
26 MyApp 0x00001e52 start + 54


Thanks for your time.



RossOliver
Apr 28, 2008, 12:22 AM
I've narrowed the problem down to these few lines:


NSURL *imageURL = [NSURL URLWithString:[[query objectAtIndex:0] stringValue]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
//[item setImage:[UIImage imageWithData:imageData].CGImage];
[item setImage:[UIImage imageNamed:@"test.jpg"].CGImage];


By replacing the commented out line with the line using an image in my application it works perfectly. Is there a step I have missed out when converting the imageData to a CGImage?

As I said in my other post, the image itself works correctly when I just make it into a UIImage from the NSURL instead of CGImage...

Another odd thing I noticed was that the image is flipped upside down before it's drawn in drawRect :confused:

-Ross

[edit]

Managed to get the image the correct way up using this useful code snippet:


CGContextTranslateCTM( context, 0, CGRectGetMaxY( rect ) );
CGContextScaleCTM( context, 1.0, -1.0 );
rect = CGRectOffset( rect, 0, -rect.origin.y );

ecume
Jan 2, 2009, 03:44 PM
I'm also running into random crashes when doing exactly your senario - compositing two images, one of which was grabbed from the web. It looks like the issue is in UIGraphicsGetCurrentContext();

I f I just use local UIImages = no problems...

yoavhacohen
Aug 28, 2011, 10:48 AM
Try to call it from the main thread:

[self.imageViewer performSelectorOnMainThread:@selector(setImage:) withObject:(id)cgImage waitUntilDone:NO];

idelovski
Aug 28, 2011, 05:03 PM
In the code above (1st post) you never retain it. I suppose it all works nice with -imageNamed: because those images tend to stick around for a long time.

PhoneyDeveloper
Aug 28, 2011, 05:24 PM
This thread is over two years old. They probably figured it out by now.

idelovski
Aug 28, 2011, 06:22 PM
Ups, you are right. I wasn't paying attention to all the dates. The guy in front of me had a fresh time on his post and I probably assumed all was fine.

Now when I looked at this thread more carefully I have noticed that original message from 2008 resurfaced twice so far. First time after 8 months and now after more than two years. Second interesting thing is the label on yoavhacohen:

Joined in 2008, macrumors newbie.

ArtOfWarfare
Aug 28, 2011, 06:40 PM
Second interesting thing is the label on yoavhacohen:

Joined in 2008, macrumors newbie.

Member titles are mostly based on the number of posts a member has made. They probably just haven't posted much since joining the forums.