在 CALayer 中绘制的 UIImage 太模糊

发布于 2024-10-01 08:51:56 字数 832 浏览 0 评论 0原文

我在获取在 CALayer 内绘制的 UIImage 时遇到一些问题,使其显示得不模糊。我将 400x300px 图像放入 123x89 CALayer 中。这个规模应该意味着生成的 CALayer 相对尖锐,但事实并非如此。

这是我用来绘制 UIImage 的代码:

    CGSize s = image.size;
    CGRect r = CGRectInset (bounds, 8, 8);
    CGFloat scale = MIN (r.size.width / s.width, r.size.height / s.height);
    s.width *= scale; s.height *= scale;
    r.origin.x += (r.size.width - s.width) * .5;
    r.size.width = s.width;
    r.origin.y += (r.size.height - s.height) * .5;
    r.size.height = s.height;

    CGContextSaveGState (ctx);
    CGContextTranslateCTM (ctx, 0, bounds.size.height);
    CGContextScaleCTM (ctx, 1, -1);

    if (image != nil) {
        CGContextDrawImage (ctx, r, image.CGImage);
    }

    CGContextRestoreGState (ctx);

如果您遇到了同样的问题或知道此问题的解决方案,我们将不胜感激。

谢谢,

约书亚·李·塔克。

I'm having some issues getting a UIImage I draw inside a CALayer to show up without it's blurriness. I'm placing a 400x300px image into a 123x89 CALayer. The scale of this should mean that the resulting CALayer is relatively sharp, but it isn't.

This is the code I'm using to draw my UIImage:

    CGSize s = image.size;
    CGRect r = CGRectInset (bounds, 8, 8);
    CGFloat scale = MIN (r.size.width / s.width, r.size.height / s.height);
    s.width *= scale; s.height *= scale;
    r.origin.x += (r.size.width - s.width) * .5;
    r.size.width = s.width;
    r.origin.y += (r.size.height - s.height) * .5;
    r.size.height = s.height;

    CGContextSaveGState (ctx);
    CGContextTranslateCTM (ctx, 0, bounds.size.height);
    CGContextScaleCTM (ctx, 1, -1);

    if (image != nil) {
        CGContextDrawImage (ctx, r, image.CGImage);
    }

    CGContextRestoreGState (ctx);

If you've ran into the same problem or know of a solution to this problem, any help would be appreciated.

Thanks,

Joshua Lee Tucker.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

与往事干杯 2024-10-08 08:51:56

为什么不直接将 CALayer 内容属性设置为 CGImageRef 并使用contentsGravity 属性来定义缩放?您可以通过 CALayer 框架或边界控制大小。

myLayer.contentsGravity = kCAGravityResizeAspect;
myLayer.contents = (id) [myImage CGImage];

Why not just set the CALayer contents property to the CGImageRef and use the contentsGravity property to define the scaling? You can control the size through the CALayer frame or bounds.

myLayer.contentsGravity = kCAGravityResizeAspect;
myLayer.contents = (id) [myImage CGImage];
柠栀 2024-10-08 08:51:56

不要忘记在 CALayer 上设置 contentScale 值,否则您可能会发现 CGImage 在视图边界之外拉伸到视网膜设备上正常大小的 2 倍。由于某种原因,CALayers 上的默认比例始终为 1.0,即使在 Retina 设备上也是如此。

另外

layer.contentsScale = [UIScreen mainScreen].scale;

,如果您使用 CAShapeLayer 绘制形状,并且想知道其边缘在视网膜设备上看起来有点锯齿状,请尝试:

shapeLayer.rasterizationScale = [UIScreen mainScreen].scale;
shapeLayer.shouldRasterize = YES;

Don't forget to set the contentsScale value on the CALayer or you may find the CGImage stretched outside the bounds of the view to 2 times normal size on retina devices. For some reason, the default scale on CALayers is always 1.0, even on Retina devices.

i.e.

layer.contentsScale = [UIScreen mainScreen].scale;

Also, if you're drawing a shape using CAShapeLayer and wondering its edges look a little jagged on retina devices, try:

shapeLayer.rasterizationScale = [UIScreen mainScreen].scale;
shapeLayer.shouldRasterize = YES;
沧笙踏歌 2024-10-08 08:51:56

我预计它会被扭曲。

首先,这些数字并不是均匀分布的。

其次,源尺寸和目标尺寸的纵横比不同,因此会出现一点拉伸/收缩。

如果您确实需要这样做 - 尝试使其宽高比相同,它们可以均匀划分 - 或者更好 - 您首先将图像渲染为正确的目标尺寸。

I would expect it to be distorted.

First of all, the numbers don't divide into each other evenly.

Second of all, the aspect ratios of the source and destination sizes are different, so there is going to be a little bit of stretching/shrinking that way.

If you really need to do this - try to make it so the aspect ratios are the same, they can be evenly divided - or better yet - you're rendering the images to the correct destination size to begin with.

第七度阳光i 2024-10-08 08:51:56

如果将图像放置在非整数坐标处,或将宽度/高度设置为非整数值,图像往往会看起来模糊。您(可能)在代码中同时执行这两件事。

我认为给出的代码的修复方法是:

CGFloat scale = MIN (r.size.width / s.width, r.size.height / s.height);
s.width = trunc(s.width * scale); 
s.height = trunc(s.height * scale);
r.origin.x += trunc((r.size.width - s.width) * .5);
r.size.width = s.width;
r.origin.y += trunc((r.size.height - s.height) * .5);
r.size.height = s.height;

Images will tend to look fuzzy if you either place them at non-integer coordinates, or set the width/height to a non-integer value. You are (potentially) doing both things in your code.

I think the fix for the code given would be:

CGFloat scale = MIN (r.size.width / s.width, r.size.height / s.height);
s.width = trunc(s.width * scale); 
s.height = trunc(s.height * scale);
r.origin.x += trunc((r.size.width - s.width) * .5);
r.size.width = s.width;
r.origin.y += trunc((r.size.height - s.height) * .5);
r.size.height = s.height;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文