I have an NSBitmapImageRep
which is W
xH
size.
I create NSImage
and call addRepresentation:
. Then I n
Actually it is not necessary to modify any source image parameters like size
. The following snippet is already in Swift, but I think you can infer the Objective-C version from it:
func resized(to: CGSize) -> NSImage {
let img = NSImage(size: to)
img.lockFocus()
defer {
img.unlockFocus()
}
if let ctx = NSGraphicsContext.current {
ctx.imageInterpolation = .high
draw(in: NSRect(origin: .zero, size: to),
from: NSRect(origin: .zero, size: size),
operation: .copy,
fraction: 1)
}
return img
}
Here is a Swift 3 version keeping ratio of image, just set minimumSize as the minimum height or width you want:
func imageResized(image: NSImage) -> NSImage {
let ratio = image.size.height / image.size.width
let width: CGFloat
let height: CGFloat
// We keep ratio of image
if ratio > 1 {
width = minimumSize
height = minimumSize * ratio
} else {
width = minimumSize
height = minimumSize * (1 / ratio)
}
let destSize = NSSize(width: width, height: height)
let newImage = NSImage(size: destSize)
newImage.lockFocus()
image.draw(in: NSRect(x: 0, y: 0, width: destSize.width, height: destSize.height), from: NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height), operation: .sourceOver, fraction: 1.0)
newImage.unlockFocus()
newImage.size = destSize
return NSImage(data: newImage.tiffRepresentation!)!
}
2020 | SWIFT 4 and 5:
usage:
let resizedImg = someImage.resizedCopy(w: 500.0, h:500.0)
let scaledImg = someImage.scaledCopy( sizeOfLargerSide: 1000.0)
//and bonus:
scaledImg.writePNG(toURL: someUrl )
code:
extension NSImage {
func scaledCopy( sizeOfLargerSide: CGFloat) -> NSImage {
var newW: CGFloat
var newH: CGFloat
var scaleFactor: CGFloat
if ( self.size.width > self.size.height) {
scaleFactor = self.size.width / sizeOfLargerSide
newW = sizeOfLargerSide
newH = self.size.height / scaleFactor
}
else{
scaleFactor = self.size.height / sizeOfLargerSide
newH = sizeOfLargerSide
newW = self.size.width / scaleFactor
}
return resizedCopy(w: newW, h: newH)
}
func resizedCopy( w: CGFloat, h: CGFloat) -> NSImage {
let destSize = NSMakeSize(w, h)
let newImage = NSImage(size: destSize)
newImage.lockFocus()
self.draw(in: NSRect(origin: .zero, size: destSize),
from: NSRect(origin: .zero, size: self.size),
operation: .copy,
fraction: CGFloat(1)
)
newImage.unlockFocus()
guard let data = newImage.tiffRepresentation,
let result = NSImage(data: data)
else { return NSImage() }
return result
}
public func writePNG(toURL url: URL) {
guard let data = tiffRepresentation,
let rep = NSBitmapImageRep(data: data),
let imgData = rep.representation(using: .png, properties: [.compressionFactor : NSNumber(floatLiteral: 1.0)]) else {
Swift.print("\(self) Error Function '\(#function)' Line: \(#line) No tiff rep found for image writing to \(url)")
return
}
do {
try imgData.write(to: url)
}catch let error {
Swift.print("\(self) Error Function '\(#function)' Line: \(#line) \(error.localizedDescription)")
}
}
}
EDIT You can resize image using below function:
- (NSImage *)imageResize:(NSImage*)anImage
newSize:(NSSize)newSize
{
NSImage *sourceImage = anImage;
[sourceImage setScalesWhenResized:YES];
// Report an error if the source isn't a valid image
if (![sourceImage isValid])
{
NSLog(@"Invalid Image");
} else
{
NSImage *smallImage = [[[NSImage alloc] initWithSize: newSize] autorelease];
[smallImage lockFocus];
[sourceImage setSize: newSize];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
[smallImage unlockFocus];
return smallImage;
}
return nil;
}
Secondly like this:
NSData *imageData = [yourImg TIFFRepresentation]; // converting img into data
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData]; // converting into BitmapImageRep
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor]; // any number betwwen 0 to 1
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps]; // use NSPNGFileType if needed
NSImage *resizedImage = [[NSImage alloc] initWithData:imageData]; // image created from data