Ios CIAffineClamp滤清器未夹紧

Ios CIAffineClamp滤清器未夹紧,ios,swift,crop,cifilter,ciimage,Ios,Swift,Crop,Cifilter,Ciimage,我试着做一件简单的事。 我有图像视图,其中包含图像。我想按图像大小的一半宽度平移图像,并在变换图像的边缘夹紧像素,借助CIAffineClamp将它们向外扩展。但它不起作用。什么都不做是不可能的。我附上了样本项目 我的代码是: func translateAndClamp(image: UIImage) -> UIImage { guard let cgImage = image.cgImage else { return image

我试着做一件简单的事。 我有图像视图,其中包含图像。我想按图像大小的一半宽度平移图像,并在变换图像的边缘夹紧像素,借助
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)
    }

更新


    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
    }

问题是,您还将转换应用于输出
范围
。下面是适用于我的代码和一些注释:

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)
}

你好,弗兰克。你能帮我做三个操作吗:旋转、缩放、平移和裁剪。对于旋转,我使用的是
cGraffeTransform+clampedToExtent
首先是旋转图像。接下来,我尝试根据变换参数计算裁剪面积:缩放、平移。下一步是裁剪旋转图像。但效果不太好。事实上,我认为我的种植面积是正确的,我认为我的种植操作本身存在问题。我需要裁剪和钳制新图像的透明像素,这有点难看出你想要实现什么。也许你可以发布一些示例/模型来说明结果应该是什么样的?照片:这张图片是旋转(CGAffineClamp)和平移以及裁剪的结果。正如你们所看到的:有钳制像素(旋转后)和黑色区域。我想黑色区域也会被钳制到。如何做到这一点?