【问题标题】:Thin white lines being added when cropping an image (Objective-C OSX)裁剪图像时添加细白线(Objective-C OSX)
【发布时间】:2012-11-17 03:47:16
【问题描述】:

我正在剪切一个大图像并将其保存到许多不同的图像中。我首先在iOS 中实现了它,它工作正常,但是当我尝试将代码移植到OSX 时,图像的顶部和右侧出现一条细白线(1 像素)。这条线不是纯白色的,也不是实心的(参见下面的示例)。

这是制作一个子图像的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 中的移植代码,它会导致添加白线:

NSImage *source = [[[NSImage alloc]initWithContentsOfFile:imagePath] autorelease];
//init the image
NSImage *target = [[[NSImage alloc]initWithSize:panelRect.size] autorelease];
//start drawing
[target lockFocus];
[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];
[target unlockFocus];

//create a NSBitmapImageRep
NSBitmapImageRep *bmpImageRep = [[[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]] autorelease];
//write to tiff
[[target TIFFRepresentation] writeToFile:@"outputImage.tiff" atomically:NO];
[target addRepresentation:bmpImageRep];     
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];

//get the data from the representation
NSData *data = [bmpImageRep representationUsingType: NSJPEGFileType
                                             properties: imageProps];

//write the data to a file
[data writeToFile: @"outputImage.jpg" atomically:NO];

data = [bmpImageRep representationUsingType: NSPNGFileType properties: imageProps];

//write the data to png
[data writeToFile: @"outputImage.png" atomically:NO];

以上代码将图片保存为三种不同的格式,以检查问题是否出在特定格式的保存过程中。似乎不是因为所有格式都有相同的问题。

这是图片右上角的放大 (4x) 版本:

(OSX,注意左上角的白线。这里看起来很模糊,因为图像被放大了)


(iOS,注意没有白线)

如果有人能告诉我为什么会发生这种情况,我会非常高兴。也许它与质量差异有关(OSX 版本似乎质量较低 - 尽管您没有注意到)?也许有完全不同的方法可以做到这一点?

作为参考,这里是未缩放的 osx 图像:


更新:感谢Daij-Djan,我能够阻止drawInRect 方法的抗锯齿:

    //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:NSCompositeDestinationAtop
              fraction:1.0];

    [NSGraphicsContext restoreGraphicsState];
    //end drawing
    [target unlockFocus];

更新:将“插值”更改为 NSImageInterpolationNone,因为这样可以提供更好的表示。高插值进行细微调整,这在放大文本时很明显。移除插值会阻止像素跳动,但颜色仍有少许差异(灰色为 164 到 155)。能够像在 iOS 中那样剪切图像会很棒...

【问题讨论】:

    标签: objective-c macos crop nsimage


    【解决方案1】:

    它看起来像抗锯齿...您必须在切割/缩放图像时将计算的浮点值四舍五入。

    对浮点值使用 froundf()

    【讨论】:

    • ++++1 - 这是抗锯齿!谢谢!
    • 注意:我刚刚停止做抗锯齿(参见上面的问题编辑)。
    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2012-11-26
    相关资源
    最近更新 更多