我有一個1600x1600 1.2MB的圖像,調整到320x320縮小到404KB。 我需要更進一步,減少字節大小而不減少圖像方面的大小。用Cocoa減少圖像字節大小
當前我使用 - TIFFRepresentationUsingCompression:factor:
NSImage方法NSTIFFCompressionJPEG
以及似乎不影響圖像尺寸/質量的因素。
我該如何解決?
馬爾科
我有一個1600x1600 1.2MB的圖像,調整到320x320縮小到404KB。 我需要更進一步,減少字節大小而不減少圖像方面的大小。用Cocoa減少圖像字節大小
當前我使用 - TIFFRepresentationUsingCompression:factor:
NSImage方法NSTIFFCompressionJPEG
以及似乎不影響圖像尺寸/質量的因素。
我該如何解決?
馬爾科
如果你需要壓縮和你不介意丟失的圖像質量然後將該文件保存爲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:method? – Marco 2010-02-22 22:23:49
否。該方法創建一個具有內部JPEG壓縮的TIFF文件。但是,文檔聲明「不支持TIFF文件中的JPEG壓縮,並且忽略因素。」我的代碼創建了一個實際的JPEG文件。 – 2010-02-22 22:28:43
感謝您提取缺少的'autorelease',彼得,我從GC項目中的一個類別中複製了該行,所以在我的情況下沒有必要。 – 2010-02-24 05:07:25
#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
你說的是降低內存或磁盤上的圖像的大小? – 2010-02-22 21:40:44
在磁盤上。 1.2MB和404KB是磁盤大小 – Marco 2010-02-22 22:05:17