Create a Layer in Cocoa from a picture

Moderator
Posts: 608
Joined: 2002.04
Post: #16
Quote:Originally posted by w_reade
load your image in either the init method or some other one you make up (and remember to call ;) )
Actually, probably best to load the image in the -awakeFromNib or -initWithFrame:(NSRect)frame method. I don't know if -init gets called when the view is created by IB. Your code (for your NSView subclass) should resemble this:
Code:
- (void)awakeFromNib
{
    yourImage = [NSImage imageNamed:@"imageName"];
}

- (void)drawRect:(NSRect)rect
{
   // erase whatever is in the view right now
    [[NSColor whiteColor] set];
      [[NSBezierPath bezierPathWithRect:[self bounds]] fill];

    // draw your image
    [yourImage compositeToPoint:[self centerInView:self] operation:NSCompositeSourceOver];
}

- (NSPoint)centerInView:(NSView *)view
{
    return NSMakePoint([view bounds].size.width/2, [view bounds].size.height/2);
}
Quote this message in a reply
quillbit
Unregistered
 
Post: #17
I apologize for not posting this sooner; work and Valentine's Day both conspired to keep me off the computer until this evening.

I've put together a simple application that demonstrates how to position sprites within an NSView. Here's the basic steps:

1. Create a new Cocoa application.

2. Open the application's nib file in Interface Builder (IB). Place a CustomView in the main window and resize it as desired.

3. Under the Classes tab, right-click on NSView and choose "Subclass NSView." Call the subclass "SampleView" and select it. From the "Classes" menu item, instantiate the subclass; then go back to the "Classes" tab, select "SampleView," and choose "Create Files" from the "Classes" menu item. Accept the defaults for placing the files into your application. Open the Info for the CustomView, choose "Custom Class," and set it to SampleView. Save the whole shebang and exit IB.

4. Back in Project Builder (PB), open the "Other Sources" item, and choose "SampleView.m." Delete what's in there, then cut and paste the following code:

[SOURCECODE]
#import "SampleView.h"

// create global objects
NSPoint drawPoint;
NSImage *bgImage;
NSImage *spriteImage;

@implementation SampleView


// override acceptsFirstMouse to let the first mouse click trigger an event
- (BOOL)acceptsFirstMouse: (NSEvent *)event {
return(YES);
}

- (void)awakeFromNib {
// init drawPoint to origin
drawPoint = NSMakePoint(0,0);

// the files background.pdf and sprite.pdf are added to the application resources.
// You have to use NSBundle calls to get the path to the resources so you can load
// them.
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString *bgPath = [thisBundle pathForResource:@"background" ofType:@"pdf"];
NSString *spritePath = [thisBundle pathForResource:@"sprite" ofType:@"pdf"];

// Load the images.
spriteImage = [[NSImage alloc] initWithContentsOfFile:spritePath];
bgImage = [[NSImage alloc] initWithContentsOfFile:bgPath];

// For demonstrative purposes: the paths you're loading from.
NSLog(bgPath);
NSLog(spritePath);

// eyeball the objects to make sure we actually loaded the data from file.
if (bgImage == nil){
NSLog(@"Failed to get background data!\n");
exit(13);
}
if (spriteImage == nil){
NSLog(@"Failed to get sprite data!\n");
exit(14);
} // end niltest

}

- (void)drawRect: (NSRect)rect {

// draw the background and sprite. THIS IS THE BRAIN-DEAD WAY TO DO THIS!
// A much better way is to only update the dirty rectangles that the
// sprites have been blitted over.
[bgImage compositeToPoint:NSMakePoint(0,0) operation:NSCompositeCopy];
[spriteImage compositeToPoint:drawPoint operation:NSCompositeSourceOver];


}

// event handler for mouseDown events. (I suppose you could have figured that out
// on your own....)
- (void)mouseDown: (NSEvent *)event {

// converts the mouse-click coordinates in the view into a point tuple
drawPoint = [self convertPoint:[event locationInWindow] fromView:nil];
// again, just to show you what we're doing.
NSLog(@"Mouse at %@", NSStringFromPoint(drawPoint));
// call drawRect to update the window.
[self setNeedsDisplay:YES];
}



@end

[/SOURCECODE]

Save the file.

5. Get two image files, both in a suitable format. (I use PDFs; if you want a different image type, just change the type in the appropriate bundle calls.) The file names should be "background.pdf" (or whatever extension is appropriate) and "sprite.pdf." For obvious reasons, the background image should be the size of your view, and the sprite should be somewhat smaller. Right-click on the "Resources" item, choose "Add Files," select the files, and add them into your project. (Choose the copy option before doing so.)

For no particularly good reason, I use a spaceship flying over a Renaissance map of Italy.

6. Compile and run. That's it!
Quote this message in a reply
Simon
Unregistered
 
Post: #18
When I try that you did quillbit I gett 3 Errors:
parse error before '*'
On line:
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];

and a error on ( spritePath undeclared)
spriteImage = [[NSImage alloc] initWithContentsOfFile:spritePath];
and

bgImage = [[NSImage alloc] initWithContentsOfFile:bgPath];


My pictures are jpg.
Quote this message in a reply
quillbit
Unregistered
 
Post: #19
Hrm, a line-break problem mayhaps? Please cut-and-paste the file from SampleView.m and PM it to me (no need to clutter the thread with what should be an OT issue).
Quote this message in a reply
Simon
Unregistered
 
Post: #20
I can¥t send pm it say: "vBulletin Message
Your administrator has disabled private messaging."
I have to put I upp again:
[SOURCECODE]
#import "SampleView.h"



// create global objects

NSPoint drawPoint;

NSImage *bgImage;

NSImage *spriteImage;



@implementation SampleView





// override acceptsFirstMouse to let the first mouse click trigger an event

- (BOOL)acceptsFirstMouse: (NSEvent *)event {

return(YES);

}



- (void)awakeFromNib {

// init drawPoint to origin

drawPoint = NSMakePoint(0,0);



// the files background.pdf and sprite.pdf are added to the application resources.

// You have to use NSBundle calls to get the path to the resources so you can load

// them.

NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];

NSString *bgPath = [thisBundle pathForResource:@"background" ofType:@"jpg"];

NSString *spritePath = [thisBundle pathForResource:@"sprite" ofType:@"jpg"];



// Load the images.

spriteImage = [[NSImage alloc] initWithContentsOfFile:spritePath];

bgImage = [[NSImage alloc] initWithContentsOfFile:bgPath];



// For demonstrative purposes: the paths you're loading from.

NSLog(bgPath);

NSLog(spritePath);



// eyeball the objects to make sure we actually loaded the data from file.

if (bgImage == nil){

NSLog(@"Failed to get background data!\n");

exit(13);

}

if (spriteImage == nil){

NSLog(@"Failed to get sprite data!\n");

exit(14);

} // end niltest



}



- (void)drawRect: (NSRect)rect {



// draw the background and sprite. THIS IS THE BRAIN-DEAD WAY TO DO THIS!

// A much better way is to only update the dirty rectangles that the

// sprites have been blitted over.

[bgImage compositeToPoint:NSMakePoint(0,0) operation:NSCompositeCopy];

[spriteImage compositeToPoint:drawPoint operation:NSCompositeSourceOver];





}



// event handler for mouseDown events. (I suppose you could have figured that out

// on your own....)

- (void)mouseDown: (NSEvent *)event {



// converts the mouse-click coordinates in the view into a point tuple

drawPoint = [self convertPoint:[event locationInWindow] fromView:nil];

// again, just to show you what we're doing.

NSLog(@"Mouse at %@", NSStringFromPoint(drawPoint));

// call drawRect to update the window.

[self setNeedsDisplay:YES];

}







@end

[/SOURCECODE]

Should I not change anything i stampleView?ø
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Cocoa and the big picture Varias 3 2,653 Feb 1, 2010 07:34 AM
Last Post: backslash
  Picture in Interface Builder skyhawk 1 3,205 Jun 15, 2006 02:10 PM
Last Post: OneSadCookie