如何在调整UIImage大小时提高清晰度?

时间:2015-04-22 09:36:14

标签: ios swift uiimage image-compression uiimagejpegrepresentation

在我的应用程序中,我需要在服务器上上传照片,所以在此之前,我想调整大小并将其压缩到可接受的大小。我尝试用两种方式调整它们的大小,第一种方法是:

    // image is an instance of original UIImage that I want to resize
    let width : Int = 640
    let height : Int = 640
    let bitsPerComponent = CGImageGetBitsPerComponent(image.CGImage)
    let bytesPerRow = CGImageGetBytesPerRow(image.CGImage)
    let colorSpace = CGImageGetColorSpace(image.CGImage)
    let bitmapInfo = CGImageGetBitmapInfo(image.CGImage)

    let context = CGBitmapContextCreate(nil, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo)
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh)
    CGContextDrawImage(context, CGRect(origin: CGPointZero, size: CGSize(width: CGFloat(width), height: CGFloat(height))), image.CGImage)

    image = UIImage(CGImage: CGBitmapContextCreateImage(context))

另一种方式:

image = RBResizeImage(image, targetSize: CGSizeMake(640, 640))

func RBResizeImage(image: UIImage?, targetSize: CGSize) -> UIImage? {
        if let image = image {
            let size = image.size

            let widthRatio  = targetSize.width  / image.size.width
            let heightRatio = targetSize.height / image.size.height

            // Figure out what our orientation is, and use that to form the rectangle
            var newSize: CGSize
            if(widthRatio > heightRatio) {
                newSize = CGSizeMake(size.width  heightRatio, size.height  heightRatio)
            } else {
                newSize = CGSizeMake(size.width  widthRatio,  size.height  widthRatio)
            }

            // This is the rect that we've calculated out and this is what is actually used below
            let rect = CGRectMake(0, 0, newSize.width, newSize.height)

            // Actually do the resizing to the rect using the ImageContext stuff
            UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
            image.drawInRect(rect)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return newImage
        } else {
            return nil
        }
    }

之后,我使用UIImageJPEGRepresentation来压缩UIImage,但即使compressionQuality为1,照片仍然模糊(大部分在对象边缘都可见,也许是' s没什么大不了的,但是照片比来自Instagram的同一张照片大三到五倍,例如但是没有相同的清晰度。当然,0.5甚至更糟,照片仍然比Instagram中的照片更大(以KB为单位)。

Photo from my app, compressionQuality is 1, edges are blurry, and size is 341 KB 我的应用中的照片,compressionQuality为1,边缘模糊,大小为341 KB

Photo from Instagram, edges are sharp, and size is 136 KB 来自Instagram的照片,边缘清晰,大小为136 KB

修改

好的,但我现在很困惑,我不知道该怎么办,以保持宽高比?这就是我裁剪图像的方式(scrollView有UIImageView,所以我可以移动和缩放图像,最后,我能够裁剪scrollView的可见部分,即sqare)。无论如何,上面的图像最初是2048x2048,但它仍然模糊不清。

 var scale  = 1/scrollView.zoomScale
 var visibleRect : CGRect = CGRect()

 visibleRect.origin.x = scrollView.contentOffset.x * scale
 visibleRect.origin.y = scrollView.contentOffset.y * scale
 visibleRect.size.width = scrollView.bounds.size.width * scale
 visibleRect.size.height = scrollView.bounds.size.height * scale
 image = crop(image!, rect: visibleRect)


func crop(srcImage : UIImage, rect : CGRect) -> UIImage? {
     var imageRef = CGImageCreateWithImageInRect(srcImage.CGImage, rect)
     var cropped = UIImage(CGImage: imageRef)

     return cropped
}

1 个答案:

答案 0 :(得分:0)

您给出的代码是正确的,但问题是您不保持图像的宽高比  在您的代码中,您创建一个新的矩形

let rect = CGRectMake(0, 0, newSize.width, newSize.height) 

如果给定的图像具有相同的高度和宽度,它将提供平滑的调整大小图像,但如果高度和宽度不同,则图像模糊。所以尽量保持宽高比
回复编辑问题
使裁剪图像的高度或宽度恒定
例如,如果将宽度设置为常量,则使用以下代码

 visibleRect.size.height = orignalImg.size.height *  visibleRect.size.width / orignalImg.size.width     

image = crop(image!, rect: visibleRect)