用于视网膜显示的 CoreGraphics
Posted
技术标签:
【中文标题】用于视网膜显示的 CoreGraphics【英文标题】:CoreGraphics for retina display 【发布时间】: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
【问题讨论】:
【参考方案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)
【讨论】:
以上是关于用于视网膜显示的 CoreGraphics的主要内容,如果未能解决你的问题,请参考以下文章