【问题标题】:Reduce image bytes size with Cocoa使用 Cocoa 减少图像字节大小
【发布时间】:2010-02-22 19:13:16
【问题描述】:

我有一个 1600x1600 的 1.2MB 图像,它调整为 320x320,然后缩小到 404KB。 我需要更进一步,在不减小图像纵横比的情况下减小字节大小。

目前我正在使用 -TIFFRepresentationUsingCompression:factor: NSImage 方法和 NSTIFFCompressionJPEG 以及似乎不会影响图像大小/质量的因素。

我该如何解决?

马可

【问题讨论】:

  • 你是说减少内存或磁盘上的图像大小吗?
  • 在磁盘上。 1.2MB 和 404KB 是磁盘大小

标签: objective-c cocoa


【解决方案1】:

如果您需要压缩并且不介意丢失图像质量,请将文件另存为 JPEG。为此,您需要从图像中获取NSBitmapImageRep,然后获取 JPEG 表示:

//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];

【讨论】:

  • 我不介意图像质量,但您的代码与 -TIFFRepresentationUsingCompression:factor: 方法不一样吗?
  • 没有。该方法创建一个具有内部 JPEG 压缩的 TIFF 文件。但是,文档状态“不支持 TIFF 文件中的 JPEG 压缩,并且忽略因素。”我的代码创建了一个实际的 JPEG 文件。
  • 感谢您接回丢失的autorelease,Peter,我从 GC 项目中的一个类别中复制了该行,因此在我的情况下没有必要。
【解决方案2】:
#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

【讨论】:

    猜你喜欢
    • 2011-08-09
    • 2021-07-28
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2021-12-18
    • 2019-10-24
    相关资源
    最近更新 更多