2016-09-15 4 views
0

I haben die folgenden in der Funktions app:die gleiche UIImage mit derselben CGRect Beschneiden gibt unterschiedliche Ergebnisse

  1. nimmt der Benutzer (oder wählt) ein Bild (im folgenden originalImage).
  2. Die originalImage wird an eine externe API gesendet, die das Koordinatenfeld der Punkte zurückgibt, die ich zu originalImage hinzufügen muss.
  3. Da die Punkte immer in einem Bereich (Gesicht) liegen, möchte ich die originalImage in der Nähe der Gesichtsränder zuschneiden und dem Benutzer nur das Ergebnis der Zuschneidung anzeigen.
  4. Nachdem das Crop-Ergebnis angezeigt wird, füge ich Punkte nacheinander hinzu.

Hier ist der Code, der die Arbeit erledigt (außer Bild zu senden, lassen Sie uns sagen, dass es bereits geschehen ist)

class ScanResultViewController{ 

    @IBOutlet weak var scanPreviewImageView: UIImageView! 

    let originalImage = ORIGINAL_IMAGE //meaning we already have it 

    let scanDots = [["x":123, "y":123], ["x":234, "y":234]]//total 68 coordinates 

    var cropRect:CGRect! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.setScanImage() 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 

     self.animateScan(0) 
    } 


    func setScanImage(){ 

     self.cropRect = self.getCropRect(self.scanDots, sourceImage:self.originalImage) 

     let croppedImage = self.originalImage.imageAtRect(self.cropRect) 

     self.scanPreviewImageView.image = croppedImage 
     self.scanPreviewImageView.contentMode = .ScaleAspectFill 

    } 


    func animateScan(index:Int){ 

     let i = index 

     self.originalImage = self.addOnePointToImage(self.originalImage, pointImage: GREEN_DOT!, point: self.scanDots[i]) 

     let croppedImage = self.originalImage.imageAtRect(self.cropRect) 

     self.scanPreviewImageView.image = croppedImage 
     self.scanPreviewImageView.contentMode = .ScaleAspectFill 

     if i < self.scanDots.count-1{ 

      let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
      dispatch_after(delay, dispatch_get_main_queue()) { 

       self.animateScan(i+1) 
      } 
     } 
    } 


    func addOnePointToImage(sourceImage:UIImage, pointImage:UIImage, point: Dictionary<String,CGFloat>)->UIImage{ 

     let rect = CGRect(x: 0, y: 0, width: sourceImage.size.width, height: sourceImage.size.height) 

     UIGraphicsBeginImageContextWithOptions(sourceImage.size, true, 0) 
     let context = UIGraphicsGetCurrentContext() 

     CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor) 
     CGContextFillRect(context, rect) 

     sourceImage.drawInRect(rect, blendMode: .Normal, alpha: 1) 

     let pointWidth = sourceImage.size.width/66.7 

     pointImage.drawInRect(CGRectMake(point["x"]!-pointWidth/2, point["y"]!-pointWidth/2, pointWidth, pointWidth), blendMode: .Normal, alpha: 1) 

     let result = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return result 
    } 


    func getCropRect(points: Array<Dictionary<String,CGFloat>>, sourceImage:UIImage)->CGRect{ 

     var topLeft:CGPoint = CGPoint(x: points[0]["x"]!, y: points[0]["y"]!) 
     var topRight:CGPoint = CGPoint(x: points[0]["x"]!, y: points[0]["y"]!) 
     var bottomLeft:CGPoint = CGPoint(x: points[0]["x"]!, y: points[0]["y"]!) 
     var bottomRight:CGPoint = CGPoint(x: points[0]["x"]!, y: points[0]["y"]!) 

     for p in points{ 

      if p["x"]<topLeft.x {topLeft.x = p["x"]!} 
      if p["y"]<topLeft.y {topLeft.y = p["y"]!} 

      if p["x"]>topRight.x {topRight.x = p["x"]!} 
      if p["y"]<topRight.y {topRight.y = p["y"]!} 

      if p["x"]<bottomLeft.x {bottomLeft.x = p["x"]!} 
      if p["y"]>bottomLeft.y {bottomLeft.y = p["y"]!} 

      if p["x"]>bottomRight.x {bottomRight.x = p["x"]!} 
      if p["y"]>bottomRight.y {bottomRight.y = p["y"]!} 

     } 

     let rect = CGRect(x: topLeft.x, y: topLeft.y, width: (topRight.x-topLeft.x), height: (bottomLeft.y-topLeft.y)) 

     return rect 
    } 

} 

extension UIImage{ 

    public func imageAtRect(rect: CGRect) -> UIImage { 
     let imageRef: CGImageRef = CGImageCreateWithImageInRect(self.CGImage, rect)! 
     let subImage: UIImage = UIImage(CGImage: imageRef) 

     return subImage 
    } 

} 

Das Problem ist, dass der gewünschte Bereich genau abgeschnitten und angezeigt wird in setScanImage, aber wenn animateScan Methode heißt ein anderer Bereich des gleichen Bildes wird beschnitten (und angezeigt) obwohl cropRect ist das gleiche und die Größe von originalImage ist völlig gleich.

Irgendwelche Ideen, Leute?

Übrigens, wenn ich originalImage ohne Zuschneiden anzeigen, funktioniert alles reibungslos.

Antwort

0

So schließlich nach ca. 10 Stunden Netto-Zeit ( und eine Menge Hilfe der Gemeinschaft Stackoverflow :-) ich es geschafft, das Problem zu beheben:

In der Funktion addOnePointToImage Sie müssen Folgendes ändern:

In dieser Zeile:

UIGraphicsBeginImageContextWithOptions(sourceImage.size, true, 0) 

Sie das letzte Argument ändern müssen (die Skala steht) bis 1:

UIGraphicsBeginImageContextWithOptions(sourceImage.size, true, 1) 

Das löst das Problem vollständig.

Verwandte Themen