对 UIImage 进行像素化会返回具有不同大小的 UIImage

Posted

技术标签:

【中文标题】对 UIImage 进行像素化会返回具有不同大小的 UIImage【英文标题】:Pixellating a UIImage returns UIImage with a different size 【发布时间】:2017-05-22 03:58:15 【问题描述】:

我正在使用扩展程序对我的图像进行像素化,如下所示:

func pixellated(scale: Int = 8) -> UIImage? 
    guard let ciImage = CIImage(image: self), let filter = CIFilter(name: "CIPixellate") else  return nil 
    filter.setValue(ciImage, forKey: kCIInputImageKey)
    filter.setValue(scale, forKey: kCIInputScaleKey)

    guard let output = filter.outputImage else  return nil 

    return UIImage(ciImage: output)

问题是这里self 表示的图像与我使用UIImage(ciImage: output) 创建的图像大小不同。

例如,使用该代码:

print("image.size BEFORE : \(image.size)")
if let imagePixellated = image.pixellated(scale: 48) 
    image = imagePixellated
    print("image.size AFTER : \(image.size)")

将打印:

image.size BEFORE : (400.0, 298.0)
image.size AFTER : (848.0, 644.0)

大小不一样,比例也不一样。

知道为什么吗?

编辑:

我在扩展中添加了一些打印如下:

func pixellated(scale: Int = 8) -> UIImage? 
    guard let ciImage = CIImage(image: self), let filter = CIFilter(name: "CIPixellate") else  return nil 

    print("UIIMAGE : \(self.size)")
    print("ciImage.extent.size : \(ciImage.extent.size)")

    filter.setValue(ciImage, forKey: kCIInputImageKey)
    filter.setValue(scale, forKey: kCIInputScaleKey)

    guard let output = filter.outputImage else  return nil 

    print("output : \(output.extent.size)")

    return UIImage(ciImage: output)

以下是输出:

UIIMAGE : (250.0, 166.5)
ciImage.extent.size : (500.0, 333.0)
output : (548.0, 381.0)

【问题讨论】:

ciImageextent 在创建之后是什么?我怀疑这个问题可能与selfscale 有关。 @ravron 我更新了问题并在扩展中添加了一些打印。起初看起来像一个比例是的但无法弄清楚为什么output是这样的(比例不一样) 【参考方案1】:

你有两个问题:

    self.size 以点为单位。 self 的像素大小实际上是 self.size 乘以 self.scaleCIPixellate 过滤器更改其图像的边界。

要解决问题一,您可以简单地将返回的UIImagescale 属性设置为与self.scale 相同:

return UIImage(ciImage: output, scale: self.scale, orientation: imageOrientation)

但是您会发现这仍然不太正确。那是因为问题二。对于问题二,最简单的解决方案是裁剪输出CIImage

// Must use self.scale, to disambiguate from the scale parameter
let floatScale = CGFloat(self.scale)
let pixelSize = CGSize(width: size.width * floatScale, height: size.height * floatScale)
let cropRect = CGRect(origin: CGPoint.zero, size: pixelSize)
guard let output = filter.outputImage?.cropping(to: cropRect) else  return nil 

这将为您提供所需大小的图像。

现在,您的下一个问题可能是,“为什么我的像素化图像周围有一条又细又黑的边框?”好问题!但请为此提出一个新问题。

【讨论】:

谢谢拉夫隆。工作正常。不过我还没有看到你说的黑色边框。

以上是关于对 UIImage 进行像素化会返回具有不同大小的 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

UIImageView 和 UIImage 大小相等

检索透明UIImage的最后一个非透明像素位置

UIImage 大小(以像素为单位)

具有特定格式 RGB-565 的 UIImage

使用 CGContext 调整 UIImage 的大小会使我的图像变软,像素密度错误

colworWithPatternImage 返回一个 1 像素的透明边框