Open confile opened 11 years ago
@meltingice Do you have any idea on this issue?
@confile I can't repro this with my algo (de Casteljau). Either my implementation is incorrect or there's some other difference. Are you getting the same result in GIMP or some other app? Would it be possible for you to provide a screenshot of Photoshop curve and settings?
It is as if PS uses some form of curve fitting on those values. Ie. the values are absolute values the curve passes. In the implementation those are just reference points that may not be never reached. You can actually sort of mimic this with a declaration like this:
this.curves('rgb', [0, 0], [54, 43], [55, 43], [56, 44], [93, 226], [94, 226], [95, 226], [255, 255]);
The more "padding" you add, the sharper the curve. The results are quite close as you can see from this screenshot:
@bebraw Here is my photoshop curve:
I will test it in Gimp as well.
@confile Ok. I think that single curve explains a lot. It is indeed using some form of curve fitting. What my, and I guess @meltingice's algo does, is to interpolate between given control points. There's no curve fitting in place. But as I mentioned you can sort of mimic that by adding more control points (possible in my algo).
@bebraw Here is the same curve with Gimp:
I do not see a difference to what Photoshop did.
Alright. Let's see what @meltingice thinks about curve fitting. I'm not actually sure what it would take algorithm-wise.
@bebraw I could not manage to compile toe coffescript on osx can you please update the dist folder in your repo? Thank you.
The fitting you did with the cure is far away from the result it should be.
@confile The dist of my repo should be up to date. Just remember to look at the right branch (arbitrarycp). You can download the dist version through the web UI.
If you can point me to some curve fitting implementation online (preferably with arbitrary cps), I don't mind having a look.
@bebraw Are the points for your curve like in this graph: http://cubic-bezier.com/ I mean are they not on the curve?
@bebraw If it is not like in Photoshop or in Gimp that the curve is not very useful, because you cannot use them for anything to compare with a Photoshop or Gimp result. What do you think?
@bebraw I tried the branch (arbitrarycp) Using the lomo filter gives this:
@bebraw Are the points for your curve like in this graph: http://cubic-bezier.com/ I mean are they not on the curve?
Exactly. This is how the algorithms work. In my case you can just have an arbitrary amount of control points. It iterates towards the solution (reduces amount of control points to one per t till solved). Bilinear etc. rely on formulas. That makes them nice and fast on low resolution. On high resolution it becomes expensive.
@bebraw If it is not like in Photoshop or in Gimp that the curve is not very useful, because you cannot use them for anything to compare with a Photoshop or Gimp result. What do you think?
It seems PS, GIMP etc. implement actually another variant known as Catmull-Rom spline. As you can see the curves are guaranteed to pass through the control points.
I think we could end up with two variants. The arbitrary one (replaces current implementation) and this. If you need the new behavior, just pass Catmull-Rom generator to curves
as an extra parameter. What would that sound @meltingice? This would allow us to retain backwards compatibility and provide an extension point while at it.
I think that Catmull-Rom spline should be the default one because they are much more common to users. They probably have used Photoshop or Gimp before so this is common to them.
@bebraw What do you think about the bug I posted in the image above where the surrounding of the image is black?
I think for now, using a Catmull-Rom spline should be an opt-in option. We can also consider making it the default with the next major release.
@bebraw I tried the branch (arbitrarycp) Using the lomo filter gives this:
@confile There might be vignette or something in the lomo filter. My work doesn't do any masking.
I would suggest we implement a modified version of Catmull-Rom. That will avoid certain visual artefacts. That Java code there should be relatively easy to port to JS.
I think for now, using a Catmull-Rom spline should be an opt-in option. We can also consider making it the default with the next major release.
What sort of API would you suggest? What if we make it possible to pass a curve generator as an extra argument and default to bezier (backwards compatible). If someone needs Catmull-Rom that can be passed in instead. On 5.0 you could switch to it by default as you suggested.
I can make a separate pull request for this. It might be a good idea to review and merge the current work before that, though.
@bebraw modified version of Catmull-Rom would be great. How much time will it cost you to bring it to JS?
@confile Something like 2-3 hours. I'll try to get this done this week at some point.
@bebraw Great if I can do something beside testing let me know.
@confile Sure!
May be this will help you: https://github.com/sporritt/jsBezier
I found a better source at Unity docs. Need to port that bit of code at the end to CamanJS. Looks pretty straight-forward. Going to give it a go tomorrow.
@bebraw great. I am happy to see it.
@confile I did the initial port. You can see results at jsbin. Note that it renders just the curve itself (flipped y). There is still some glitch with [0, 0]. It has something to do with the way the tangent is calculated although I'm not entirely sure what yet.
Anyway, give it a go and play with the curve to see if you can make it pop in a bad way or something.
@bebraw I did not get it. How do I have to set up a curve? Is it this way: [in_1, out_1], [in_2, out_2],...,[in_n, out_n]
I tried to model the following curve: var points = [[0, 0], [55, 43], [140, 196], [255, 255]];
This is the original in Photoshop:
your approach gives:
@bebraw Okay I see that you have to flip the x-axis and then it is close but there is still this edge at the point 140, 196
@confile Thanks! Looks like the algorithm begins to fail after certain point. I wonder what's going on. Anyway, I'll look into it.
@confile Another go. I flipped it. There was wrong operation at certain place. Do you think it looks acceptable now? Try some special cases to see if we get knots.
@bebraw Great I testet this curve: var points = [[0, 0], [31, 107], [115, 42], [194, 216], [255, 255]];
Photoshop:
Look where the arrow is. It does not look so smooth when you compare it to photoshop. By the way good job.
@confile One more go. I simplified it further. Looks like there's still tiny difference but I'm not sure if it makes any real difference in practice, though.
@bebraw Looks great fantastig job of you. I also think that it will not make any difference in practice.
Will you insert this into Caman.js?
@confile Yup. That's the next step. I'll need to port the code to CoffeeScript and do the necessary tweaks.
As discussed above I'll make it so that you can pass the method to curves
as an optional parameter. After that it will use it instead of the default (bezier). In 5.0 @meltingice can default to it if he wants to.
@confile I suggest you look at #116. ;)
I have the following image:
I tried to apply the following curve:
This is the result in Photoshop:
This is the Camanjs result:
What did I wrong?
Here is a working example: http://jsfiddle.net/confile/DTGXn/