Re: I just don't get NSAffineTransform and compositeToPoint:
Re: I just don't get NSAffineTransform and compositeToPoint:
- Subject: Re: I just don't get NSAffineTransform and compositeToPoint:
- From: Serge Meynard <email@hidden>
- Date: Sun, 13 Mar 2005 22:59:40 -0500
GOAL: To select a region of an image, crop to a new image (ie just
copy that portion). I have started with some good samples from Apple.
With their code I have it selecting and copying the image, the problem
is that it creates an image the same size of the original image.
I have tried changing sourceImageRect on line #10 to newImageBounds.
And that created an image of the right size, but only contained my
selection if I select from the lower left corner.
I tried playing with pathAdjustment on line #16 and that didn't help
I tried using compositeToPoint:fromRect:operation on line #23, but
that didn't help.
1: // Returns an autoreleased NSImage, consisting of the selected
portion of the reciever's image.
2: // If there's no selection, this method will return the original
image.
3: - (NSImage *)croppedImage
4: {
5: NSRect sourceImageRect = [[self cell]
rectCoveredByImageInBounds:[self bounds]];
6: NSRect newImageBounds = NSIntersectionRect([selectionMarker
selectedRect], sourceImageRect);
7:
8: if (!NSIsEmptyRect(newImageBounds))
9: {
10: NSImage *newImage = [[NSImage alloc]
initWithSize:sourceImageRect.size];
11:
12: NSAffineTransform *pathAdjustment = [NSAffineTransform
transform];
13:
14: NSBezierPath *croppingPath = [selectionMarker selectedPath];
15:
16: [pathAdjustment translateXBy: -NSMinX(sourceImageRect) yBy:
-NSMinY(sourceImageRect)];
17: croppingPath = [pathAdjustment
transformBezierPath:[selectionMarker selectedPath]];
18:
19: [newImage lockFocus];
20: [[NSGraphicsContext currentContext] setShouldAntialias:NO];
21: [[NSColor blackColor] set];
22: [croppingPath fill];
23: [[self image] compositeToPoint:NSZeroPoint
operation:NSCompositeSourceIn];
24: [newImage unlockFocus];
25:
26: return [newImage autorelease];
27: }
28: return [self image];
29: }
I have read the docs on NSAffineTransform and what I can find on the
net. But what it comes down to is I just don't understand it.
1) Is there a good place that explains these? I have spent over two
days and I just don't get it.
2) How do I fix the above code.
Thanks,
Jim
I didn't follow the start of this thread, so forgive me if I repeat
anything that's been said or tried...
You definitely need to use newImageBounds as the size of the new image
(as you point out yourself). As for the rest, I'm doing a bit of
guesswork since you don't specify everything in context. But I'm
assuming sourceImageRect is the complete rect for the source image, and
that [selectionMarker selectedPath] is defined in the same coordinate
system as the source image. I'm also assuming that [selectionMarker
selectedRect] basically matches with [[selectionMarker selectedPath]
bounds]. I think this code should work (barring any brain farts or
typos):
NSImage* newImage = [[NSImage alloc] initWithSize:
newImageBounds.size];
NSBezierPath* croppingPath = [selectionMarker selectedPath];
[newImage lockFocus];
[[NSGraphicsContext currentContext] saveGraphicsState];
NSAffineTransform* pathAdjustment = [NSAffineTransform transform];
[pathAdjustment translateXBy:-newImageBounds.origin.x
yBy:-newImageBounds.origin.y];
[pathAdjustment concat];
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
[[NSColor clearColor] set];
NSRectFill(newImageBounds);
[[NSColor blackColor] set];
[croppingPath fill];
[[self image] compositeToPoint:newImageBounds.origin
fromRect:newImageBounds operation:NSCompositeSourceIn];
[[NSGraphicsContext currentContext] restoreGraphicsState];
[newImage unlockFocus];
The pathAdjustment transform lets you modify the coordinate system of
the target image so it matches up with the source. You then clear the
target to transparent (so that NSCompositeSourceIn will clip to the
black fill) and composite the part of the source that you want into the
target.
This bit of code is very similar to something I wrote last week for a
similar purpose, so it should work OK; if it doesn't, let me know and
we can figure out what I typed wrong :) I'm actually not sure if the
save/restore is really needed, but it doesn't hurt (much).
Serge
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden