How to resize NSImage?

前端 未结 10 1647
萌比男神i
萌比男神i 2020-12-02 21:21

I have an NSBitmapImageRep which is WxH size.

I create NSImage and call addRepresentation:. Then I n

相关标签:
10条回答
  • 2020-12-02 21:41

    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
    }
    
    0 讨论(0)
  • 2020-12-02 21:42

    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!)!
    }
    
    0 讨论(0)
  • 2020-12-02 21:43

    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)")
            }
        }
    }
    
    
    0 讨论(0)
  • 2020-12-02 21:46

    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
    
    0 讨论(0)
提交回复
热议问题