Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
I'm working on a Mac program that should combine two images and display them in an ImageView.

The first image is dragged into XCode and the other one is loaded from disk.

How do I combine(merge) those two images and put them into my ImageView?
 

xArtx

macrumors 6502a
Mar 30, 2012
764
1
I'm working on a Mac program that should combine two images and display them in an ImageView.

The first image is dragged into XCode and the other one is loaded from disk.

How do I combine(merge) those two images and put them into my ImageView?

Could you not give the second image some transparency and print it over the first one?
 

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
I'm fairly new to Mac programming have done a lot of iOS programming.

But I don't think an ImageView can cotain two images!

I need to combine them somehow.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Do you actually need the images combined in memory/on disk or do you just want to display the result? If the latter just use 2 image views with one slightly transparent.

Otherwise:

1) Load each image into an NSImage object
2) Lock focus using lockFocus on the bottom "layer"
3) Draw the top "layer" using drawInRect:fromRect:eek:peration:fraction: setting the operation and fraction to do what you want.
 

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
I want to take one image and put another on on top of the first one and display it in an ImageView. Later I wan't the save the merged image form the ImageView.

I have eight ImageViews and for each of the I have a button. When a button is clicked I choose an image from disk and combine it with an image already dragged into Xcode.

Right now I have some code that actually merge two images and it works fine for the first ImageView but when I do the same for the second ImageView the first one changes to the exact same as the second one. If I then loads a new image into the first one the second changes automatically.

So I'm thinking theres something wrong with my code and thats why I'm asking for an example on how to do it.

Here the code from my m file.

The load button ( it the same code for the second button)
Code:
NSOpenPanel* panel = [NSOpenPanel openPanel];
        
    [panel setCanChooseFiles:YES];
    [panel setCanChooseDirectories:NO];
    
    [panel beginWithCompletionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            NSURL *theDoc = [[panel URLs] objectAtIndex:0];
                
            NSString *fileNameAndPath = [[theDoc path] stringByStandardizingPath];

            //** Vælg device
            switch ([[rbSelectDevice selectedCell] tag]) {
                case 1: //** iPhone 5
                    screenShot1 = [self mergeImages:iPhone5 withImage:[[NSImage alloc]initWithContentsOfFile:fileNameAndPath]];
                    break;
            }

            [ivScreenshot1 setImage:screenShot1];
            
        }
            
    }];

The merge method
Code:
//** Merge two images together
-(NSImage *)mergeImages:(NSImage *)theTarget withImage:(NSImage *)theSource{

    //Get the source image from file
	NSImage *source = theSource; //[[NSImage alloc]initWithContentsOfFile:@"/Users/JensThomsen/Library/Developer/Xcode/DerivedData/Smartphone_App_Store_Icons_and_Images_Tool-bsnfzaaviuzrqdcpuknipijqslci/Build/Products/Debug/icon512.png"];
	
	//Init target image
	NSImage *target = theTarget; //[[NSImage alloc]initWithContentsOfFile:@"/Users/JensThomsen/Library/Developer/Xcode/DerivedData/Smartphone_App_Store_Icons_and_Images_Tool-bsnfzaaviuzrqdcpuknipijqslci/Build/Products/Debug/tempImage.png"];
    
	//start drawing on target
	[target lockFocus];
	//draw the portion of the source image on target image
	[source drawInRect:NSMakeRect(84,270,770,1365) fromRect:NSZeroRect operation: NSCompositeCopy fraction:1.0];
	//end drawing
	[target unlockFocus];
	
	//create a NSBitmapImageRep
	NSBitmapImageRep *bmpImageRep = [[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]];
	//add the NSBitmapImage to the representation list of the target
	[target addRepresentation:bmpImageRep];


    return target;
}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Sounds like you are using the same NSImage instance for all the views then. But we don't have the code for that bit. Also you're merge code has hard-coded both images so it will always return the exact same thing...
 

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
Maybe you are right but I cannot figure out where the problem is.


I declare this variables in the top.
Code:
NSImage *iPhone5;

NSImage *screenShot1;
NSImage *screenShot2;

I set the iPhone5 image in the initWithNibName method
Code:
iPhone5 = [NSImage imageNamed:@"IPhone_5.png"];

Does this clear things so that you maybe can see what I'm doing wrong?
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Maybe you are right but I cannot figure out where the problem is.


I declare this variables in the top.
Code:
NSImage *iPhone5;

NSImage *screenShot1;
NSImage *screenShot2;

I set the iPhone5 image in the initWithNibName method
Code:
iPhone5 = [NSImage imageNamed:@"IPhone_5.png"];

Does this clear things so that you maybe can see what I'm doing wrong?
It matters not what variable names you declare. It matters what's loaded to them. I see I miss read your code: the fixed paths are commented out. But we still can't see all of the code: only the code for one case. If all cases use
"iphone5" as their target then they are sharing a single instance so all will always be the same image.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Ahh, so if I use

NSImage *iPhone5_1;
NSImage *iPhone5_2;
NSImage *iPhone5_3;

It will be better?

Assuming each of those points to a different instance, not the same then yes. I.e. don't do this:

Code:
NSImage *temp = [NSImage imageNamed:@"IPhone_5.png"];
NSImage *iPhone5_1 = temp;
NSImage *iPhone5_2 = temp;
...

as the variable names completely and utterly don't matter: they would all point at the same instance.

Also check that imageNamed is not caching the result and returning the same instance: I'd use alloc/init to ensure a new, clean instance each time.
 

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
Okay I tried this
Code:
        iPhone5_1 = [[NSImage alloc] init];
        iPhone5_2 = [[NSImage alloc] init];
        iPhone5_1 = [NSImage imageNamed:@"IPhone_5.png"];
        iPhone5_2 = [NSImage imageNamed:@"IPhone_5.png"];

But I get the same result
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Okay I tried this
Code:
        iPhone5_1 = [[NSImage alloc] init];
        iPhone5_2 = [[NSImage alloc] init];
        iPhone5_1 = [NSImage imageNamed:@"IPhone_5.png"];
        iPhone5_2 = [NSImage imageNamed:@"IPhone_5.png"];

But I get the same result

I think you fundamentally don't understand objects, pointers and what this code does. The first two lines of code are completely and utterly pointless as they allocate new objects and point the variables at them to immediately afterwards have those pointers moved to other objects. You then use the method I warned you not to use as it would cache the object so it is most likely that _1 and _2 are now pointing at the same instance. When I suggested using alloc/init that was commonly used shorthand to indicate this style of code but not necessarily a plain init: in this case I expected you to use one of initWithContentsOfFile or initWithContentsOfURL.

But I would suggest you need to take step back and consider learning some basic debugging techniques like using NSLog...
 

Trisect Develop

macrumors newbie
Original poster
Jun 28, 2013
13
0
Denmark
Thanks!
This did it.
Code:
        NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"IPhone_5.png"];
        iPhone5_1 = [[NSImage alloc] initWithContentsOfFile:filePath];
        iPhone5_2 = [[NSImage alloc] initWithContentsOfFile:filePath];

And YES I'm new to Mac programming. Never had this problems when programming for iOS.
 

xArtx

macrumors 6502a
Mar 30, 2012
764
1
If your CPU has the time, why not load both images into bitmap contexts,
set the transparency of one of the images there,
overlay one atop the other, and then load the final image into the view?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.