CGContextDrawImage绘制大图像时显示模糊

3

我想制作一个对象,可以使用CGContextDrawImage(...)绘制大图像的一部分(例如2048 x 1537)。它可以正常工作,但是非常模糊。我使用一个“drawingController”,覆盖drawLayer:inContext:如下:

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    CGImageRef drawImage = CGImageRetain(imageToDraw);
    if(drawImage) {
        CGRect drawRect = CGRectMake(0, 0, 1024, 748);//Just hard coded to my window size for now.
        CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);
        CGContextDrawImage(ctx, drawRect, drawImage);
    }
    CGImageRelease(drawImage);
}

这是我设置自定义图像托管视图的方法:
- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"large" ofType:@"jpg"];
        CGImageRef imageRef = [self createCGImageFromFilePath:filePath];


        drawingController = [[DrawingLayerController alloc] init];
        drawingController.imageToDraw = imageRef;

        [self setWantsLayer:YES];
        imageLayer = [[CALayer alloc] init];
        imageLayer.frame = self.bounds;
        imageLayer.drawsAsynchronously = YES;
        imageLayer.delegate = drawingController;
        [self.layer addSublayer:imageLayer];

        imageLayer.contentsRect = CGRectMake(0.5, 0.265452179, 0.5, 0.486662329); //Just an example contents rect.
        imageLayer.drawsAsynchronously = YES;

        [imageLayer setNeedsDisplay];
        [imageLayer displayIfNeeded];
    }
    return self;
}

这是一张与源图像在相似缩放比例下在预览中打开的图像部分,以便您可以看到与源图像相比图像有多模糊。
请看下面的图片,我的代码生成的图像看起来非常糟糕。这是怎么回事?
另外,为了完整起见,我尝试使用CATiledLayer来制作我的图像层,但生成的图像看起来同样糟糕。
最后一点说明:该代码需要与iOS和OSX兼容,但我正在OSX上进行所有测试。
编辑:感谢@Andrea,我已经在CGContextDrawImage(…)上方添加了以下内容。
CGFloat scale = MAX(1,MAX(CGImageGetWidth(drawImage)/drawRect.size.width,CGImageGetHeight(drawImage)/drawRect.size.height));

layer.contentsScale = scale;

请尝试将CALayer.contentsScale设置为[UIScreen mainScreen].scale。 - yurish
1
@yurish:UIScreen在OS X上不可用。 - Peter Hosey
1个回答

0

我不确定对于OSX,但我可以给你一些建议。

  • 检查contentScale属性,如评论中所述,我也写了一个问题,但我从未得到真正的答案
  • 大多数情况下,模糊是由于像素不匹配造成的,这要求系统在图像上应用抗锯齿技术,我看到你设置了一个contentsRect,这个与contentsGravity一起使用,可能会改变图像的比例和缩放,使其变成模糊的。这里有一个很好的答案
  • 你的contentGravity是什么?
  • 在第一次尝试中保持简单,你真的需要异步绘制吗?

希望这能帮到你。


2
contentScale为2.0确实会使图像变得更清晰。但我完全不知道该如何解释这一点。为什么我需要使用contentScale为2.0?我直接从文件中加载图像到CGImageRef中,因此没有NSImage @2x的魔法发生,并且我正在非Retina屏幕上绘制。 - Kelly Bennett
嗨@RagnarDanneskjöld,原始图像的分辨率是多少? - Andrea
嗨,@RagnarDanneskjöld,图像的分辨率更大(两倍),因此需要在较小的空间中重新绘制图层,所以你可能需要在绘制时设置一些选项。你试过使用CGContextSetShouldAntialias(ctx, true); CGContextSetAllowsAntialiasing(ctx, true);吗?我之前遇到类似的问题,并通过在图层上直接设置minificationFilter为kCAFilterTrilinear来解决,但我是直接将图像作为图层的内容进行设置。 - Andrea
图像分辨率为2048 x 1537。“图像的分辨率更高”——比什么更高,我的图层吗?我不明白。该图像比我的图层大得多,但将内容比例设置为2使图像与将其设置为5一样清晰(据我所知)。此外,抗锯齿等处理没有任何效果。 - Kelly Bennett
CGRect drawRect = CGRectMake(0, 0, 1024, 748); - Andrea
哦,我明白你的意思了。2048 x 1537大约是我的drawRect的两倍大小。 - Kelly Bennett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接