4

i am new bie in IOS Image editing work.

I want to make functionality of Image Warp in ios or swift (any one).

I search lots of googling but not getting exact what i want

below link i am searf

How can you apply distortions to a UIImage using OpenGL ES?

https://github.com/BradLarson/GPUImage

https://github.com/Ciechan/BCMeshTransformView

Here is image what i want (When i touch the grid point image should we wrap and if i place the grid point at original place its should be original like wise)

enter image description here

enter image description here

Community
  • 1
  • 1
Anny
  • 509
  • 1
  • 5
  • 14
  • You are not likely to find exactly what you want as a component you can copy/paste into your code. OpenGL is an advanced, hard-to-learn API, and that's what you'll need in order to accomplish your goal. Realistically, you've got several months of study ahead of you before you're ready to tackle something this complex. – Duncan C Jul 24 '16 at 12:17

2 Answers2

3

I've written an extension for BCMeshTransformView that allows you to apply warp transform in response to user's touch input.

extension BCMutableMeshTransform {
    static func warpTransform(from startPoint:CGPoint,
                              to endPoint:CGPoint, in size:CGSize) -> BCMutableMeshTransform {
        let resolution:UInt = 30
        let mesh = BCMutableMeshTransform.identityMeshTransform(withNumberOfRows: resolution,
                                                                numberOfColumns: resolution)!

        let _startPoint = CGPoint(x: startPoint.x/size.width, y: startPoint.y/size.height)
        let _endPoint = CGPoint(x: endPoint.x/size.width, y: endPoint.y/size.height)
        let dragDistance = _startPoint.distance(to: _endPoint)

        for i in 0..<mesh.vertexCount {
            var vertex = mesh.vertex(at: i)
            let myDistance = _startPoint.distance(to: vertex.from)

            let hEdgeDistance = min(vertex.from.x, 1 - vertex.from.x)
            let vEdgeDistance = min(vertex.from.y, 1 - vertex.from.y)
            let hProtection = min(100, pow(hEdgeDistance * 100, 1.5))/100
            let vProtection = min(100, pow(vEdgeDistance * 100, 1.5))/100

            if (myDistance < dragDistance) {
                let maxDistort = CGPoint(x:(_endPoint.x - _startPoint.x) / 2,
                                         y:(_endPoint.y - _startPoint.y) / 2)

                let normalizedDistance = myDistance/dragDistance
                let normalizedImpact = (cos(normalizedDistance * .pi) + 1) / 2

                vertex.to.x += maxDistort.x * normalizedImpact * hProtection
                vertex.to.y += maxDistort.y * normalizedImpact * vProtection

                mesh.replaceVertex(at: i, with: vertex)
            }
        }
        return mesh
    }
}

Then just set the property to your transformView.

fileprivate var startPoint:CGPoint?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        startPoint = touch.location(in: self)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let startPoint_ = startPoint else { return }
        guard let touch = touches.first else { return }

        let position = touch.location(in: self)
        transformView.meshTransform = BCMutableMeshTransform.warpTransform(from: startPoint_,
                                                                           to: position, in: bounds.size)
    }

The warp code is not perfect, but it gets the job done in my case. You can play with it, but the general idea stays the same.

Yaroslav
  • 2,435
  • 1
  • 19
  • 36
  • It is working great. However, it does not keep the previous transformView state and reset the transformView to its original state as soon as the new touch begins. would be great if you please guide how can I keep the previous state for the transformView so it should not reset with the new touch begins. – Jabbar Sep 06 '22 at 16:39
  • @Jabbar I suppose I was rendering the image every time after updating the mesh and resetting the mesh again, so next time you edit another image. The mesh itself probably will not allow you to be so flexible as to have multiple edits applied to it. I have to say that this is a pretty old code and I definitely don't remember how exactly everything worked. – Yaroslav Sep 12 '22 at 07:35
  • yes it's very old code but it's still working. I have managed to use it from Swift. Any help or suggestion would be great if you could let me know where were you rendering the image at the touchesEnd function or somewhere else. I actually did leave a message on your Twitter handle as well on what I want and shared a demo video there. – Jabbar Sep 12 '22 at 12:19
2

Take a look at my answer to this question:

Warp \ bend effect on a UIView?

You might also look at this git library:

https://github.com/Ciechan/BCMeshTransformView

That might be a good starting point for what you want to do, but you'll need to learn about OpenGL, transformation matrices, at lots of other things.

What you are asking about is fairly straightforward OpenGL. You just need to set up a triangle strip that describes the modified grid points. You'd load your image as a texture, and then render the texture using the triangle strips.

However, "straightforward OpenGL" is sort of like straightforward rocket science. The high-level concepts may be straightforward, but there end up being lots of very fussy details you have to get right in order to make it work.

Take a look at this short video I created with my app Face Dancer

Face Dancer video with grid lines

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thank you Duncan C for nice answer. and i am really suprised that some one down voted the answer. If he know more better answer then please answer the question rather then down voted. – Anny Jul 25 '16 at 04:52