在高分辨率图像上绘制形状?

时间:2016-01-28 02:32:53

标签: ios swift core-graphics

我希望能够在特定位置在高分辨率照片(例如8百万像素图像)上画一条线。

这是一个很简单的事情,关于这个问题已经有很多帖子,但我的问题是CGContext"绘图空间"并不像高分辨率图像一样。

我可以绘制线条并保存图像,但我的问题是在特定位置绘制线条。我的坐标空间似乎彼此不同。我认为必须有一个我缺少的比例因子,或者我的理解只是搞砸了。

所以我的问题是:

如何绘制图像,即"方面适合"到屏幕(但分辨率要高得多)并使图形(在这种情况下是一条线)在屏幕上的相同位置和最终的全分辨率合成图像?

示例图片: enter image description here

红线是我画的线。它应该从起始目标的中心(目标)到最终目标的中心(theEnd)。

我已经将我的绘图功能简化为在此发布,但我怀疑这是我的整个想法/方法是错误的。

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!  
@IBOutlet weak var theTarget: UIImageView!
@IBOutlet weak var theEnd: UIImageView!

var lineColor = UIColor.redColor()
var targetPos : CGPoint!
var endPos : CGPoint!
var originalImage : UIImage!

override func viewDidLoad() {
    super.viewDidLoad()

    imageView.image = UIImage(named: "reference.jpg")
    originalImage = imageView.image

    drawTheLine() 
}


func drawTheLine () {
    UIGraphicsBeginImageContext(originalImage!.size);

    // Draw the original image as the background
    originalImage?.drawAtPoint(CGPointMake(0, 0))

    // Pass 2: Draw the line on top of original image
    let context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 10.0);

    targetPos = theTarget.frame.origin
    endPos = theEnd.frame.origin

    CGContextMoveToPoint(context, targetPos.x, targetPos.y);
    CGContextAddLineToPoint(context, endPos.x, endPos.y)
    CGContextSetStrokeColorWithColor(context, lineColor.CGColor)
    CGContextStrokePath(context);

    imageView.image = UIGraphicsGetImageFromCurrentImageContext()
}

@IBAction func saveButton(sender: AnyObject) {
    // Create new image

   let newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIImageWriteToSavedPhotosAlbum(newImage!, nil, nil, nil )
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    if let view = recognizer.view {
        view.center = CGPoint(x:view.center.x + translation.x,
            y:view.center.y + translation.y)
    }
    recognizer.setTranslation(CGPointZero, inView: self.view)

    //redraw the line
    drawTheLine()

    print("the start pos of the line is: ", theTarget.frame.origin, " and end pos is: ", theEnd.frame.origin)

}


}

1 个答案:

答案 0 :(得分:0)

前一段时间我遇到了这个问题,所以当填充模式为UIImageView时,我写了一个.ScaleAspectFit扩展名,将图片视图的坐标映射到图像坐标。

extension UIImageView {

    func pointInAspectScaleFitImageCoordinates(point:CGPoint) -> CGPoint {

        if let img = image {

            let imageSize = img.size
            let imageViewSize = frame.size

            let imgRatio = imageSize.width/imageSize.height // The ratio of the image before scaling.
            let imgViewRatio = imageViewSize.width/imageViewSize.height // The ratio of the image view

            let ratio = (imgRatio > imgViewRatio) ? imageSize.width/imageViewSize.width:imageSize.height/imageViewSize.height // The ratio of the image before scaling to after scaling.

            let xOffset = (imageSize.width-(imageViewSize.width*ratio))*0.5 // The x-offset of the image on-screen (as it gets centered)
            let yOffset = (imageSize.height-(imageViewSize.height*ratio))*0.5 // The y-offset of the image on-screen (as it gets centered)

            let subImgOrigin = CGPoint(x: point.x*ratio, y: point.y*ratio); // The origin of the image (relative to the origin of the view)

            return CGPoint(x: subImgOrigin.x+xOffset, y: subImgOrigin.y+yOffset);
        }
        return CGPointZero
    }
}

您应该可以非常轻松地在drawTheLine功能中使用它:

func drawTheLine () {
    UIGraphicsBeginImageContext(originalImage!.size);

    // Draw the original image as the background
    originalImage?.drawAtPoint(CGPointMake(0, 0))

    // Pass 2: Draw the line on top of original image
    let context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 10.0);

    targetPos = imageView.pointInAspectScaleFitImageCoordinates(theTarget.frame.origin)
    endPos = imageView.pointInAspectScaleFitImageCoordinates(theEnd.frame.origin)

    CGContextMoveToPoint(context, targetPos.x, targetPos.y);
    CGContextAddLineToPoint(context, endPos.x, endPos.y)
    CGContextSetStrokeColorWithColor(context, lineColor.CGColor)
    CGContextStrokePath(context);

    imageView.image = UIGraphicsGetImageFromCurrentImageContext()
}