tags:

views:

442

answers:

2

I'm trying to crop a NSImage which contains a PDF. When printing I am using NSImage's drawInRect to have it draw only what I need - and this works great.

But, now instead I'm trying to create a new NSImage of just the cropped area. I played with it for a while, then found this code on CocoaBuilder:

- (NSImage *) imageFromRect: (NSRect) rect
{
  NSAffineTransform * xform = [NSAffineTransform transform];

  // translate reference frame to map rectangle 'rect' into first quadrant
  [xform translateXBy: -rect.origin.x
                  yBy: -rect.origin.y];

  NSSize canvas_size = [xform transformSize: rect.size];

  NSImage * canvas = [[NSImage alloc] initWithSize: canvas_size];
  [canvas lockFocus];

  [xform concat];

  // Get NSImageRep of image
  NSImageRep * rep = [self bestRepresentationForDevice: nil];

  [rep drawAtPoint: NSZeroPoint];

  [canvas unlockFocus];
  return [canvas autorelease];
}

This works, but the returned NSImage is blurry, and no longer suitable for printing. Any ideas?

+3  A: 

lockFocus/unlockFocus performs raster drawing to the image's cache. That's why it's “blurry”—it's low-resolution and possibly misregistered. You need vector drawing.

Use PDF Kit. First, set the crop box of each page to your rectangle. You should then be able to create your cropped NSImage from the dataRepresentation of the PDFDocument.

Peter Hosey
+2  A: 

Here is the code to perform what Peter Hosey answered. Thanks!

PDFDocument *thePDF = [[PDFDocument alloc] initWithData:pdfData];
PDFPage *thePage = [thePDF pageAtIndex:0];
NSRect pageCropRect = NSMakeRect(0, 100, 100, 100);

[thePage setBounds:pageCropRect forBox:kPDFDisplayBoxMediaBox];
NSImage *theCroppedImage = [[NSImage alloc] initWithData:[thePage dataRepresentation]];
Jonathan
Make sure you duly release or autorelease thePDF and theCroppedImage.
Peter Hosey