如何缩小UIImage并同时使其变得清脆/锐利而不是模糊?

Pro*_*ber 74 scaling image core-graphics uikit ios

我需要缩小图像,但需要以锐利的方式缩小.例如,在Photoshop中有图像尺寸缩小选项"Bicubic Smoother"(模糊)和"Bicubic Sharper".

这个图像缩减算法是在某处开源或记录的,还是SDK提供了这样做的方法?

Dan*_*ark 126

仅仅使用imageWithCGImage是不够的.它会缩放,但无论是放大还是缩小,结果都会模糊不清.

如果你想获得正确的别名并摆脱"锯齿",你需要这样的东西:http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-方式/.

我的工作测试代码看起来像这样,这是Trevor的解决方案,只需要一个小的调整就可以使用我的透明PNG:

- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = image.CGImage;

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Set the quality level to use when rescaling
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);

    CGContextConcatCTM(context, flipVertical);  
    // Draw into the context; this scales the image
    CGContextDrawImage(context, newRect, imageRef);

    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(context);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();    

    return newImage;
}
Run Code Online (Sandbox Code Playgroud)


bzm*_*zmw 18

对于那些使用Swift的人来说,这是Swift中接受的答案:

func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
    let newRect = CGRectIntegral(CGRectMake(0,0, newSize.width, newSize.height))
    let imageRef = image.CGImage

    UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
    let context = UIGraphicsGetCurrentContext()

    // Set the quality level to use when rescaling
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh)
    let flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)

    CGContextConcatCTM(context, flipVertical)
    // Draw into the context; this scales the image
    CGContextDrawImage(context, newRect, imageRef)

    let newImageRef = CGBitmapContextCreateImage(context) as CGImage
    let newImage = UIImage(CGImage: newImageRef)

    // Get the resized image from the context and a UIImage
    UIGraphicsEndImageContext()

    return newImage
}
Run Code Online (Sandbox Code Playgroud)

  • kCGInterpolationHigh - > CGInterpolation.High in Swift 2或者你得到一个编译错误 (5认同)
  • 为什么需要翻转图像来调整大小(即,为什么需要`CGContextConcatCTM(context,flipVertical)`? (2认同)

Sar*_*raz 18

如果有人正在寻找Swift版本,这里是@Dan Rosenstark接受的答案的Swift版本:

func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
    let scale = newHeight / image.size.height
    let newWidth = image.size.width * scale
    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
    image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}
Run Code Online (Sandbox Code Playgroud)


NSE*_*rer 12

如果在缩放时保留图像的原始宽高比,无论缩小多少,您都将始终获得清晰的图像.

您可以使用以下方法进行缩放:

+ (UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
Run Code Online (Sandbox Code Playgroud)


Saz*_*han 12

对于Swift 3

func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {

    let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
    let context = UIGraphicsGetCurrentContext()

    // Set the quality level to use when rescaling
    context!.interpolationQuality = CGInterpolationQuality.default
    let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)

    context!.concatenate(flipVertical)
    // Draw into the context; this scales the image
    context?.draw(image.cgImage!, in: CGRect(x: 0.0,y: 0.0, width: newRect.width, height: newRect.height))

    let newImageRef = context!.makeImage()! as CGImage
    let newImage = UIImage(cgImage: newImageRef)

    // Get the resized image from the context and a UIImage
    UIGraphicsEndImageContext()

    return newImage
 }
Run Code Online (Sandbox Code Playgroud)