在 iOS swift 中旋转和混合图像
Rotate and blend image in iOS swift
如何获得与下方图像混合并围绕其中心旋转的图像?
我正在尝试显示与该图像下方的任何视图混合的图像。在我的应用程序中,用户能够移动、扩展和旋转正在混合的图像。
为此,我有一个主图像视图,以及一个用于混合的较小图像视图。混合图像视图图像 属性 每次位置更改时都会更新。
只要图像不旋转,图像的混合就可以正常工作,一旦旋转发生变化,我的函数返回的图像就会不在正确的位置。
我已经尝试了同一功能的两个不同版本。
版本 1:updateBlendingView
- 创建具有混合图像视图大小的上下文
- 在偏移处绘制主图像视图,以便上下文位于混合图像视图的位置。
- 将上下文移到它的中心
- 将上下文旋转到混合图像视图的旋转
- 使用混合模式绘制混合图像视图
- 从上下文中获取图像并更新图像视图
版本 2:updateBlendingView2
- 创建具有混合图像视图大小的上下文
- 将上下文移至其中心
- 反向旋转上下文
- 在偏离中心的位置绘制主图像视图
- 撤消旋转
- 在其与上下文原点的原点偏移处绘制混合视图
- 从上下文获取图像并更新混合图像视图
当前结果:
预期结果:
注意:请记住,sketch 中的混合强度可能与应用程序不同,但问题不在于此,而是关于图像定位:)
func updateBlendingView() {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x , y: -blendingImageView.frame.origin.y )
mainViewImage.draw(at: mainViewOrigin)
context.concatenate(blendingOriginTransform)
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}
func updateBlendingView2() {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
context.concatenate(blendingOriginTransform)
context.concatenate(rotateTransform.inverted())
let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x - (blendingImageView.bounds.width * 0.5) , y: -blendingImageView.frame.origin.y - (blendingImageView.bounds.height * 0.5))
mainViewImage.draw(at: mainViewOrigin)
// undo the rotate
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}
func getImageFromView(view: UIView) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return nil}
view.layer.render(in: context)
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return snapshotImage
}
任何帮助将不胜感激,非常感谢。
你可以在这个 link 中找到一个小的演示项目来说明这个问题
https://github.com/Gregortega/BlendDemo
我还查看了有关核心图形的不同教程以了解该问题。
Swift: Translating and Rotating a CGContext, A Visual Explanation (iOS/Xcode)
我会回答我自己的问题。一个朋友给了我一个轮换问题的解决方案。
解决方案是考虑混合图像视图的位置差异或变化。
func updateBlendingView2(xDiff: CGFloat = 0, yDiff: CGFloat = 0) {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
// X, Y translation
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
context.concatenate(blendingOriginTransform)
// Rotation
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
context.concatenate(rotateTransform.inverted())
var mainViewOrigin = self.lastMainViewOrign
mainViewOrigin = CGPoint(x: mainViewOrigin.x + xDiff, y: mainViewOrigin.y + yDiff)
mainViewImage.draw(at: mainViewOrigin)
self.lastMainViewOrign = mainViewOrigin
// undo the rotate
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}
如何获得与下方图像混合并围绕其中心旋转的图像?
我正在尝试显示与该图像下方的任何视图混合的图像。在我的应用程序中,用户能够移动、扩展和旋转正在混合的图像。
为此,我有一个主图像视图,以及一个用于混合的较小图像视图。混合图像视图图像 属性 每次位置更改时都会更新。
只要图像不旋转,图像的混合就可以正常工作,一旦旋转发生变化,我的函数返回的图像就会不在正确的位置。
我已经尝试了同一功能的两个不同版本。
版本 1:updateBlendingView
- 创建具有混合图像视图大小的上下文
- 在偏移处绘制主图像视图,以便上下文位于混合图像视图的位置。
- 将上下文移到它的中心
- 将上下文旋转到混合图像视图的旋转
- 使用混合模式绘制混合图像视图
- 从上下文中获取图像并更新图像视图
版本 2:updateBlendingView2
- 创建具有混合图像视图大小的上下文
- 将上下文移至其中心
- 反向旋转上下文
- 在偏离中心的位置绘制主图像视图
- 撤消旋转
- 在其与上下文原点的原点偏移处绘制混合视图
- 从上下文获取图像并更新混合图像视图
当前结果:
预期结果:
注意:请记住,sketch 中的混合强度可能与应用程序不同,但问题不在于此,而是关于图像定位:)
func updateBlendingView() {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x , y: -blendingImageView.frame.origin.y )
mainViewImage.draw(at: mainViewOrigin)
context.concatenate(blendingOriginTransform)
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}
func updateBlendingView2() {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
context.concatenate(blendingOriginTransform)
context.concatenate(rotateTransform.inverted())
let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x - (blendingImageView.bounds.width * 0.5) , y: -blendingImageView.frame.origin.y - (blendingImageView.bounds.height * 0.5))
mainViewImage.draw(at: mainViewOrigin)
// undo the rotate
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}
func getImageFromView(view: UIView) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return nil}
view.layer.render(in: context)
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return snapshotImage
}
任何帮助将不胜感激,非常感谢。 你可以在这个 link 中找到一个小的演示项目来说明这个问题 https://github.com/Gregortega/BlendDemo
我还查看了有关核心图形的不同教程以了解该问题。 Swift: Translating and Rotating a CGContext, A Visual Explanation (iOS/Xcode)
我会回答我自己的问题。一个朋友给了我一个轮换问题的解决方案。
解决方案是考虑混合图像视图的位置差异或变化。
func updateBlendingView2(xDiff: CGFloat = 0, yDiff: CGFloat = 0) {
guard let mainViewImage = getImageFromView(view: mainImageView) else {return}
// Reset image to original state before blending
blendingImageView.image = UIImage(named: "square")!
guard let blendingImage = getImageFromView(view: blendingImageView) else {return}
UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return}
// X, Y translation
let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5))
context.concatenate(blendingOriginTransform)
// Rotation
let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a))
let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians))
context.concatenate(rotateTransform.inverted())
var mainViewOrigin = self.lastMainViewOrign
mainViewOrigin = CGPoint(x: mainViewOrigin.x + xDiff, y: mainViewOrigin.y + yDiff)
mainViewImage.draw(at: mainViewOrigin)
self.lastMainViewOrign = mainViewOrigin
// undo the rotate
context.concatenate(rotateTransform)
let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5)
blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5)
guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
blendingImageView.image = blendedImage
}