void ResizeAndSaveSourceImageFromFile(NSString *imagePath, NSInteger width, NSInteger height, NSString *destinationFolder, NSString *fileName, BOOL shouldCrop, NSInteger rotation, NSInteger cornerRadius, BOOL removeAlpha) { NSString *outputFilePath = [NSString stringWithFormat:@"%@/%@", destinationFolder, fileName]; NSImage *sourceImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; NSSize sourceSize = sourceImage.size; float sourceAspect = sourceSize.width / sourceSize.height; float desiredAspect = width / height; float finalWidth = width; float finalHeight = height; if (shouldCrop == true) { if (desiredAspect > sourceAspect) { width = height * sourceAspect; } else if (desiredAspect < sourceAspect) { height = width / sourceAspect; } } if (width < finalWidth) { width = finalWidth; height = width / sourceAspect; } if (height < finalHeight) { height = finalHeight; width = height * sourceAspect; } NSImage *resizedImage = ImageByScalingToSize(sourceImage, CGSizeMake(width, height)); if (shouldCrop == true) { resizedImage = ImageByCroppingImage(resizedImage, CGSizeMake(finalWidth, finalHeight)); } if (rotation != 0) { resizedImage = ImageRotated(resizedImage, rotation); } if (cornerRadius != 0) { resizedImage = ImageRounded(resizedImage, cornerRadius); } NSBitmapImageRep *imgRep = UnscaledBitmapImageRep(resizedImage, removeAlpha); NSBitmapImageFileType type = NSPNGFileType; if ([fileName rangeOfString:@".jpg"].location != NSNotFound) { type = NSJPEGFileType; } NSData *imageData = [imgRep representationUsingType:type properties: @{}]; [imageData writeToFile:outputFilePath atomically:NO]; if ([outputFilePath rangeOfString:@"land-mdpi"].location != NSNotFound) { [imageData writeToFile:[outputFilePath stringByReplacingOccurrencesOfString:@"land-mdpi" withString:@"tvdpi"] atomically:NO]; } } NSImage* ImageByScalingToSize(NSImage* sourceImage, NSSize newSize) { if (! sourceImage.isValid) return nil; NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:newSize.width pixelsHigh:newSize.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace bytesPerRow:0 bitsPerPixel:0]; rep.size = newSize; [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:rep]]; [sourceImage drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height) fromRect:NSZeroRect operation:NSCompositingOperationCopy fraction:1.0]; [NSGraphicsContext restoreGraphicsState]; NSImage *newImage = [[NSImage alloc] initWithSize:newSize]; [newImage addRepresentation:rep]; return newImage; } NSBitmapImageRep* UnscaledBitmapImageRep(NSImage *image, BOOL removeAlpha) { NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:image.size.width pixelsHigh:image.size.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:0 bitsPerPixel:0]; [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithBitmapImageRep:rep]]; [image drawAtPoint:NSMakePoint(0, 0) fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; [NSGraphicsContext restoreGraphicsState]; NSBitmapImageRep *imgRepFinal = rep; if (removeAlpha == YES) { NSImage *newImage = [[NSImage alloc] initWithSize:[rep size]]; [newImage addRepresentation:rep]; static int const kNumberOfBitsPerColour = 5; NSRect imageRect = NSMakeRect(0.0, 0.0, newImage.size.width, newImage.size.height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef tileGraphicsContext = CGBitmapContextCreate (NULL, imageRect.size.width, imageRect.size.height, kNumberOfBitsPerColour, 2 * imageRect.size.width, colorSpace, kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst); NSData *imageDataTIFF = [newImage TIFFRepresentation]; CGImageRef imageRef = [[NSBitmapImageRep imageRepWithData:imageDataTIFF] CGImage]; CGContextDrawImage(tileGraphicsContext, imageRect, imageRef); // Create an NSImage from the tile graphics context CGImageRef newImageRef = CGBitmapContextCreateImage(tileGraphicsContext); NSImage *newNSImage = [[NSImage alloc] initWithCGImage:newImageRef size:imageRect.size]; // Clean up CGImageRelease(newImageRef); CGContextRelease(tileGraphicsContext); CGColorSpaceRelease(colorSpace); CGImageRef CGImage = [newNSImage CGImageForProposedRect:nil context:nil hints:nil]; imgRepFinal = [[NSBitmapImageRep alloc] initWithCGImage:CGImage]; } return imgRepFinal; } NSImage* ImageByCroppingImage(NSImage* image, CGSize size) { NSInteger trueWidth = image.representations[0].pixelsWide; double refWidth = image.size.width; double refHeight = image.size.height; double scale = trueWidth / refWidth; double x = (refWidth - size.width) / 2.0; double y = (refHeight - size.height) / 2.0; CGRect cropRect = CGRectMake(x * scale, y * scale, size.width * scale, size.height * scale); CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)[image TIFFRepresentation], NULL); CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); CGImageRef imageRef = CGImageCreateWithImageInRect(maskRef, cropRect); NSImage *cropped = [[NSImage alloc] initWithCGImage:imageRef size:size]; CGImageRelease(imageRef); return cropped; }