PDA

View Full Version : Drawing a PNG to a CALayer




tooom
Oct 21, 2010, 09:20 AM
I wrote the following minimalistic iPhone app for drawing a simple png file onto a CALayer object.

Here is the code
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface DrawPNGOnCALayerViewController : UIViewController {
CGImageRef img;
CALayer* noteLayer;
UIImageView* imgView;
}

@end


And the implementation
#import "DrawPNGOnCALayerViewController.h"

@implementation DrawPNGOnCALayerViewController




// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {

}
return self;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

noteLayer = [[CALayer alloc] init];
[self.view.layer addSublayer:noteLayer];

/*imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"note.png"]];
[self.view addSubview:imgView];*/
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {}

- (void)viewWillAppear:(BOOL)animated {
/*
noteLayer.delegate = self;
noteLayer.bounds = CGRectMake(0.f, 0.f, 200.f, 200.f);
noteLayer.backgroundColor = [[UIColor blueColor] CGColor];
noteLayer.position = self.view.center;
[noteLayer setNeedsDisplay];
*/

UIImage* image = [UIImage imageNamed:@"note.png"];
img = CGImageRetain( image.CGImage );

noteLayer.delegate = self;
noteLayer.bounds = CGRectMake( 0.f,0.f, 200., 200. );
noteLayer.backgroundColor = [[UIColor blueColor] CGColor];
NSLog(@"img = %f,%f",CGImageGetWidth(img),CGImageGetHeight(img));
noteLayer.contents = (id)img;
noteLayer.position = self.view.center;
[noteLayer setNeedsDisplay];
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}

@end


I checked with the UIImageView that the png file is correctly found and it is displayed in the UIImageView. But if I run the code as above nothing will be drawn to the CALayer noteLayer. Just a blue square with no content.

I ran the program in the debugger and set a breakpoint to have look at the CGImageRef object img. When hovering with the mouse over the obeject the debugger tells me a memory address so the object doesn't seem to be nil. But the output of NSLog is strange, it displays the following output
2010-10-21 16:10:36.963 DrawPNGOnCALayer[72288:207] img = 0.000000,13510798882111488.000000

I do not understand what is wrong in my very simple program???



robbieduncan
Oct 21, 2010, 09:23 AM
I think if you have a drawLayer method then you are telling CALayer that your delegate will do all the drawing for that layer. As you are doing nothing in drawLayer nothing will get drawn. Either remove that method or implement it correctly to draw the contents.

tooom
Oct 21, 2010, 10:40 AM
Thanks for the answer.


If I understood you correctly I just have to remove the method "drawLayer:inContext:" from my code. So did I but still nothing is drawn...

Separately I also commented the line "noteLayer.delegate = self;" out. But it did had any effect either. No png is drawn.

robbieduncan
Oct 21, 2010, 10:54 AM
What size does the layer have? What is it's position? What is it attached to that will result in it getting drawn in screen?

tooom
Oct 21, 2010, 10:57 AM
:confused: Shouldn't this be clear from the code i posted?

robbieduncan
Oct 21, 2010, 11:01 AM
:confused: Shouldn't this be clear from the code i posted?

I don't see you set the frame or position anywhere. You seem to be assuming that by adding it as a sublayer this gets set to something sensible. Are you sure. I would be adding NSLog statements to make sure that the layer is actually a sensible size in a sensible position.

tooom
Oct 21, 2010, 11:08 AM
Sorry I don't understand what you trying to tell me. Could you just simply modify my "viewWillAppear" method so that it just makes what you want to know?

robbieduncan
Oct 22, 2010, 04:39 AM
Sorry I don't understand what you trying to tell me. Could you just simply modify my "viewWillAppear" method so that it just makes what you want to know?

You already have a NSLog statement in there. Did you just copy and paste this from somewhere? Do you understand what each and every line of code is doing?