Layering an image over another

Discussion in 'Mac Programming' started by RossOliver, Apr 22, 2008.

  1. RossOliver macrumors regular

    Joined:
    Nov 6, 2006
    #1
    Hey,

    I want to try some image manipulation. The effect I'm after is similar to that of the Delicious Library images; a solid image as an overlay to another image - in their case they put an image of a book cover over a base image, which gives it a book-looking texture.

    How would I go about replicating these effects?

    Thanks,

    -Ross
     
  2. RossOliver thread starter macrumors regular

    Joined:
    Nov 6, 2006
    #2
    I think I have what I need now:

    http://developer.apple.com/document...//apple_ref/doc/uid/TP30001066-CH212-CJBEBCAA

    What's the best way to go about this? I have two NSImage objects at the minute and I want to overlay one on top of the other. Is there a relatively straight forward example of this knocking around that anyone knows of? I can't seem to find any good documentation on how it all fits together...

    -Ross
     
  3. RossOliver thread starter macrumors regular

    Joined:
    Nov 6, 2006
    #3
    I have a working program now doing what I want. I made it by subclassing UIView, adding a UIImageView subview containing the bottom image I want to use and then added the image I wanted on top of it in the drawRect method:

    Code:
    -( 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 )drawRect:( CGRect )rect
    {
    	if( overlayImage )
    	{
    		CGContextRef context = UIGraphicsGetCurrentContext(); 
    		CGContextDrawImage( context, rect, overlayImage );
    	}
    }
    
    I call it with this in my main class:

    Code:
    	itemView = [[ItemView alloc] initWithItemUnderlay:defaultItemUnderlay 
    		frame:CGRectMake( ITEM_VIEW_X, ITEM_VIEW_Y, ITEM_VIEW_WIDTH, ITEM_VIEW_HEIGHT )];
    	[itemView setOverlayImage:defaultOverlayImage];
    	[customTableView addSubview:itemView];
    
    This gives me the default images. However, if I try and change the top image (overlayImage) using this code:

    Code:
    	[itemView setOverlayImage:[item image]];
    	[itemView drawRect:CGRectMake( ITEM_VIEW_X, ITEM_VIEW_Y, ITEM_VIEW_WIDTH, ITEM_VIEW_HEIGHT )];
    
    It doesn't change the UIView at all... I also get this error message in the console:

    Code:
    <Error>: CGContextDrawImage: invalid context
    
    If anyone knows how I can re-draw my overlayImage after I have set the default underlay/overlay images I would appreciate the help...
     
  4. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #4
    Manually calling drawRect is basically always a mistake in Cocoa. Use setNeedsDisplayInRect instead.
     
  5. RossOliver thread starter macrumors regular

    Joined:
    Nov 6, 2006
    #5
    Ah right, I changed that and it actually crashes now instead of just not working (which is a step forward I guess...).

    I think the problem might be because I am getting warnings about my UIView which has my drawRect in not responding to a setOverlayImage message:

    Code:
    warning: 'UIView' may not respond to 'setOverlayInage'
    
    It must work at least once, however, since that is how the default image is set initially...

    I don't know why it's complaining - I have declared setOverlayImage like so:

    Code:
    	@private
    		CGImageRef overlayImage;
    
    ...
    
    @property( nonatomic, assign ) CGImageRef overlayImage;
    
    ...
    
    @synthesize overlayImage;
    
    Any ideas?

    Thanks
     
  6. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #6
    Does the error really say "setOverlayInage" or did you type it in by hand? If its just a typo in your post and not code, then never mind.

    Also. In the first bit of code you have "overlayImage = NO" and also have "CGImageRef overlayImage" in the last bit of sample code, which seems like a conflict of types to me.
     
  7. RossOliver thread starter macrumors regular

    Joined:
    Nov 6, 2006
    #7

    Ah, I just mistyped that...

    What does the NO constant actually point to? I thought it was like nil and could be applied to any object?
     

Share This Page