Skip to content

Try gdImageCrop + gdImageScale instead of legacy gdImageCopyResampled #2

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

Merged
merged 1 commit into from
Dec 27, 2014

Conversation

lilith
Copy link
Contributor

@lilith lilith commented Dec 27, 2014

gdImageCopyResampled is retained for compatibility purposes, but in theory should be quite a bit slower than gdImageScale (which defaults to bilinear).

Also, gdImageSharpen is extremely inefficient, and should be avoided in favor of a composed scaling and sharpening weight kernel (which, unfortunately, isn't in the mainstream release yet).

vips-bench doesn't seem to work on OS X (/usr/bin/time: illegal option -- f usage: time [-lp] command., and there are many warnings when linking against vips 7.42.1). I can't run the benchmark myself, but I think these changes may help.

jcupitt added a commit that referenced this pull request Dec 27, 2014
Try gdImageCrop + gdImageScale instead of legacy gdImageCopyResampled
@jcupitt jcupitt merged commit 3ea781c into libvips:master Dec 27, 2014
@jcupitt
Copy link
Member

jcupitt commented Dec 27, 2014

Oh great, thanks, I'll test this. I assumed avoiding the separate crop would be faster.

Yes, the sharpen takes 1s of the 3s run time, ouch.

No, I've not tried to make vips-bench work on OS X, it's too hard to measure memuse portably. You'd need to find some other way to do that.

@lilith
Copy link
Contributor Author

lilith commented Dec 27, 2014

On everything higher-quality than bilinear, we can compose the sharpen and resize kernels, and avoid any overhead whatsoever. The crop and resize operations are also composable. But not in gd 2.1.0. If you build libgd with tiff support, you might be able to make a closer comparison. At minimum there should be a 30% improvement.

Our build script may make that easier, as it builds all the dependencies from source:

export tbs_gd_tiff=1
git clone https://github.com/imazen/gd-libgd
./thumbs.sh make

@jcupitt
Copy link
Member

jcupitt commented Dec 27, 2014

Yes, that does give a speedup. I now see:

$ time ./gd tmp/x.jpg tmp/x2.jpg
real    0m1.247s
user    0m1.166s
sys 0m0.072s
$ time ./vips-c tmp/x.jpg tmp/x2.jpg
real    0m0.393s
user    0m1.268s
sys 0m0.024s

Are your improvements in gd master? I'll try making my own gd.

@lilith
Copy link
Contributor Author

lilith commented Dec 27, 2014

No, our improvements aren't in the gd repository yet. In fact, they're currently designed to work with GDI+, since that was our use case. They're currently AGPL licensed here: https://github.com/imazen/resizer/tree/develop/Plugins/FastScaling

Backporting them to gd will require

  • Swapping the byte order rgba<-->bgra
  • Enabling consecutive memory in libgd allocator (GD 2.3+)
  • 8-bit alpha (GD 2.3+)
  • adapting the interpolation and image structures.

@AGenchev
Copy link

AGenchev commented Jun 11, 2020

what is the purpose of these improvements - to create a fair benchmark with GD ?
if so, then do you "benchmark" the quality of the resampled image ?
I mean that the speed ups often come at a cost, so if you compare the pixel ARGB values differences to a best quality/reference implementation for the given filtering method, then you'll be able to tell whether the quality is OK or not.

@lilith
Copy link
Contributor Author

lilith commented Jun 11, 2020

Both LibGD and libvips differ considerably from reference software such as ImageWorsener. Ideally they would match with only off-by-one errors.

@AGenchev
Copy link

AGenchev commented Jun 17, 2020

What size are the images in your test ?
I created a dHash function which needs 9x8 thumbnail. I run the code on a 416x416 pixels jpeg. Together with the JPEG file load time, the GD based solution works much faster than the vips based one.
The difference is that in vips I create max 128x128 thumbnail, convert it to gray then resample to 9x8 and in GD I use gdImageCopyResampled for direct TrueColor resampling to 9x8 of the whole image, then I convert to gray on pixel read with floating-point multiply.
The reason I don't use direct 9x8 thumbnail-on-load from vips is that in this case, the hamming distance between the vips-created and gdImageCopyResampled dHashes becomes too much. E.t. if gdImageCopyResampled is the reference, the vips-created thumbnail is much different.

@jcupitt
Copy link
Member

jcupitt commented Jun 17, 2020

git master libvips has some improvements to downsample accuracy, it might be worth testing that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants