我想允许用户在照片上绘画。我目前正在关注这个tutorial,它显示了如何使用UIKit制作一个简单的绘图应用程序。

视图控制器中有两个UIImageView(tempImageViewmainImageView)。当用户拖动手指时,他们直接在tempImageView上绘画,而在释放时,tempImageViewmainImageView的图像合并在一起以创建主图像。

现在,我的应用程序的行为如下:

ios - 在UIImage上徒手绘制-LMLPHP

当我开始时(左屏幕截图),我将mainImageView设置为具有想要允许用户绘制的现有照片。 问题是,一旦用户画出笔触并松开手指,背景中的原始照片就会拉长(右图)。它在tempImageViewmainImageView合并期间发生。 如何解决此问题?

我尝试设置图像视图的内容模式(纵横比填充,居中等),但没有任何改变。

视图控制器是使用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);
...

09-07 14:17