5

I'm new to cocoa and what I'm trying to do is resize a NSImage, but it looks like I'm doing something wrong as my image's don't get resized. I had a look at the other questions and this approach looked like it should work:

- (void)scaleIcons:(NSString *)outputPath{
NSImage *anImage;
NSSize imageSize;
NSString *finalPath;

anImage = [self image];

imageSize = [anImage size];
imageSize.width = 512;
imageSize.height = 512;
[anImage setSize:imageSize];

finalPath = [outputPath stringByAppendingString:@"/icon_512x512.png"];

NSData *imageData = [anImage TIFFRepresentation];
NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageData];
NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:nil];
[dataToWrite writeToFile:finalPath atomically:NO];
}

everything works, except the fact that my images don't get scaled. Could someone help a bit?

Rokas
  • 57
  • 1
  • 5

3 Answers3

6

So your code snippet is omitting the operations actually required to scale/transform the image. Pass your image through a method such as this one before you try to save it:

- (NSImage *)scaleImage:(NSImage *)image toSize:(NSSize)targetSize
{
  if ([image isValid])
  {
    NSSize imageSize = [image size];
    float width  = imageSize.width;
    float height = imageSize.height;
    float targetWidth  = targetSize.width;
    float targetHeight = targetSize.height;
    float scaleFactor  = 0.0;
    float scaledWidth  = targetWidth;
    float scaledHeight = targetHeight;

    NSPoint thumbnailPoint = NSZeroPoint;

    if (!NSEqualSizes(imageSize, targetSize))
    {
      float widthFactor  = targetWidth / width;
      float heightFactor = targetHeight / height;

      if (widthFactor < heightFactor)
      {
        scaleFactor = widthFactor;
      }
      else
      {
        scaleFactor = heightFactor;
      }

      scaledWidth  = width  * scaleFactor;
      scaledHeight = height * scaleFactor;

      if (widthFactor < heightFactor)
      {
        thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
      }

      else if (widthFactor > heightFactor)
      {
        thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
      }

    NSImage *newImage = [[NSImage alloc] initWithSize:targetSize];

    [newImage lockFocus];

     NSRect thumbnailRect;
     thumbnailRect.origin = thumbnailPoint;
     thumbnailRect.size.width = scaledWidth;
     thumbnailRect.size.height = scaledHeight;

     [image drawInRect:thumbnailRect
              fromRect:NSZeroRect
             operation:NSCompositeSourceOver
              fraction:1.0];

    [newImage unlockFocus];
  }

  return newImage;
}

If you integrate this into your existing method:

- (void)scaleIcons:(NSString *)outputPath{

    NSSize outputSize = NSMakeSize(512.0f,512.0f);
    NSImage *anImage  = [self scaleImage:[self image] toSize:outputSize];

    NSString *finalPath = [outputPath stringByAppendingString:@"/icon_512x512.png"];
    NSData *imageData = [anImage TIFFRepresentation];
    NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageData];
    NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:nil];
   [dataToWrite writeToFile:finalPath atomically:NO];
}
isaac
  • 4,867
  • 1
  • 21
  • 31
  • Thanks for one of the most explanatory answers ever! Just had to change this line: NSSize outputSize = NSSizeMake(512.0f,512.0f); with this one: NSSize outputSize = NSSizeFromString(@"{512,512}"); – Rokas Jan 09 '13 at 20:52
  • 1
    NSMakeSize is what you want. NSSizeFromString will do a bunch of unnecessary string parsing. – Catfish_Man Jan 09 '13 at 20:59
  • Updated the answer, a mistake carried from the fact that most of my experience is with Cocoa Touch (where you'd call CGSizeMake(width,height))... Hope it works for you! – isaac Jan 09 '13 at 20:59
2

About Parag Bafna's answer, for resizeing it should be "resample" instead of "crop":

sips --resampleHeightWidth 10 10 input.png --out output.png
Soul Clinic
  • 1,189
  • 12
  • 18
0

You can also use sips(scriptable image processing system) command.

sips --cropToHeightWidth 10 10 input.png --out output.png
Parag Bafna
  • 22,812
  • 8
  • 71
  • 144
  • The name of that command suggests that it CROPS the image (trimming away pixels that are not inside the selected area) rather than resizing it. – Duncan C Apr 20 '15 at 17:31