I haben die folgenden in der Funktions app:die gleiche UIImage mit derselben CGRect Beschneiden gibt unterschiedliche Ergebnisse
- nimmt der Benutzer (oder wählt) ein Bild (im folgenden
originalImage
). - Die
originalImage
wird an eine externe API gesendet, die das Koordinatenfeld der Punkte zurückgibt, die ich zuoriginalImage
hinzufügen muss. - 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. - 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.