UIImage

时间:2015-12-08 05:26:54

标签: ios swift uiimageview uikit

我想允许用户绘制照片。我目前正在关注此tutorial,其中介绍了如何使用UIKit制作简单的绘图应用。

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

现在,我的应用就像这样:

Example

当我开始(左侧屏幕截图)时,我将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()

    }
}

2 个答案:

答案 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)