2017-12-22 15 views
0

Wie kann ich ein Bild erhalten, das mit einem Bild darunter gemischt und um sein Zentrum gedreht wird?Drehen und Bild in iOS swid mischen

Ich versuche, ein Bild zu zeigen, das mit der Ansicht gemischt ist, die sich unter diesem Bild befindet. In meiner App kann der Benutzer das Bild, das eingeblendet wird, verschieben, erweitern und drehen.

Um dies zu tun habe ich eine Haupt-imageView, und oben eine kleinere Bildansicht, die für die Mischung verwendet wird. Die Eigenschaft imageview image wird jedes Mal aktualisiert, wenn sich die Position ändert.

Die Überblendung des Bildes funktioniert gut, solange das Bild nicht gedreht wird. Sobald sich die Drehung ändert, ist das Bild, das von meiner Funktion zurückgegeben wird, nicht an der richtigen Position.

Ich habe 2 verschiedene Versionen der gleichen Funktion ausprobiert.

Version 1: updateBlendingView

  1. schaffen Zusammenhang mit der Größe der Bildansicht
  2. Mischen der Hauptbildansicht auf eine so versetzt ziehen, dass der Kontext an der Position des Mischbildansicht ist.
  3. bewegt der Kontext zu seinem Zentrum
  4. drehen, um den Kontext zu der Rotation des Mischimageview
  5. das Mischungsimageview mit blendmode zeichnen
  6. Bild aus dem Kontext und Update Imageview

Version 2 erhalten : updateBlendingView2

  1. Kontext mit Größe des Mischens Bildansicht
  2. erstellen
  3. move Kontext seines Zentrum drehen
  4. invers den Kontext
  5. die Hauptbildansicht auf einem von der Mitte
  6. das Drehen
  7. undo Versatzzeichnungs die Mischungs Ansicht zieht es Ursprung vom Ursprung des Kontextes versetzt ist
  8. erhalten Bild von Kontext und Aktualisierung Blending Imageview

Aktuelles Ergebnis:

enter image description here

Erwartetes Ergebnis:

enter image description here

Hinweis: hält die Intensität der Vermischung in der Skizze im Kopf aus dem App abweichen, aber das Problem ist nicht, geht es um die Bildposition:)

func updateBlendingView() { 

    guard let mainViewImage = getImageFromView(view: mainImageView) else {return} 

    // Reset image to original state before blending 
    blendingImageView.image = UIImage(named: "square")! 
    guard let blendingImage = getImageFromView(view: blendingImageView) else {return} 

    UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale) 
    guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return} 

    let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5)) 

    let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a)) 
    let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians)) 

    let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x , y: -blendingImageView.frame.origin.y) 
    mainViewImage.draw(at: mainViewOrigin) 

    context.concatenate(blendingOriginTransform) 
    context.concatenate(rotateTransform) 


    let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5) 
    blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5) 

    guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else { 
     UIGraphicsEndImageContext() 
     return 
    } 

    UIGraphicsEndImageContext() 

    blendingImageView.image = blendedImage 
} 

func updateBlendingView2() { 

    guard let mainViewImage = getImageFromView(view: mainImageView) else {return} 

    // Reset image to original state before blending 
    blendingImageView.image = UIImage(named: "square")! 
    guard let blendingImage = getImageFromView(view: blendingImageView) else {return} 

    UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale) 
    guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return} 

    let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5)) 

    let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a)) 
    let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians)) 

    context.concatenate(blendingOriginTransform) 
    context.concatenate(rotateTransform.inverted()) 

    let mainViewOrigin = CGPoint(x: -blendingImageView.frame.origin.x - (blendingImageView.bounds.width * 0.5) , y: -blendingImageView.frame.origin.y - (blendingImageView.bounds.height * 0.5)) 
    mainViewImage.draw(at: mainViewOrigin) 

    // undo the rotate 
    context.concatenate(rotateTransform) 

    let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5) 
    blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5) 

    guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else { 
     UIGraphicsEndImageContext() 
     return 
    } 

    UIGraphicsEndImageContext() 
    blendingImageView.image = blendedImage 
} 

func getImageFromView(view: UIView) -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, UIScreen.main.scale) 
    guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return nil} 
    view.layer.render(in: context) 
    let snapshotImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return snapshotImage 
} 

Jede Hilfe würde geschätzt werden, vielen Dank. Sie können ein kleines Demo-Projekt finden diese Frage in diesem Link zu illustrieren https://github.com/Gregortega/BlendDemo

ich auch in verschiedene Tutorials auf Core-Grafik ausgesehen haben, das Problem zu verstehen. Swift: Translating and Rotating a CGContext, A Visual Explanation (iOS/Xcode)

Antwort

0

Ich werde meine eigene Frage beantworten. Ein Freund gab mir eine Lösung für das Rotationsproblem.

Die Lösung bestand darin, den Unterschied oder die Änderung der Position des Blending-Bilds zu berücksichtigen.

func updateBlendingView2(xDiff: CGFloat = 0, yDiff: CGFloat = 0) { 

    guard let mainViewImage = getImageFromView(view: mainImageView) else {return} 

    // Reset image to original state before blending 
    blendingImageView.image = UIImage(named: "square")! 
    guard let blendingImage = getImageFromView(view: blendingImageView) else {return} 

    UIGraphicsBeginImageContextWithOptions(blendingImageView.bounds.size, true, UIScreen.main.scale) 
    guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext();return} 

    // X, Y translation 
    let blendingOriginTransform = CGAffineTransform(translationX: (blendingImageView.bounds.width * 0.5), y: (blendingImageView.bounds.height * 0.5)) 
    context.concatenate(blendingOriginTransform) 

    // Rotation 
    let radians:Float = atan2f(Float(blendingImageView.transform.b), Float(blendingImageView.transform.a)) 
    let rotateTransform: CGAffineTransform = CGAffineTransform(rotationAngle: CGFloat(radians)) 
    context.concatenate(rotateTransform.inverted()) 

    var mainViewOrigin = self.lastMainViewOrign 
    mainViewOrigin = CGPoint(x: mainViewOrigin.x + xDiff, y: mainViewOrigin.y + yDiff) 
    mainViewImage.draw(at: mainViewOrigin) 
    self.lastMainViewOrign = mainViewOrigin 

    // undo the rotate 
    context.concatenate(rotateTransform) 

    let blendingDrawingOrigin = CGPoint(x: -blendingImageView.bounds.width * 0.5, y: -blendingImageView.bounds.height * 0.5) 
    blendingImage.draw(at: blendingDrawingOrigin, blendMode: .multiply , alpha: 0.5) 

    guard let blendedImage = UIGraphicsGetImageFromCurrentImageContext() else { 
     UIGraphicsEndImageContext() 
     return 
    } 

    UIGraphicsEndImageContext() 
    blendingImageView.image = blendedImage 
}