我有一个Cocoa Mac图像编辑应用程序,可让用户导出JPEG图像。我目前正在使用以下代码将这些图像导出为JPEG文件:
//this is user specified
NSInteger resolution;
NSImage* savedImage = [[NSImage alloc] initWithSize:NSMakeSize(600, 600)];
[savedImage lockFocus];
//draw here
[savedImage unlockFocus];
NSBitmapImageRep* savedImageBitmapRep = [NSBitmapImageRep imageRepWithData:[savedImage TIFFRepresentationUsingCompression:NSTIFFCompressionNone factor:1.0]];
NSDictionary* properties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:1.0], NSImageCompressionFactor, nil];
//holds the jpeg file
NSData * imageData = nil;
imageData = [savedImageBitmapRep representationUsingType:NSJPEGFileType properties:properties];
但是,我希望用户能够为此JPEG图像提供每英寸像素(就像在Photoshop的导出选项中一样)。我需要在上面的代码中修改哪些内容来为导出的JPEG调整此值?
答案 0 :(得分:3)
对于NSImage
或NSImageRep
,您不直接设置分辨率,而是设置大小。
对于size,numberOfPixels和分辨率,以下等式成立:
size = numberOfPixels * 72.0 / resolution
size
是一个长度,用单位inch/72
表示。
(size
和resolution
是浮点数)。您可以看到,对于dpi = 72大小的图像,numberOfPixels的数字相同(但含义非常不同)。
创建NSBitmapImageRep
后,可以设置所需分辨率的大小:
NSBitmapImageRep* savedImageBitmapRep = . . . ; // create the new rep
NSSize newSize;
newSize.width = [savedImageBitmapRep pixelsWide] * 72.0 / resolution; // x-resolution
newSize.height = [savedImageBitmapRep pixelsHigh] * 72.0 / resolution; // y-resolution
[savedImageBitmapRep setSize:newSize];
// save the rep
两个评论:你真的需要lockFocus / unlockFocus方式吗?构建新NSBitmapImageRep的首选方法是使用NSGraphicsContext
。见:http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg74857.html
并且:TIFFRepresentation
使用NSBitmapImageRep
非常节省时间和空间。另有10.6
方式存在并且不需要任何费用,因为lockFocus和unlockFocus创建了一个类NSCGImageSnapshotRep
的对象,它在引擎盖下是一个CGImage。 (在10.6之前的操作系统版本中,它是NSCachedImageRep
。)以下是:
[anImage lockFocus];
// draw something
[anImage unlockFocus];
// now anImage contains an NSCGImageSnapshotRep
CGImageRef cg = [anImage CGImageForProposedRect:NULL context:nil hints:nil];
NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cg];
// set the resolution
// here you may NSLog anImage, cg and newRep
// save the newRep
// release the newRep if needed
答案 1 :(得分:2)
我找不到使用NSImage API的方法,但CGImage可以通过设置kCGImagePropertyDPIHeight / Width来实现。
我还设置了kCGImageDestinationLossyCompressionQuality,我认为它与NSImageCompressionFactor相同。
//this is user specified
NSInteger resolution = 100;
NSImage* savedImage = [[NSImage alloc] initWithSize:NSMakeSize(600, 600)];
[savedImage lockFocus];
//draw here
[savedImage unlockFocus];
NSBitmapImageRep* savedImageBitmapRep = [NSBitmapImageRep imageRepWithData:[savedImage TIFFRepresentationUsingCompression:NSTIFFCompressionNone factor:1.0]];
NSDictionary* properties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:1.0], kCGImageDestinationLossyCompressionQuality,
[NSNumber numberWithInteger:resolution], kCGImagePropertyDPIHeight,
[NSNumber numberWithInteger:resolution], kCGImagePropertyDPIWidth,
nil];
NSMutableData* imageData = [NSMutableData data];
CGImageDestinationRef imageDest = CGImageDestinationCreateWithData((CFMutableDataRef) imageData, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImage(imageDest, [savedImageBitmapRep CGImage], (CFDictionaryRef) properties);
CGImageDestinationFinalize(imageDest);
// Do something with imageData
if (![imageData writeToFile:[@"~/Desktop/test.jpg" stringByExpandingTildeInPath] atomically:NO])
NSLog(@"Failed to write imageData");