Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize and Save NSImage?

I have an NSImageView which I get an image for from an NSOpenPanel. That works great.

Now, how can I take that NSImage, half its size and save it as the same format in the same directory as the original as well?

If you can help at all with anything I'd appreciate it, thanks.

like image 352
Josh Kahane Avatar asked Mar 10 '11 19:03

Josh Kahane


5 Answers

Check the ImageCrop sample project from Matt Gemmell:
http://mattgemmell.com/source/

Nice example how to resize / crop images.
Finally you can use something like this to save the result (dirty sample):

// Write to TIF
[[resultImg TIFFRepresentation] writeToFile:@"/Users/Anne/Desktop/Result.tif" atomically:YES];

// Write to JPG
NSData *imageData = [resultImg  TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
[imageData writeToFile:@"/Users/Anne/Desktop/Result.jpg" atomically:NO];
like image 154
Anne Avatar answered Sep 27 '22 03:09

Anne


Since NSImage objects are immutable you will have to:

  1. Create a Core Graphics context the size of the new image.
  2. Draw the NSImage into the CGContext. It should automatically scale it for you.
  3. Create an NSImage from that context
  4. Write out the new NSImage
  5. Don't forget to release any temporary objects you allocated.

There are definitely other options, but this is the first one that came to mind.

like image 33
Mark Avatar answered Sep 26 '22 03:09

Mark


+(NSImage*) resize:(NSImage*)aImage scale:(CGFloat)aScale
{
    NSImageView* kView = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, aImage.size.width * aScale, aImage.size.height* aScale)];
    [kView setImageScaling:NSImageScaleProportionallyUpOrDown];
    [kView setImage:aImage];

    NSRect kRect = kView.frame;
    NSBitmapImageRep* kRep = [kView bitmapImageRepForCachingDisplayInRect:kRect];
    [kView cacheDisplayInRect:kRect toBitmapImageRep:kRep];

    NSData* kData = [kRep representationUsingType:NSJPEGFileType properties:nil];
    return [[NSImage alloc] initWithData:kData];
}
like image 26
Changhoon Avatar answered Sep 30 '22 03:09

Changhoon


Here is a specific implementation

-(NSImage*)resizeImage:(NSImage*)input by:(CGFloat)factor
{    
    NSSize size = NSZeroSize;      
    size.width = input.size.width*factor;
    size.height = input.size.height*factor; 

    NSImage *ret = [[NSImage alloc] initWithSize:size];
    [ret lockFocus];
    NSAffineTransform *transform = [NSAffineTransform transform];
    [transform scaleBy:factor];  
    [transform concat]; 
    [input drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];    
    [ret unlockFocus];        

    return [ret autorelease];
}

Keep in mind that this is pixel based, with HiDPI the scaling must be taken into account, it is simple to obtain :

-(CGFloat)pixelScaling
{
    NSRect pixelBounds = [self convertRectToBacking:self.bounds];
    return pixelBounds.size.width/self.bounds.size.width;
}
like image 29
valexa Avatar answered Sep 29 '22 03:09

valexa


Apple has source code for downscaling and saving images found here http://developer.apple.com/library/mac/#samplecode/Reducer/Introduction/Intro.html

like image 22
awiebe Avatar answered Sep 27 '22 03:09

awiebe