CGContextDrawImage draws large images very blurry

北战南征 提交于 2019-12-21 20:15:39

问题


I'm trying to make an object that can draw a portion of a large (say 2048 x 1537) image using CGContextDrawImage(…). It works just fine, except that it is extremely blurry. I'm using a "drawingController" which overrides drawLayer:inContext: like this

-(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);
}

And this is how I set up my custom image hosting view:

- (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;
}

Here is a portion of the image produced along side the source image at a similar zoom scale opened in Preview, so you can see just how blurry the image is as compared to the source image.

As you can see, the image produced by my code looks HORRIBLE. What is up with that?

Also, just for completeness, I have tried using a CATiledLayer for my imageLayer. The resulting image looks just as awful.

One final note: The code needs to be compatible with iOS AND OSX, but I am doing all my testing on OSX.

EDIT: Thanks to @Andrea, I've added the following above CGContextDrawImage(…)

CGFloat scale = MAX(1,MAX(CGImageGetWidth(drawImage)/drawRect.size.width,CGImageGetHeight(drawImage)/drawRect.size.height));

layer.contentsScale = scale;

回答1:


I don't know exactly for osx but I can give you some advices.

  • Check the contentScale property as stated in commets, I wrote also a question about it, but I never had a real answer
  • Most of time blurriness is due to unmatching pixel, this asks to the system to apply antialiasing on the image, I see that you set a contentsRect this, with the contentsGravity, probably could change proportion and scaling of the image turning it into a blur one. Here a good answer about it.
  • Which is your contentGravity?
  • Keep it simple in first try, do you really need to draw async?

Hope this helps.



来源:https://stackoverflow.com/questions/20509203/cgcontextdrawimage-draws-large-images-very-blurry

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!