2017-04-05 83 views
0

我试图实现一个UIImageView子类,它允许用户使用他们的手指在图像视图中绘制。我的UIImageView的contentMode设置为Aspect Fill。我注意到,当我的绘图代码执行并且从图形上下文中提取出结果图像时,它将以Scale to Fill类型格式缩放,这不是我想要的。我想知道是否有人知道如何实现提取图像并保持图像的纵横比。UIGraphicsGetImageFromCurrentContext并保留长宽比

class DrawImageView : UIImageView { 

    var lastTouchPoint = CGPoint.zero 
    var isSwiping = false 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     isSwiping = false 
     if let touchPoint = touches.first { 
      lastTouchPoint = touchPoint.location(in: self) 
     } 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     isSwiping = true 

     if let touchPoint = touches.first { 
      let currentPoint = touchPoint.location(in: self) 
      UIGraphicsBeginImageContext(frame.size) 

      image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height)) 

      if let context = UIGraphicsGetCurrentContext() { 
       context.move(to: lastTouchPoint) 
       context.addLine(to: currentPoint) 
       context.setLineCap(CGLineCap.round) 
       context.setLineWidth(9.0) 
       context.setStrokeColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0) 
       context.strokePath() 
       image = UIGraphicsGetImageFromCurrentImageContext() 
       UIGraphicsEndImageContext() 
       lastTouchPoint = currentPoint 
      } 
     } 
    } 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
     if(!isSwiping) { 

      UIGraphicsBeginImageContext(frame.size) 
      image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height)) 


      if let context = UIGraphicsGetCurrentContext() { 
       context.setLineCap(CGLineCap.round) 
       context.setLineWidth(9.0) 
       context.setStrokeColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0) 
       context.move(to: lastTouchPoint) 
       context.addLine(to: lastTouchPoint) 
       context.strokePath() 
       image = UIGraphicsGetImageFromCurrentImageContext() 
       UIGraphicsEndImageContext() 
      } 
     } 
    } 
} 

回答

1

有了这个代码:

UIGraphicsBeginImageContext(frame.size) 
image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height)) 

你说“画这个完整的图像 - 无论大小或纵横比的 - 到宽度x高度尺寸的矩形。”因此,如果image的“原生”尺寸为300 x 200,并且您的frame为200 x 200,那么图像即将绘制。

为了避免这种情况,您需要计算正确的矩形。使用这些尺寸,你会想要做的(对于纵横填):

image?.draw(in: CGRect(x:-50, y:0, width:frame.size.width + 50, height:frame.size.height)) 

当然,而不是硬编码值,你会运行快速计算来确定实际的数字。

0

功能我结束了发现和使用以提供一个方面填充矩形和一个方面配合RECT如下:

func getAspectFillFrame(sizeImageView : CGSize, sizeImage: CGSize) -> CGRect { 

     let aspect = sizeImage.width/sizeImage.height 
     let rect: CGRect 

     if sizeImageView.width/aspect > sizeImageView.height { 

      let height = sizeImageView.width/aspect 

      rect = CGRect(x: 0, y: (sizeImageView.height - height)/2, 
          width: sizeImageView.width, height: height) 

     } else { 
      let width = sizeImageView.height * aspect 
      rect = CGRect(x: (sizeImageView.width - width)/2, y: 0, 
          width: width, height: sizeImageView.height) 
     } 

     return rect 

    } 

    func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect { 

     let imageSize:CGSize = sizeImage 
     let viewSize:CGSize = sizeImgView 

     let hfactor : CGFloat = imageSize.width/viewSize.width 
     let vfactor : CGFloat = imageSize.height/viewSize.height 

     let factor : CGFloat = max(hfactor, vfactor) 

     // Divide the size by the greater of the vertical or horizontal shrinkage factor 
     let newWidth : CGFloat = imageSize.width/factor 
     let newHeight : CGFloat = imageSize.height/factor 

     var x:CGFloat = 0.0 
     var y:CGFloat = 0.0 
     if newWidth > newHeight{ 
      y = (sizeImgView.height - newHeight)/2 
     } 
     if newHeight > newWidth{ 
      x = (sizeImgView.width - newWidth)/2 
     } 
     let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight) 

     return newRect 

    }