【问题标题】:CoreGraphics for retina display用于视网膜显示的 CoreGraphics
【发布时间】:2011-01-16 19:13:38
【问题描述】:

我正在使用以下代码对我加载的图像执行一些操作,但我发现当它在视网膜显示器上时显示变得模糊

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

如何更改它以使其与视网膜兼容。

提前感谢您的帮助

最好, DV

【问题讨论】:

    标签: iphone core-graphics retina-display cg


    【解决方案1】:

    CGImages 不考虑您设备的 Retina-ness,因此您必须自己这样做。

    为此,您需要将 CoreGraphics 例程中使用的所有坐标和大小乘以输入图像的 scale 属性(在 Retina 设备上为 2.0),以确保以双倍分辨率进行所有操作.

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

    【讨论】:

    • 如果您通过调用 CGContextScaleCTM(UIGraphicsGetCurrentContext(), 2, 2) 更改上下文的 CTM(当前变换矩阵),则无需手动乘以坐标,您可以像使用非视网膜图像。
    • 抱歉,评论太快了,编辑太晚了。如果你这样做,你不需要考虑自己缩放所有坐标:CGFloat scale = [[UIScreen mainScreen] scale]; CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale);
    • 是的。很好的解决方案。
    • 如果您只在该图像内绘制一部分(子矩形),仍然必须手动修复比例。
    【解决方案2】:

    感谢您的回答,帮助了我!无论如何,为了更清楚,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;
    }
    

    【讨论】:

      【解决方案3】:

      斯威夫特版本:

          let scale = UIScreen.mainScreen().scale
      
          CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)
      

      【讨论】:

        最近更新 更多