【问题标题】:How to avoid quality loss when combining two images via CGBitmapContext in monotouch在monotouch中通过CGBitmapContext组合两个图像时如何避免质量损失
【发布时间】:2012-12-20 17:02:43
【问题描述】:

我有两张图片。第一个 (avatar) 是 640x640,第二个 (like) 是 21x20。 当我试图先画第二个时,我明白了,但质量非常低。 代码如下:

var bounds = targeImageView.Bounds;
CGImageAlphaInfo alphaInfo = CGImageAlphaInfo.PremultipliedLast;
CGColorSpace colorSpaceInfo = CGColorSpace.CreateDeviceRGB ();
CGBitmapContext resultBitmap = new CGBitmapContext (IntPtr.Zero, (int)bounds.Width, (int)bounds.Height, 8, 4 * (int)bounds.Width, colorSpaceInfo, alphaInfo);
resultBitmap.DrawImage (bounds, avatar.CGImage);
var likeY = 0;
var likeX = 0;
var likeHeight = (float)Math.Floor (bounds.Height / 2);
var likeWidth = likeHeight;
resultBitmap.DrawImage (new RectangleF (likeX, likeY, likeWidth, likeHeight), like.CGImage);
targetImageView.Image = UIImage.FromImage (resultBitmap.ToImage ());

这是同一图像视图上的avatar图片,但没有上面的代码,只是imageView.Image = avatar;

这里是相同的,但在绘制之后。

【问题讨论】:

  • 您附加的位图太小,即我看不出它们之间的质量差异。你能把它们放大吗?和/或描述质量问题?例如会不会是第二个没有使用视网膜(代替双像素)?
  • 请仔细看,有区别。即使没有单独打开它,我也可以在那个帖子中看到它。是的,考虑到视网膜,那就是 iphone 视网膜模拟器。
  • @poupou:左图中人物的头发差异最为明显。

标签: iphone ios xamarin.ios core-graphics


【解决方案1】:

你的视力比我好——至少在那么小的尺寸上。如果是视网膜问题(我认为是这样),那么下面的代码应该会对您有所帮助,因为它会创建一个上下文来调整自身以适应视网膜(或不)显示。

UIImage avatar = ...;
UIImage like = ...;
UIGraphics.BeginImageContextWithOptions (avatar.Size, false, 0);
using (CGContext ctx = UIGraphics.GetCurrentContext ()) {
    var rect = new RectangleF (Point.Empty, avatar.Size);
    avatar.Draw (rect);
    // coordinates are likely reversed (UIKit wrt CoreGraphics) you might have to fix them (untried)
    rect = new RectangleF (0, avatar.Height / 2, avatar.Width / 2, avatar.Height / 2);
    like.Draw (rect);

    targetImageView.Image = UIGraphics.GetImageFromCurrentImageContext ();
    UIGraphics.EndImageContext ();
    // dispose of avatar and like UIImage if not used anymore
}

【讨论】:

    【解决方案2】:
    1. 使用 PNG,它们是无损的,质量比 JPG 或位图更好。

      NSData *imageData = UIImagePNGRepresentation(image);

      UIImage *image=[UIImage imageWithData:data];

    2. 使用 CGRectMake () 分配带有框架的 UIImageView 以进行放置。您将能够将图像浮动到任何您想要的位置。

    3. 使用 [ImageView setImage:...] 设置 ImageView 的图像

    4. 图像会变得更加清晰,您可以完全控制质量和位置。

    我使用了一个 256 的图像,压缩到 15px x 15px,它的形状仍然很好。相比之下,我还以相反的方式拉伸图像。

    【讨论】:

    • 提问者正在将一张图像合成到另一张图像上;其中哪一部分与“使用 PNG”相关?至于你的其他三个步骤,它们似乎是关于如何显示图像的建议,但提问者想要合成两个图像。你的建议如何完成提问者的任务?而且,您的建议与提问者的最后一行代码有何不同?
    • @Peter:我对这个问题的理解是使用第一张图像(头像)并添加子图像(笑脸和云),如提供的示例所示,以“渲染”统一的外观到用户。我的建议是将这些分层并为用户提供可以代表任意数量配置的堆叠图像。例如可以控制开/关的徽章或云等,增量数字等。通过实际根深蒂固的图像,新的单个图像被粘在一起。您可以随时循环遍历容器 UIView 并拍摄所有子图像的图像以供以后使用。
    • @Peter 继续...如果应用程序想在头像上使用分层的“云”来表示用户已“连接”,那么在分层透明的高质量 png 时会有更大的灵活性,而不是在位图级别将它们拼接在一起。但是,如果客户端应用程序绝对需要将两个图像整合在一起,那么您是正确的,那么我的回答不支持这种努力。如果是这样,我很抱歉,也许它会帮助别人。
    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2012-06-22
    • 2013-10-16
    • 1970-01-01
    相关资源
    最近更新 更多