在Objective-c / cocoa(OSX)中有没有办法在不改变图像质量的情况下裁剪图像?
我非常接近解决方案,但仍然存在一些我可以在颜色中检测到的差异。放大文字时我会注意到它。这是我目前使用的代码:
NSImage *target = [[[NSImage alloc]initWithSize:panelRect.size] autorelease];
target.backgroundColor = [NSColor greenColor];
//start drawing on target
[target lockFocus];
[NSGraphicsContext saveGraphicsState];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationNone];
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
//draw the portion of the source image on target image
[source drawInRect:NSMakeRect(0,0,panelRect.size.width,panelRect.size.height)
fromRect:NSMakeRect(panelRect.origin.x , source.size.height - panelRect.origin.y - panelRect.size.height, panelRect.size.width, panelRect.size.height)
operation:NSCompositeCopy
fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
//end drawing
[target unlockFocus];
//create a NSBitmapImageRep
NSBitmapImageRep *bmpImageRep = [[[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]] autorelease];
//add the NSBitmapImage to the representation list of the target
[target addRepresentation:bmpImageRep];
//get the data from the representation
NSData *data = [bmpImageRep representationUsingType: NSJPEGFileType
properties: imageProps];
NSString *filename = [NSString stringWithFormat:@"%@%@.jpg", panelImagePrefix, panelNumber];
NSLog(@"This is the filename: %@", filename);
//write the data to a file
[data writeToFile:filename atomically:NO];
以下是原始图像和裁剪图像的放大比较:
(原始图片 - 上图)
(裁剪图像 - 上图)
区别很难看,但如果你在它们之间轻弹,你会发现它。您也可以使用颜色选择器来注意差异。例如,图像底行的最暗像素是不同的阴影。
我还有一个解决方案,完全按照我想要的方式在iOS中运行。这是代码:
-(void)testMethod:(int)page forRect:(CGRect)rect{
NSString *filePath = @"imageName";
NSData *data = [HeavyResourceManager dataForPath:filePath];//this just gets the image as NSData
UIImage *image = [UIImage imageWithData:data];
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);//crop in the rect
UIImage *result = [UIImage imageWithCGImage:imageRef scale:0 orientation:image.imageOrientation];
CGImageRelease(imageRef);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
[UIImageJPEGRepresentation(result, 1.0) writeToFile:[documentsDirectoryPath stringByAppendingPathComponent::@"output.jpg"] atomically:YES];
}
那么,有没有办法在OSX中裁剪图像,以便裁剪的图像根本不会改变?也许我必须调查一个不同的库,但如果我不能用Objective-C做到这一点我会感到惊讶......
注意,这是我之前提问here的后续问题。
更新我已尝试(根据suggestion)将CGRect值舍入为整数,但没有发现差异。以下是我使用的代码:
[source drawInRect:NSMakeRect(0,0,(int)panelRect.size.width,(int)panelRect.size.height)
fromRect:NSMakeRect((int)panelRect.origin.x , (int)(source.size.height - panelRect.origin.y - panelRect.size.height), (int)panelRect.size.width, (int)panelRect.size.height)
operation:NSCompositeCopy
fraction:1.0];
更新我已经尝试了mazzaroth code,如果我将其保存为png,它会有效,但如果我尝试将其保存为jpeg,则图像会失去质量。如此接近,但还不够近。仍然希望得到一个完整的答案...
答案 0 :(得分:11)
使用CGImageCreateWithImageInRect。
// this chunk of code loads a jpeg image into a cgimage
// creates a second crop of the original image with CGImageCreateWithImageInRect
// writes the new cropped image to the desktop
// ensure that the xy origin of the CGRectMake call is smaller than the width or height of the original image
NSURL *originalImage = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"lockwood" ofType:@"jpg"]];
CGImageRef imageRef = NULL;
CGImageSourceRef loadRef = CGImageSourceCreateWithURL((CFURLRef)originalImage, NULL);
if (loadRef != NULL)
{
imageRef = CGImageSourceCreateImageAtIndex(loadRef, 0, NULL);
CFRelease(loadRef); // Release CGImageSource reference
}
CGImageRef croppedImage = CGImageCreateWithImageInRect(imageRef, CGRectMake(200., 200., 100., 100.));
CFURLRef saveUrl = (CFURLRef)[NSURL fileURLWithPath:[@"~/Desktop/lockwood-crop.jpg" stringByExpandingTildeInPath]];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(saveUrl, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImage(destination, croppedImage, nil);
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to write image to %@", saveUrl);
}
CFRelease(destination);
CFRelease(imageRef);
CFRelease(croppedImage);
我也有一个要点:
答案 1 :(得分:3)
尝试将drawInRect设置为0.5,0.5。否则,Quartz会将每个像素颜色分配到相邻的4个固定点。
设置目标图像的色彩空间。您可能有不同的颜色空间导致看起来略有不同。
尝试各种渲染意图,看看哪种效果最好,感知与相对比色等等。我认为有4种选择。
您提到通过保存JPEG与PNG来修改颜色。
您可以在保存为JPEG时指定压缩级别。尝试使用0.8或0.9之类的东西。您也可以使用1.0保存JPEG而无需压缩,但PNG具有明显的优势。您可以在CGImageDesinationAddImage的选项字典中指定压缩级别。
最后 - 如果她没有帮助 - 你应该用DTS打开TSI,他们当然可以为你提供你所寻求的指导。
答案 2 :(得分:1)
通常的问题是裁剪尺寸是浮动的,但图像像素是整数。 cocoa自动插值。
你需要对尺寸和坐标进行平整,圆化或细化,以确保它们是整数。
这可能有所帮助。
答案 3 :(得分:0)
我正在EXIF删除JPG文件,我想我抓住了原因:
所有损失和更改都来自保存到文件期间图像的重新压缩。
如果您只想再次保存整个图像,也可能会注意到更改。 我要做的是阅读原始JPG并将其重新压缩到质量相当的文件大小。