如何裁剪 UIImage 而不会丢失它的 scale 属性?

Posted

技术标签:

【中文标题】如何裁剪 UIImage 而不会丢失它的 scale 属性?【英文标题】:How to crop a UIImage without losing it's scale property? 【发布时间】:2016-09-23 07:30:49 【问题描述】:

目标:裁剪 UIImage(以 scale 属性 2.0 开头)

我执行以下代码:

let croppedCGImage = originalUIImage.cgImage!.cropping(to: cropRect)
let croppedUIImage = UIImage(cgImage: croppedCGImage!)

此代码有效,但结果 croppedUIImagescale 属性不正确,为 1.0。


我尝试在创建最终图像时指定scale

let croppedUIImage = UIImage(cgImage: croppedCGImage!, scale: 2.0, orientation: .up)

这会产生正确的比例,但会错误地将 size 尺寸减半。


我应该在这里做什么?

(*注意:UIImage 上的scale 属性很重要,因为我后来使用受scale 属性影响的UIImagePNGRepresentation(_ image: UIImage) 保存图像)



编辑:

我得到了以下工作。不幸的是,它比CGImage 裁剪功能慢很多。

extension UIImage 
    func cropping(to rect: CGRect) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(rect.size, false, self.scale)

        self.draw(in: CGRect(x: -rect.origin.x, y: -rect.origin.y, width: self.size.width, height: self.size.height))

        let croppedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return croppedImage
    

【问题讨论】:

【参考方案1】:

试试这个:

extension UIImage 
    func imageByCropToRect(rect:CGRect, scale:Bool) -> UIImage 

        var rect = rect
        var scaleFactor: CGFloat = 1.0
        if scale  
            scaleFactor = self.scale
            rect.origin.x *= scaleFactor
            rect.origin.y *= scaleFactor
            rect.size.width *= scaleFactor
            rect.size.height *= scaleFactor
        

        var image: UIImage? = nil;
        if rect.size.width > 0 && rect.size.height > 0 
            let imageRef = self.cgImage!.cropping(to: rect)
            image = UIImage(cgImage: imageRef!, scale: scaleFactor, orientation: self.imageOrientation)
        

        return image!
    

【讨论】:

【参考方案2】:

使用这个扩展 :-

extension UIImage 

    func cropping(to quality: CGInterpolationQuality, rect: CGRect) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(rect.size, false, self.scale)

        let context = UIGraphicsGetCurrentContext()! as CGContext
        context.interpolationQuality = quality

        let drawRect : CGRect = CGRect(x: -rect.origin.x, y: -rect.origin.y, width: self.size.width, height: self.size.height)

        context.clip(to: CGRect(x:0, y:0, width: rect.size.width, height: rect.size.height))

        self.draw(in: drawRect)

        let croppedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return croppedImage
    

【讨论】:

您希望这段代码如何从矩形的位置和大小裁剪图像??它不适合我【参考方案3】:

我正在使用适用于 ios 和 tvOS 的 ImageHelper Pod,它运行良好,也可能满足您的需求。

它带来了很多 UIImage 扩展如:

裁剪和调整大小

// Crops an image to a new rect
func crop(bounds: CGRect) -> UIImage?

// Crops an image to a centered square
func cropToSquare() -> UIImage? 

// Resizes an image
func resize(size:CGSize, contentMode: UIImageContentMode = .ScaleToFill) -> UIImage?

屏幕密度

// To create an image that is Retina aware, use the screen scale as a multiplier for your size. You should also use this technique for padding or borders.
let width = 140 * UIScreen.mainScreen().scale
let height = 140 * UIScreen.mainScreen().scale
let image = UIImage(named: "myImage")?.resize(CGSize(width: width, height: height))

还有类似的东西:图像效果

// Applies a light blur effect to the image
func applyLightEffect() -> UIImage?
// Applies a extra light blur effect to the image
func applyExtraLightEffect() -> UIImage?
// Applies a dark blur effect to the image
func applyDarkEffect() -> UIImage?
// Applies a color tint to an image
func applyTintEffect(tintColor: UIColor) -> UIImage?
// Applies a blur to an image based on the specified radius, tint color saturation and mask image
func applyBlur(blurRadius:CGFloat, tintColor:UIColor?, saturationDeltaFactor:CGFloat, maskImage:UIImage? = nil) -> UIImage?

【讨论】:

【参考方案4】:
-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect


    CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
    UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
    CGImageRelease(subImage);
    return croppedImage;

打电话

    UIImage *imageSample=image;
    CGRect rectMake1=CGRectMake(0, 0,imageSample.size.width*1/4, imageSample.size.height);
    UIImage *img1=[[JRGlobal sharedInstance] getNeedImageFrom:imageSample cropRect:rectMake1];

【讨论】:

以上是关于如何裁剪 UIImage 而不会丢失它的 scale 属性?的主要内容,如果未能解决你的问题,请参考以下文章

使用javascript裁剪GIF图像而不会丢失动画[重复]

将位图裁剪为特定的宽度和高度,而不会丢失分辨率

像IOS 5一样裁剪UIImage时如何制作视图效果?

裁剪旋转的 UIImage

如何裁剪 UIImage?

如何获得正确的区域来裁剪 UIImage?