我想允许用户在照片上绘画。我目前正在关注这个tutorial,它显示了如何使用UIKit
制作一个简单的绘图应用程序。
视图控制器中有两个UIImageView
(tempImageView
和mainImageView
)。当用户拖动手指时,他们直接在tempImageView
上绘画,而在释放时,tempImageView
和mainImageView
的图像合并在一起以创建主图像。
现在,我的应用程序的行为如下:
当我开始时(左屏幕截图),我将mainImageView
设置为具有想要允许用户绘制的现有照片。 问题是,一旦用户画出笔触并松开手指,背景中的原始照片就会拉长(右图)。它在tempImageView
和mainImageView
合并期间发生。 如何解决此问题?
我尝试设置图像视图的内容模式(纵横比填充,居中等),但没有任何改变。
视图控制器是使用Storyboard创建的,彼此之间仅具有两个UIImageView
。这是完整的FingerpaintViewController
代码:
import UIKit
class FingerpaintViewController: UIViewController {
@IBOutlet weak var mainImageView: UIImageView!
@IBOutlet weak var tempImageView: UIImageView!
private var lastPoint = CGPoint.zero
private var red: CGFloat = 0.0
private var green: CGFloat = 0.0
private var blue: CGFloat = 0.0
private var brushWidth: CGFloat = 10.0
private var opacity: CGFloat = 1.0
private var swiped = false
override func viewDidLoad() {
super.viewDidLoad()
mainImageView.image = UIImage(named: "golden_gate_bridge")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
swiped = false
if let touch = touches.first {
lastPoint = touch.locationInView(tempImageView)
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
swiped = true
if let touch = touches.first {
let currentPoint = touch.locationInView(tempImageView)
drawLineFrom(lastPoint, toPoint: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if !swiped {
drawLineFrom(lastPoint, toPoint: lastPoint)
}
// Merge tempImageView into mainImageView
UIGraphicsBeginImageContext(mainImageView.frame.size)
mainImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: mainImageView.frame.size.width, height: mainImageView.frame.size.height), blendMode: .Normal, alpha: 1.0)
tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: mainImageView.frame.size.width, height: mainImageView.frame.size.height), blendMode: .Normal, alpha: opacity)
mainImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImageView.image = nil
}
func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
UIGraphicsBeginImageContext(mainImageView.frame.size)
let context = UIGraphicsGetCurrentContext()
tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: mainImageView.frame.size.width, height: mainImageView.frame.size.height))
// 2
CGContextMoveToPoint(context, fromPoint.x, fromPoint.y)
CGContextAddLineToPoint(context, toPoint.x, toPoint.y)
// 3
CGContextSetLineCap(context, .Round)
CGContextSetLineWidth(context, brushWidth)
CGContextSetRGBStrokeColor(context, red, green, blue, 1.0)
CGContextSetBlendMode(context, .Normal)
// 4
CGContextStrokePath(context)
// 5
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
tempImageView.alpha = opacity
UIGraphicsEndImageContext()
}
}
最佳答案
我认为问题在于将mainImageView.image.drawinrect设置为imageview的大小,而不是所显示的图像。
我不使用swift,但是这里使用了我在Obj-c中使用的方法来获取显示的图像大小,以用作drawinrect大小。
CGRect imageRect = [self getImageRectForImageView:mainImageView];
- (CGRect) getImageRectForImageView:(UIImageView*)imageView
{
float resVi = imageView.image.size.width / imageView.image.size.height;
float resPl = imageView.size.width / imageView.size.height;
if (resPl > resVi)
{
CGSize imageSize = CGSizeMake(imageView.image.size.width * imageView.size.height / imageView.image.size.height, imageView.size.height);
return CGRectMake((imageView.size.width - imageSize.width)/2,
(imageView.size.height - imageSize.height)/2,
imageSize.width,
imageSize.height);
}
else
{
CGSize imageSize = CGSizeMake(imageView.size.width, imageView.image.size.height * imageView.size.width / imageView.image.size.width);
return CGRectMake((imageView.size.width - imageSize.width)/2,
(imageView.size.height - imageSize.height)/2,
imageSize.width,
imageSize.height);
}
}
然后,您可以将新的imageRect值用于drawinrect调用。
// Merge tempImageView into mainImageView
UIGraphicsBeginImageContext(mainImageView.frame.size)
mainImageView.image?.drawInRect(imageRect);
...