Reduce image bytes size with Cocoa

后端 未结 2 2058
小鲜肉
小鲜肉 2020-12-30 17:23

I have a 1600x1600 1.2MB image which resized to 320x320 shrinks to 404KB. I need to go further and reduce the bytes size without reducing the image aspect size.

Curr

相关标签:
2条回答
  • 2020-12-30 17:59

    If you need compression and you don't mind losing image quality then save the file as a JPEG. To do this, you need to get an NSBitmapImageRep from your image and then get a JPEG representation:

    //yourImage is an NSImage object
    
    NSBitmapImageRep* myBitmapImageRep;
    
    if(useActualSize)
    {
        //this will produce an image the full size of the NSImage's backing bitmap, which may not be what you want
        myBitmapImageRep = [NSBitmapImageRep imageRepWithData: [yourImage TIFFRepresentation]];
    }
    else
    {
        //this will get a bitmap from the image at 1 point == 1 pixel, which is probably what you want
        NSSize imageSize = [yourImage size];
        [yourImage lockFocus];
        NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
        myBitmapImageRep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect] autorelease];
        [yourImage unlockFocus];
    }
    
    CGFloat imageCompression = 0.7; //between 0 and 1; 1 is maximum quality, 0 is maximum compression
    
    // set up the options for creating a JPEG
    NSDictionary* jpegOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                    [NSNumber numberWithDouble:imageCompression], NSImageCompressionFactor,
                    [NSNumber numberWithBool:NO], NSImageProgressive,
                    nil];
    
    // get the JPEG encoded data
    NSData* jpegData = [myBitmapImageRep representationUsingType:NSJPEGFileType properties:jpegOptions];
    //write it to disk
    [jpegData writeToFile:[NSHomeDirectory() stringByAppendingPathComponent:@"foo.jpg"] atomically:YES];
    
    0 讨论(0)
  • 2020-12-30 18:08
    #import "UIImage+Compress.h"
    
    #define MAX_IMAGEPIX 200.0          // max pix 200.0px
    #define MAX_IMAGEDATA_LEN 50000.0   // max data length 5K
    
    @implementation UIImage (Compress)
    
    - (UIImage *)compressedImage {
        CGSize imageSize = self.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
    
        if (width <= MAX_IMAGEPIX && height <= MAX_IMAGEPIX) {
            // no need to compress.
            return self;
        }
    
        if (width == 0 || height == 0) {
            // void zero exception
             return self;
        }
    
        UIImage *newImage = nil;
        CGFloat widthFactor = MAX_IMAGEPIX / width;
        CGFloat heightFactor = MAX_IMAGEPIX / height;
        CGFloat scaleFactor = 0.0;
    
        if (widthFactor > heightFactor)
            scaleFactor = heightFactor; // scale to fit height
        else
            scaleFactor = widthFactor; // scale to fit width
    
        CGFloat scaledWidth  = width * scaleFactor;
        CGFloat scaledHeight = height * scaleFactor;
        CGSize targetSize = CGSizeMake(scaledWidth, scaledHeight);
    
        UIGraphicsBeginImageContext(targetSize); // this will crop
    
        CGRect thumbnailRect = CGRectZero;
        thumbnailRect.size.width  = scaledWidth;
        thumbnailRect.size.height = scaledHeight;
    
        [self drawInRect:thumbnailRect];
    
        newImage = UIGraphicsGetImageFromCurrentImageContext();
    
        //pop the context to get back to the default
        UIGraphicsEndImageContext();
    
        return newImage;
    
    }
    
    - (NSData *)compressedData:(CGFloat)compressionQuality {
        assert(compressionQuality <= 1.0 && compressionQuality >= 0);
    
        return UIImageJPEGRepresentation(self, compressionQuality);
    }
    
    - (CGFloat)compressionQuality {
        NSData *data = UIImageJPEGRepresentation(self, 1.0);
        NSUInteger dataLength = [data length];
    
        if(dataLength > MAX_IMAGEDATA_LEN) {
            return 1.0 - MAX_IMAGEDATA_LEN / dataLength;
        } else {
            return 1.0;
        }
    }
    
    - (NSData *)compressedData {
        CGFloat quality = [self compressionQuality];
    
        return [self compressedData:quality];
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题