1

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

    // 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,照片仍然模糊(主要在对象边缘可见,也许这不是什么大问题,但照片比 Instagram 中的同一张照片大三到五倍,例如但是没有相同的清晰度)。当然,0.5 甚至更糟,而且照片仍然比 Instagram 上的同一张照片更大(以 KB 为单位)。

我的应用程序中的照片,compressionQuality 为 1,边缘模糊,大小为 341 KB 我的应用程序中的照片,compressionQuality 为 1,边缘模糊,大小为 341 KB

来自 Instagram 的照片,边缘清晰,大小为 136 KB 来自 Instagram 的照片,边缘清晰,大小为 136 KB

编辑:

好的,但我现在有点困惑,我不知道该怎么做,保持纵横比?这就是我裁剪图像的方式(scrollView 具有 UIImageView,因此我可以移动和缩放图像,最后,我可以裁剪 scrollView 的可见部分,即方形)。无论如何,上面的图像最初是 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
}
4

1 回答 1

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)
于 2015-04-22T10:22:19.957 回答