CILanczosScaleTransform 后出现奇怪的现象
我正在尝试使用 Core Image 和 Lanczos Scale Transform 过滤器进行图像缩放。 当我进行放大时,这很好。但在缩小并保存为 JPEG 时,我发现一类图像会产生奇怪的噪声伪影和行为。
对于 inputScale 倍数为 0.5:0.5、0.25、0.125 等,总是没问题的。 对于其他 inputScale 值,它已损坏。
当我保存为 TIFF、PNG、JPEG2000 或在屏幕上绘图时 - 没问题。 当我保存为 JPG 或 BMP 时 - 它损坏了。
我上传了示例图片: (原始,4272x2848,3.4Mb) [http://www.zoomfoot.com/get/ package/517e2423-7795-4239-a166-03d507ec51d8]
(按噪声缩放,1920x1280,2.2Mb) [http://www.zoomfoot.com/get/ package/6eb64d33-3a30-4e8d-9953-67ce1e7d7ef9]
它也可以很好地在“日落”图像上重现。
我尝试了更多缩放图像的方法。使用 CIAffineTransform 并使用 NSImage 本身进行绘图。两者都提供没有任何噪音的结果。
这是我用于缩放的代码节省:
================= 兰佐斯 ==============
- (NSImage *) scaleLanczosImage:(NSString *)path
Width:(int) desiredWidth
Height:(int) desiredHeight
{
CIImage *image=[CIImage imageWithContentsOfURL:
[NSURL fileURLWithPath:path]];
CIFilter *scaleFilter = [CIFilter filterWithName:@"CILanczosScaleTransform"];
int originalHeight=[图像范围].size.height;
int originalWidth=[图像范围].size.width;
浮点 yScale=(浮点)desiredHeight / (浮点)originalHeight;
浮点数 xScale=(浮点数)desiredWidth / (float)originalWidth;
浮点数=fminf(yScale, xScale);
[scaleFilter setValue:[NSNumber numberWithFloat:scale]
forKey:@"inputScale"];
[scaleFilter setValue:[NSNumber numberWithFloat:1.0]
forKey:@"inputAspectRatio"];
[scaleFilter setValue: 图像
forKey:@"inputImage"];
图像 = [scaleFilter valueForKey:@"outputImage"];
NSBitmapImageRep*rep = [[NSBitmapImageRep alloc] initWithCIImage:image];
NSMutableDictionary *options=[NSMutableDictionarydictionaryWithObject:[NSDecimalNumber numberWithFloat:1.0]
forKey:NSImageCompressionFactor];
[选项 setValue:[NSNumber numberWithBool:YES] forKey:NSImageProgressive];
NSData* jpegData = [代表representationUsingType:NSJPEGFileType
属性:选项];
[jpegData writeToFile:@"/Users/dmitry/tmp/img_4389-800x600.jpg" 原子地:是];
}
================= NSImage ==============
- (void) scaleNSImage:(NSString *)path
Width:(int) desiredWidth
Height:(int) desiredHeight
{
NSImage *sourceImage = [[NSImage alloc] initWithContentsOfFile:path];
NSImage *resizedImage = [[NSImage alloc] initWithSize:
NSMakeSize(desiredWidth, desiredHeight)];
NSSize 原始大小 = [源图像大小];
[调整大小的图像锁定焦点];
[源图像drawInRect: NSMakeRect(0, 0,desiredWidth,desiredHeight)
fromRect: NSMakeRect(0, 0, 原始尺寸.宽度, 原始尺寸.高度)
操作:NSCompositeSourceOver 分数:1.0];
[调整大小的图像解锁焦点];
NSMutableDictionary *options=[NSMutableDictionarydictionaryWithObject:[NSDecimalNumber numberWithFloat:1.0]
forKey:NSImageCompressionFactor];
[选项 setValue:[NSNumber numberWithBool:YES] forKey:NSImageProgressive];
NSBitmapImageRep *rep = [[NSBitmapImageRep 分配]
initWithData:[resizedImage TIFFRepresentation]];
NSData* jpegData = [代表representationUsingType:NSJPEGFileType
属性:选项];
[jpegData writeToFile:@"~/nsimg_4389-800x600.jpg" 原子地:是];
}
如果有人可以在这里解释或提出一些建议,我真的很感激。
谢谢。
I'm trying to do image scaling using Core Image, using Lanczos Scale Transform filter.
It is fine when I'm doing scaleup. But on scaledown and saving to JPEG I found a class of images which produces strange noise artifacts and behavior.
For inputScale multiples to 0.5: 0.5, 0.25, 0.125 etc it is always fine.
For others inputScale values,it's broken.
When I'm saving to TIFF,PNG,JPEG2000 or draw on screen - it's fine.
When I'm saving to JPG or BMP - it's broken.
I uploaded sample images:
(original, 4272x2848, 3.4Mb)
[http://www.zoomfoot.com/get/package/517e2423-7795-4239-a166-03d507ec51d8]
(scaled with noise, 1920x1280, 2.2Mb)
[http://www.zoomfoot.com/get/package/6eb64d33-3a30-4e8d-9953-67ce1e7d7ef9]
It also, pretty good reproducible on 'sunset' images.
I've tried couple more ways to scale images. Using CIAffineTransform and drawing using NSImage itself. Both provides results without any noise.
Here is the code I was using for scaling & saving:
================= Lanczos ==============
- (NSImage *) scaleLanczosImage:(NSString *)path
Width:(int) desiredWidth
Height:(int) desiredHeight
{
CIImage *image=[CIImage imageWithContentsOfURL:
[NSURL fileURLWithPath:path]];
CIFilter *scaleFilter = [CIFilter filterWithName:@"CILanczosScaleTransform"];
int originalHeight=[image extent].size.height;
int originalWidth=[image extent].size.width;
float yScale=(float)desiredHeight / (float)originalHeight;
float xScale=(float)desiredWidth / (float)originalWidth;
float scale=fminf(yScale, xScale);
[scaleFilter setValue:[NSNumber numberWithFloat:scale]
forKey:@"inputScale"];
[scaleFilter setValue:[NSNumber numberWithFloat:1.0]
forKey:@"inputAspectRatio"];
[scaleFilter setValue: image
forKey:@"inputImage"];
image = [scaleFilter valueForKey:@"outputImage"];
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCIImage:image];
NSMutableDictionary *options=[NSMutableDictionary dictionaryWithObject:[NSDecimalNumber numberWithFloat:1.0]
forKey:NSImageCompressionFactor];
[options setValue:[NSNumber numberWithBool:YES] forKey:NSImageProgressive];
NSData* jpegData = [rep representationUsingType:NSJPEGFileType
properties:options];
[jpegData writeToFile:@"/Users/dmitry/tmp/img_4389-800x600.jpg" atomically:YES];
}
================= NSImage ==============
- (void) scaleNSImage:(NSString *)path
Width:(int) desiredWidth
Height:(int) desiredHeight
{
NSImage *sourceImage = [[NSImage alloc] initWithContentsOfFile:path];
NSImage *resizedImage = [[NSImage alloc] initWithSize:
NSMakeSize(desiredWidth, desiredHeight)];
NSSize originalSize = [sourceImage size];
[resizedImage lockFocus];
[sourceImage drawInRect: NSMakeRect(0, 0, desiredWidth, desiredHeight)
fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height)
operation: NSCompositeSourceOver fraction: 1.0];
[resizedImage unlockFocus];
NSMutableDictionary *options=[NSMutableDictionary dictionaryWithObject:[NSDecimalNumber numberWithFloat:1.0]
forKey:NSImageCompressionFactor];
[options setValue:[NSNumber numberWithBool:YES] forKey:NSImageProgressive];
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
initWithData:[resizedImage TIFFRepresentation]];
NSData* jpegData = [rep representationUsingType:NSJPEGFileType
properties:options];
[jpegData writeToFile:@"~/nsimg_4389-800x600.jpg" atomically:YES];
}
If anyone can explain or suggest something here, i'm really appreciate this.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 CIImage 进行缩放有一些怪癖。 Dan Wood 的这篇文章会有帮助吗?
There are some quirks with scaling with CIImage. Will this post by Dan Wood help?
我的理解是,由于其性质,硬件 Core Image 渲染器在渲染除屏幕显示之外的任何内容时都会出现一些奇怪的现象。因此,其他情况建议您使用软件渲染器。
http://developer.apple.com/mac/library/qa/ qa2005/qa1416.html
My understanding is that due to its nature, the hardware Core Image renderer has some odd quirks when rendering for anything but on-screen display. So, you are recommended to use the software renderer for other situations.
http://developer.apple.com/mac/library/qa/qa2005/qa1416.html
这绝对是 CoreImage 的错误。将其提交至 bugreport.apple.com
That's definitely a CoreImage bug. File it at bugreport.apple.com