核心图形支持视网膜显示屏

30

我使用以下代码对加载的图像进行一些操作,但是发现在Retina屏幕上显示时变得模糊了

- (UIImage*)createImageSection:(UIImage*)image section:(CGRect)section

{
float originalWidth = image.size.width ;
float originalHeight = image.size.height ;
int w = originalWidth * section.size.width;
int h = originalHeight * section.size.height;

CGContextRef ctx = CGBitmapContextCreate(nil, w, h, 8, w * 8,CGImageGetColorSpace([image CGImage]), kCGImageAlphaPremultipliedLast);
CGContextClearRect(ctx, CGRectMake(0, 0, originalWidth * section.size.width, originalHeight * section.size.height)); // w + h before
CGContextTranslateCTM(ctx, (float)-originalWidth * section.origin.x, (float)-originalHeight * section.origin.y);
CGContextDrawImage(ctx, CGRectMake(0, 0, originalWidth, originalHeight), [image CGImage]);
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
UIImage* resultImage = [[UIImage alloc] initWithCGImage:cgImage];

CGContextRelease(ctx);
CGImageRelease(cgImage);

return resultImage;
}

如何更改此内容以使其支持Retina显示屏。

感谢您的帮助。

最好的祝福, DV

3个回答

48

CGImages不考虑您的设备是否为Retina,因此您需要自己处理。

为了这样做,您需要将使用CoreGraphics例程中的所有坐标和尺寸乘以输入图像的scale属性(在Retina设备上为2.0),以确保您在双倍分辨率下进行所有操作。

然后,您需要更改resultImage的初始化,使用initWithCGImage:scale:orientation:并输入相同的比例因子。这是使Retina设备以本机分辨率而不是像素加倍分辨率呈现输出的方法。


1
如果您通过调用CGContextScaleCTM(UIGraphicsGetCurrentContext(), 2, 2)更改上下文的CTM(当前变换矩阵),则无需手动乘以坐标,您可以像非视网膜图像一样绘制相同的内容。 - epologee
14
抱歉,我之前的评论发得太快了,已经来不及编辑了。如果您按照以下方式进行操作,就无需自己考虑如何缩放所有坐标:CGFloat scale = [[UIScreen mainScreen] scale]; CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale); - epologee
非常正确。伟大的解决方案。 - GoldenJoe
绘制图像的一部分(即子矩形)时,仍需要手动调整比例。 - Hlung

5
感谢您的回答,对我很有帮助!为了更加清晰明确,OP的代码应该更改如下:
- (UIImage*)createImageSection:(UIImage*)image section:(CGRect)section        
{
    CGFloat scale = [[UIScreen mainScreen] scale]; ////// ADD

    float originalWidth = image.size.width ;
    float originalHeight = image.size.height ;
    int w = originalWidth * section.size.width *scale; ////// CHANGE
    int h = originalHeight * section.size.height *scale; ////// CHANGE

    CGContextRef ctx = CGBitmapContextCreate(nil, w, h, 8, w * 8,CGImageGetColorSpace([image CGImage]), kCGImageAlphaPremultipliedLast);
    CGContextClearRect(ctx, CGRectMake(0, 0, originalWidth * section.size.width, originalHeight * section.size.height)); // w + h before
    CGContextTranslateCTM(ctx, (float)-originalWidth * section.origin.x, (float)-originalHeight * section.origin.y);

    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale); ////// ADD

    CGContextDrawImage(ctx, CGRectMake(0, 0, originalWidth, originalHeight), [image CGImage]);
    CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
    UIImage* resultImage = [[UIImage alloc] initWithCGImage:cgImage];

    CGContextRelease(ctx);
    CGImageRelease(cgImage);

    return resultImage;
}

2

Swift版本:

    let scale = UIScreen.mainScreen().scale

    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)

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