2017-04-05 162 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 

    }