New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resized images pixelated - option for better downsampling available? [$300 awarded] #1741
Comments
Got the exact same issue than NewsteadEric. Am adding a $50 bounty. On a side note, am curious on how teespring.com handles this issue. |
Hi Zolomon, From what I understood on Eric's post, he suggests handling the issue by stepping down several times the scaling. For instance, instead of dividing once the scale by 8, divide it by half 3 times. It gives better results see here (http://jsfiddle.net/qwDDP/). There may be even more improvements to bring. Perhaps looking at the interpolation method (linear vs bicubic vs lanczos). All in all, when the image is scaled down server-side with Imagemagick, the sizing is very clean. When scaled down with fabric.js, the quality is as poor as you can see on the 1st fiddle. I'll let @NewsteadEric comment further on this as he may actually have more precised info. |
Hi to everybody,
On this way we shouldn't lose any performance, we shall need a little bit more memory but I think it shouldn't be concern, or maybe I'm wrong? So when we need scaling we will just use 3) point, cause first two's had to be done on initialization. |
would nt be better to have some resize filter implemented in the fabric filter class? |
@ByteRogue > you mention creating sample images that are powers of 2, wouldn't it stretch the image? Unless you have an idea to overcome stretching the image, we may be better off scaling down recursively the image starting from its original ratio. Ok, here's an idea to overcome the streching problem... we could add transparent pixels to a side until we reach a power of 2 ratio, then scaling down as you proposed, and then cropping the artificially added transparent pixels. I read something interesting here: http://stackoverflow.com/questions/6355954/resize-image-without-distortion-keeping-aspect-ratio-then-crop-excess-using-wide?rq=1 |
The image filter idea is excellent. It would be the most idiomatic solution to this problem, and judging by http://fabricjs.com/image-filters/, the performance is probably not going to be (much of) an issue. |
Some progress report:
Left is scaled by hack, right is normally resized. |
Looks pretty good, Andrea. Thanks! On Sun, Nov 2, 2014 at 1:36 AM, Andrea Bogazzi notifications@github.com
|
I added even hermite fast resize alghoritm, working pretty good. |
@NewsteadEric any though on the work so far? do you like it, do you think is good for the bounty, should i go on? |
Any branch available to test the result? Can you create one working version, i.e., plug one of the filter in, fix the mentioned async problem, etc. Please document: How can I apply the filter? Then I can support in testing the performance of the different algorithms on mobile devices. |
Yes, as soon as i get an idea from @NewsteadEric i will finish it and give a repo for testing. |
Asyncronous effect is solved, of course the effect is not immediate, because there are the timings of resize alghoritm to wait. |
@luron01 @NewsteadEric i would make a demo and a PR. |
@asturur |
I think a will make a demo page, ok? 2014-11-07 15:55 GMT+01:00 luron01 notifications@github.com:
|
sure |
@luron01, @NewsteadEric , @kangax , @Kienz ( what a spammer i am ) http://jsfiddle.net/asturur/6qaacwea/12/ or to test more free http://www.deltalink.it/andreab/fabric/resize.html The fiddle has 4 buttons, for normal image, "divide by 2 hack" , hermite algorithm and another try that is a step resize ( instead of dividing by 2 i resize by equal steps to the destination, but is not so good ) You can compare them. comparing to first screenshot i semplified the parameters and the functionality. I will add even lanczosresize maybe. |
Very cool. "slice by 2" seems the blurriest one, at small size. But also the "softest" one, naturally. "Steps hack" still looks a bit pixelated to me, and hermite seems the best. Especially, if you shrink image even more: Notice how hermite is so much clearer than "slice by 2" (which is really blurry). |
the alghoritm are used even for upscaling, just to do not leave that
|
I only just had a chance to check in on this again, and it looks very nice already so far! I'd like to test this with a few different images - the above jsfiddle link (http://jsfiddle.net/asturur/6qaacwea/12/) produces a 404 for me. Where would I find the latest version to test? (I see that http://jsfiddle.net/asturur/6qaacwea/11/ seems to work, but that might be an older version) Eric |
Mayby not so important, but just to mention it: What about very small scale? any improvement possible there? See example with a SVG: http://jsfiddle.net/6qaacwea/13/ |
Just got around to testing this at http://jsfiddle.net/asturur/6qaacwea/11/ - works great so far. A few things:
|
this is the correct link, http://jsfiddle.net/6qaacwea/12/ but the difference is only chrome related. Resize is the same. For your first point, the hit and mis , yes. I think is like that. When you have a zebra, for example, and you have to draw 2 stripes but your scaling gives you just on 1.7 pixel to do that, the result is questionable, if you scale up a little bit and you get to 2 pixels, you can have a prettier render. I think is nothing related to fabric or resize code, i think is normal. Good find for the Png's with transparency, this is gonna be fixed for sure. To improve further we can just try some other algorithms (lanczos and classic trilinear) |
thanks for reporting, i m gonna check it. |
Hi @asturur any update? I am pretty new to this so I am not much a help but reading the documentation, it looks like JSON.stringify(canvas) will call each of its object's toJSON method. So is it this resize filter object's toJSON method not correct? |
Hi @asturur, I am sorry to bug you again, but we really would like to have this issue fix for our release. I would post bounty if need be (have not figured out how to yet, or if only certain people could post bounty). |
i m sorry i got other issues. if you mamage to make a jsfiddle for me, so i have the code causing the problem, i will look into it today. |
Hi, I did not manage to get a jsfiddle, I am not too familiar with that but it will be a quick test to just try to load this JSON: once you load it, you will see that the canvas has one object and that object has width and height of 0. Also once the resize filter is applied, and then if you serialize the canvas, the original image's width and height is changed. |
hi @lionellei, which of the filter are you using? static resize on image load or dynamic resize or both? |
Hi, @asturur , no the issue was there for quite some time, I am just busy with other part of the project that I put off this by tolerating a pixelated scaled down image. I was using static resize filter. The easiest reproduction will be to just load the json I provided above into a canvas and you will see nothing. So just to summarize, the problem is two fold:
|
It's also possible that I maybe doing something wrong. So it will be nice if you could provide some example code, I am sure you must've done some testing when you implemented this. Thanks in advance. |
as soon as i m back ( sunday ) i will make a demo with the functions. so we
|
@lionellei i checked the code and i found those errors:
now everything looks like it is working, as soon as i can i push a PR i have also to check interaction with cropping as a separate issue of course. |
@asturur very nice. I was about to report the last bullet point and you beat me to it :) |
Hi @asturur, is there any fix to this issue? Thanks. |
it has been merged recently. If you want to have a look, another check is even better. |
Hi @asturur, yes it works good in terms of now the filter is saved and could be reloaded. The image quality is better but still not very crisp when scaling down though. |
which is a good filter? do you know.some? lanczos with 8 lobes? filters do
|
I tried this but it really affects performance, browser gets crashed. |
it is taxing yes. use a simpler one, bilinear or slice hack. are way faster.
|
yes right, but that does not provide same accuracy as "lanczos 3". canvas.dispose(); |
can you create a jsfiddle with the problem? 2016-05-06 11:41 GMT+02:00 jitendrapawar notifications@github.com:
|
sorry @asturur, I found that, I called canvas.dispose(); two times. Sorry for the trouble. But can we optimize the "image filtering". Or can you guide me to make it more optimized. |
I'm pushing some control customization this weekend, polishing Itext regressions.From next week i'm gonna watch for general speedup with webgl filtering, i hope i can do something good/cool/performant. |
Can anyone please explain me how image filter lanczos works ? |
@kangax To fix the pixelation of images on resize i used the sliceHack resize filter. After applying them, i resized the image to approx half of its original size and this time the image din’t pixelate. Everything worked perfect, life was awesome before I saved the canvas using Canvas.toJson and the next time when i reloaded the saved backup again on canvas using Canvas.loadFromJson the same resized image is now pixelated. It will be really great if you could help with this. If i resize the image again, anti aliasing will work as expected, but not sure why the anti-alised state was not retained when the images reloaded on canvas using LoadFromJson |
And here's the fiddle that replicates the issue - http://jsfiddle.net/varun598/jagfhh8d/22/ |
I am facing this problem in dynamic patterns. I am attaching a high resolution image as pattern to object. And when trying to create a print version in node the pattern looks in small resolution. |
Regarding https://groups.google.com/forum/?hl=en#!topic/fabricjs/N5LOujX-qMA it would be great to have an option for better resampling when scaling images with fabric:
It looks like fabric.js currently uses only the browser's native/default (bilinear?) resampling capabilities, which usually result in very pixelated, low-quality images when scaling down.
I would like to request a feature that avoids pixelation and resamples images to a higher quality especially when scaling down (similar to http://jsfiddle.net/qwDDP/), e.g. when the user uses the scaling handles on an image element in a fabric.js canvas, or when the scaleX/Y or width/height properties are used.
Depending on performance impact, this could happen during scaling, or when scaling has completed, but should yield a high quality scaled image in any case.
Addendum: As far as text resampling suffers the same issue (which it may not), it would be ideal if that was addressed as well.
The $300 bounty on this issue has been claimed at Bountysource.
The text was updated successfully, but these errors were encountered: