2017-12-22 36 views
0

아래 이미지와 혼합되어 가운데를 회전 한 이미지는 어떻게 얻을 수 있습니까?iOS에서 이미지 회전 및 혼합

이미지 아래에 어떤보기 가든 혼합 된 이미지를 표시하려고합니다. 내 앱에서 사용자는 블렌딩중인 이미지를 이동, 확대 및 회전 할 수 있습니다.

이렇게하려면 하나의 주 이미지 뷰가 있고 블렌드에 사용되는 작은 이미지 뷰 위에 하나 있습니다. 혼합 이미지 뷰 이미지 속성은 위치가 변경 될 때마다 업데이트됩니다.

이미지가 회전하지 않는 한 이미지의 블렌드가 잘 작동합니다. 회전이 바뀌면 바로 내 기능에서 반환 된 이미지가 올바른 위치에 있지 않습니다.

동일한 기능의 2 가지 다른 버전을 사용해 보았습니다.

버전 1 : updateBlendingView

  1. 이미지 뷰
  2. 컨텍스트가 블렌딩 이미지 뷰의 위치에 위치하도록 오프셋에서 메인 이미지 뷰 그릴 배합 크기 컨텍스트를 생성한다.
  3. 이동은 중앙
  4. 의 컨텍스트는
  5. 컨텍스트 및 업데이트 이미지 뷰

버전 2에서 이미지를 얻을의 blendMode와 혼합 이미지 뷰를 그릴 혼합 이미지 뷰

  • 의 회전에 컨텍스트를 회전 : updateBlendingView2

    1. 하는 이미지 뷰
    2. ,745,151 블렌딩 크기 콘텍스트를 생성 그 중심 5,
    3. 이동 컨텍스트
    4. 반비례가 원점 컨텍스트의 원점으로부터의 오프셋에서
    5. 가 회전
    6. 이 혼합도를 그리는 취소 중심으로부터 오프셋 (offset)에서 메인 이미지 뷰 그릴 컨텍스트 회전

      :
    7. 컨텍스트 및 업데이트 블렌딩 이미지 뷰에서

    현재 결과를 이미지를 얻을 0

    enter image description here

    예상 결과 :

    enter image description here

    참고 : 스케치 혼합의 강도가 응용 프로그램 다를 수 있지만, 문제는, 그없는 이미지의 위치에 대해 알아 두셔야합니다 :)

    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 
    } 
    

    어떤 도움을 주시면 감사하겠습니다. 나는 또한 문제를 이해하는 핵심 그래픽에 다른 자습서로 보았다 https://github.com/Gregortega/BlendDemo

    당신은이 링크에서이 문제를 설명하기 위해 작은 데모 프로젝트를 찾을 수 있습니다. Swift: Translating and Rotating a CGContext, A Visual Explanation (iOS/Xcode)

  • 답변

    0

    나는 내 자신의 질문에 답할 것입니다. 친구가 나에게 회전 문제에 대한 해결책을 제시했습니다.

    해결 방법은 혼합 이미지 뷰의 위치 차이 또는 차이를 고려한 것입니다.

    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 
    }