我想允许用户绘制照片。我目前正在关注此tutorial,其中介绍了如何使用UIKit
制作简单的绘图应用。
视图控制器中有两个UIImageView
s(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()
}
}
答案 0 :(得分:2)
我认为问题在于将mainImageView.image.drawinrect设置为imageview的大小而不是显示的图像。
我没有使用swift但是我会在Obj-c中使用以获得用于绘制正确尺寸的图像的显示尺寸。
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);
...
答案 1 :(得分:0)
AVFoundation
中有一个API,可以解决在保留宽高比的同时将图像适合CGRect的确切问题:
AVMakeRect(aspectRatio: image.size, insideRect: view.bounds)