【问题标题】:CIAffineClamp filter does not clampCIAffineClamp 过滤器不夹紧
【发布时间】:2019-11-11 07:21:36
【问题描述】:

我正在尝试做简单的事情。 我有图像视图,其中包含图像。我想将图像转换为图像大小的一半,并在转换后的图像边缘夹住像素,在CIAffineClamp 的帮助下将它们向外扩展。但它没有工作。它什么都不做。我附上了示例项目。

我的代码是:

func translateAndClamp(image: UIImage) -> UIImage {
        guard let cgImage = image.cgImage else {
            return image
        }
        let ciImage = CIImage(cgImage: cgImage)

        var transform = CGAffineTransform.identity
        transform = transform.translatedBy(x: image.size.width / 2, y: 0)

        let filter = CIFilter(name: "CIAffineClamp")!
        filter.setValue(ciImage, forKey: kCIInputImageKey)
        filter.setValue(NSValue(cgAffineTransform: transform), forKey: "inputTransform")

        let context = CIContext(options: [CIContextOption.useSoftwareRenderer: true])

        guard let outputImage = filter.outputImage else {
            return image
        }

        let extent = ciImage.extent.applying(transform)

        guard let result = context.createCGImage(outputImage, from: extent) else {
            return image
        }

        return UIImage(cgImage: result, scale: image.scale, orientation: image.imageOrientation)
    }

Sample project

更新


    private func makeResultImageCroppedAndRotated(from image: UIImage) -> UIImage {
        let angle = CGFloat(gestureHandler.rotation(from: imgView.transform))

        guard let cgImage = image.cgImage else {
            return image
        }

        let rotatedCGImage = rotateImage(image: cgImage, angle: angle)
        let rotated = UIImage(cgImage: rotatedCGImage, scale: image.scale, orientation: image.imageOrientation)
        let cropArea = makeCropArea(for: rotated, in: imgView, anchor: layoutContentView)
        let cropped = cropImage(image: rotatedCGImage, to: cropArea)

        return UIImage(cgImage: cropped, scale: image.scale, orientation: image.imageOrientation)
    }


    private func makeCropArea(for image: UIImage, in imageView: UIImageView, anchor: UIView) -> CGRect {
        let boundingRect = LayoutCorrectionUtility.boundingAspectRect(for: image, inside: imageView)
        let factor = LayoutCorrectionUtility.factor(for: image, insideBoundingRect: boundingRect)

        let x = (anchor.bounds.origin.x - boundingRect.origin.x) * factor
        let y = (anchor.bounds.origin.y - boundingRect.origin.y) * factor
        let width = anchor.frame.width * factor
        let height = anchor.frame.height * factor

        return CGRect(x: x, y: y, width: width, height: height)
    }


    func rotateImage(image: CGImage, angle: CGFloat) -> CGImage {
        let ciImage = CIImage(cgImage: image)

        let newAngle = angle * CGFloat(-1)

        var transform = CATransform3DIdentity
        transform = CATransform3DRotate(transform, CGFloat(newAngle), 0, 0, 1)
        let affineTransform = CATransform3DGetAffineTransform(transform)

        let filter = CIFilter(name: "CIAffineClamp")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setDefaults()
        filter?.setValue(NSValue(cgAffineTransform: affineTransform), forKey: "inputTransform")

        let contex = CIContext(options: [CIContextOption.useSoftwareRenderer: true])

        guard let outputImage = filter?.outputImage else {
            return image
        }

        let extent = ciImage.extent.applying(affineTransform)
        guard let result = contex.createCGImage(outputImage, from: extent) else {
            return image
        }

        return result
    }


    func cropImage(image: CGImage, to rect: CGRect) -> CGImage {
        let ciImage = CIImage(cgImage: image).clampedToExtent()

        var transform = CGAffineTransform(scaleX: 1, y: -1)
        transform = transform.translatedBy(x: 0, y: -CGFloat(image.height))

        let contex = CIContext(options: [CIContextOption.useSoftwareRenderer: true])

        guard let result = contex.createCGImage(ciImage, from: rect.applying(transform)) else {
            return image
        }

        return result
    }

【问题讨论】:

    标签: ios swift crop cifilter ciimage


    【解决方案1】:

    问题是您还将转换应用于输出extent。这是适用于我的一些 cmets 的代码:

    func translateAndClamp(image: UIImage) -> UIImage {
        // no need to use use the internal CGImage
        guard let ciImage = CIImage(image: image) else {
            return image
        }
    
        // Important: use the CIImage's width here since the UIImage's size
        // is in points, not pixels.
        let transform = CGAffineTransform(translationX: ciImage.extent.width / 2, y: 0)
    
        // This does the same as CIAffineClamp, but is shorter and doesn't return an Optional.
        let outputImage = ciImage.transformed(by: transform).clampedToExtent()
    
        // I would advise against using the software renderer, but maybe you have your reasons.
        // Also, if you want to call this method more then once, it's better to create the
        // context on object initialization and re-use it every time since it's expensive to create.
        let context = CIContext(options: [CIContextOption.useSoftwareRenderer: true])
    
        // Important: don't apply the transform to the output extent!
        // Think of this as the "window" on the image you want to draw.
        // Since you moved the image "inside" the window with the transform,
        // the window needs to be the original image's extent.
        let extent = ciImage.extent
    
        guard let result = context.createCGImage(outputImage, from: extent) else {
            return image
        }
    
        return UIImage(cgImage: result, scale: image.scale, orientation: image.imageOrientation)
    }
    

    【讨论】:

    • 你好,弗兰克。你能帮我完成三个操作吗:旋转、缩放、平移和裁剪。对于旋转,我使用CGAffineTransform + clampedToExtent
    • 首先我是旋转图像。接下来我尝试根据变换参数计算裁剪区域:缩放、平移。接下来我裁剪旋转图像。但效果还不够好
    • 其实我认为我的裁剪区域是正确的,我认为我的裁剪操作本身的问题。我需要裁剪和夹住新图像的透明像素
    • 很难看出您想要达到的目标。也许您可以发布一些结果应该是什么样子的示例/模型?
    • 照片:cdn1.imggmi.com/uploads/2019/11/12/… 此图像是旋转 (CGAffineClamp) 和平移和裁剪的结果。如您所见:有固定像素(旋转后)和黑色区域。我想黑色区域也将被固定。如何做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2021-04-29
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多