gpt4 book ai didi

ios - CIAffineClamp 过滤器不夹紧

转载 作者:行者123 更新时间:2023-11-28 13:23:12 25 4
gpt4 key购买 nike

我正在尝试做简单的事情。我有 ImageView ,里面有图像。我想将图像平移图像大小的一半宽度,并将像素固定在变换图像的边缘,借助 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
}

最佳答案

问题是您还对输出 extent 应用了转换。这是对我有用的代码,带有一些注释:

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

关于ios - CIAffineClamp 过滤器不夹紧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58797067/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com