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

Posted

技术标签:

【中文标题】使用 CGContext 调整 UIImage 的大小会使我的图像变软,像素密度错误【英文标题】:Resizing UIImage with CGContext is making my images soft with wrong pixel density 【发布时间】:2016-08-20 01:34:45 【问题描述】:

我正在构建一个图像管理器类来处理 UIImages 的大小调整、裁剪等。我使用 CGContext 是因为它的速度可与带有 JPEG 的 UIGraphicsContext 相媲美,来自这里看到的基准http://nshipster.com/image-resizing/。

这是我的经理班:

func resizeImage(exportedWidth width: Int, exportedHeight height: Int, originalImage image: UIImage) -> UIImage? 
    let cgImage = image.CGImage

    let width = width
    let height = height
    let bitsPerComponent = CGImageGetBitsPerComponent(cgImage)
    let bytesPerRow = CGImageGetBytesPerRow(cgImage)
    let colorSpace = CGImageGetColorSpace(cgImage)
    let bitmapInfo = CGImageGetBitmapInfo(cgImage)

    let context = CGBitmapContextCreate(nil, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo.rawValue)

    CGContextSetInterpolationQuality(context, .High)

    CGContextDrawImage(context, CGRect(origin: CGPointZero, size: CGSize(width: CGFloat(width), height: CGFloat(height))), cgImage)

    let scaledImage = CGBitmapContextCreateImage(context).flatMap  UIImage(CGImage: $0) 

    return scaledImage

没有什么太疯狂了,但是当我将它添加到子类 UITextView 时我遇到了麻烦。我曾尝试将图像大小加倍,然后用 UIImageView 将其压缩但无济于事。此代码以正确的大小正确显示,但看起来图像像素与屏幕像素的比率是 1:1,而不是 iPhone SE 上视网膜屏幕的理想 2:1。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) 
    if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage 
        let textViewWidth: CGFloat = self.view.frame.size.width - 130
        let percentResize = textViewWidth / pickedImage.size.width
        let toBeExportedHeight = pickedImage.size.height * percentResize
        let resizedImage = ImageManipulationManager.sharedInstance.resizeImage(exportedWidth: Int(textViewWidth),exportedHeight: Int(toBeExportedHeight), originalImage: pickedImage)

        let attachment = NSTextAttachment()
        attachment.image = resizedImage
        let attString = NSAttributedString(attachment: attachment)
        textView.textStorage.insertAttributedString(attString, atIndex: textView.selectedRange.location)
        textInputbar.layoutIfNeeded()
        textView.becomeFirstResponder()
        print(textView.text.characters.count)
    
    dismissViewControllerAnimated(true, completion: nil)

【问题讨论】:

【参考方案1】:

双分辨率屏幕的图像需要双分辨率。这意味着它应该是您想要的实际大小的两倍宽和两倍高,当您从 CGImage 派生 UIImage 时,它​​的 scale 为 2。

【讨论】:

我将在哪里将比例设置为两倍大小。我尝试将 bitmapcontext 的大小设置为两倍,而实际图像边界是该大小的一半。然而,最终发生的只是渲染大小相同,额外的空间是黑色的。 正如我在回答中所说,当您从 CGImage 派生 UIImage 时,您会这样做。 那么代码呢?我不知道我需要改变什么属性。我意识到它的规模,但我希望这对我有所帮助。 看看如何从一个CGImage制作一个UIImage:developer.apple.com/library/ios/documentation/UIKit/Reference/…:你说的是UIImage(CGImage: $0)。所以你错过了设置比例的机会。

以上是关于使用 CGContext 调整 UIImage 的大小会使我的图像变软,像素密度错误的主要内容,如果未能解决你的问题,请参考以下文章

用 CGPathRef 屏蔽 CGContext?

为 PaintCode CGContext 自动调整标签中的文本

通过 CGContext 绘制 UIButton 图像

旋转 UIImageView 数据 -

iOS高效裁剪图片圆角算法

使用 UIImageView 调整 UIImage