-
-
Notifications
You must be signed in to change notification settings - Fork 699
Pixels shifts (EXIF orientation images) #703
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
Comments
Wow that is strange. I'll have a look. |
Back on this after a break. It looks like it's a problem in reduce, I'll try to make a test case. |
I could make a test case with |
I think we'll have to bump this to 8.7, 8.6 is already horribly delayed. What do you think? |
I agree, let's bump this issue to 8.7. It's just a minor issue that I've encountered. |
FWIW, there are fewer pixels shifts with commit jcupitt@7db1341 (which uses corner convention for down-sampling).
https://github.com/jcupitt/libvips/issues/705 might be relevant here. |
I've set-up a separate repo that reproduces this: https://github.com/kleisauke/vips-issue-703. Output: @jcupitt You may bump this to another milestone, debugging this issue is difficult. 😅 |
Quick update: Corner convention seems to produce more pixel shifts. The output can be viewed here: I also added some debugging notes to quickly reproduce this with the command line: |
This patch seems to partially fix this. Output: The portrait image seems fixed, but the landscape image still produces some pixel shifts. |
I tried to disable the JPEG shrink-on-load feature (commit kleisauke/vips-issue-703@f91737d). It seems to produce more pixel shifts when it's disabled, which makes sense because libvips now have to resize the whole image instead of the last 200%. With this patch applied it generates no visual difference whether shrink-on-load is enabled or disabled. Unfortunately, it still produces some small pixel shifts. |
I've made another attempt to fix this issue, and I may have found a proper solution for at least When I looked at ImageMagick's source code to see how they handle the centre convention, I found something interesting: From the above lines, I assume that the centre convention ( libvips/libvips/resample/reduceh.cpp Lines 337 to 339 in 10c4831
So, I tried to do the same thing: @@ -334,9 +324,7 @@ vips_reduceh_gen( VipsRegion *out_region, void *seq,
q = VIPS_REGION_ADDR( out_region, r->left, r->top + y );
- X = r->left * reduceh->hshrink;
- if( reduceh->centre )
- X += 0.5;
+ X = (r->left + offset) * reduceh->hshrink - offset;
/* We want p0 to be the start (ie. x == 0) of the input
* scanline we are reading from. We can then calculate the p we (where This seems to solve the problems within @@ -544,8 +545,8 @@ vips_reducev_gen( VipsRegion *out_region, void *vseq,
for( int y = 0; y < r->height; y ++ ) {
VipsPel *q =
VIPS_REGION_ADDR( out_region, r->left, r->top + y );
- const double Y = (r->top + y) * reducev->vshrink +
- (reducev->centre ? 0.5 : 0.0);
+ const double Y = (r->top + y + offset) * reducev->vshrink -
+ offset;
VipsPel *p = VIPS_REGION_ADDR( ir, r->left, (int) Y );
const int sy = Y * VIPS_TRANSFORM_SCALE * 2;
const int siy = sy & (VIPS_TRANSFORM_SCALE * 2 - 1); It still produces some pixel shifts (unfortunately), see: @jcupitt Do you have any ideas? The whole patch can be found here. You can safely ignore the |
Hello again, I'll have a few hours this weekend, I'll try to have a look then. Well done for digging on this. |
Let me know if you need any assistance (I could perhaps perform a But then within the coefficients calculations, so perhaps we'll need to check libvips/libvips/resample/templates.h Line 404 in 29d9673
(I tried to change values in there, and I saw an increase in the number of pixel shifts) Also, the above mentioned patch doesn't work when I change the kernel to libvips/libvips/resample/resize.c Line 398 in c7f98ad
|
I just stopped the The test script is available here. It's a simple test where the average value is calculated (rounded to one decimal place) after the EXIF orientation image (without labels) is thumbnailed and converted to greyscale. If all images have the same average value, it will exit with 0, otherwise with 125 (which causes |
fwiw, this bug still seems to be present on the master branch. I'm going to check the coefficients calculations to see if I can find any issues. |
I'm not sure why I didn't test the other resize kernels earlier. I added this kernel (+ the other resize kernels) with commit kleisauke/vips-issue-703@be734f3 and regenerated the output before and after applying this patch: At first sight, it looks like they're all shifting. However, if you look more closely (try to zoom-in 500%) the landscape before image is the only image that is affected by pixel shifts. All other images are not affected. This implicitly means that the (partial) patch is working, but in order to solve this issue completely, a change in coefficients calculations is also necessary. To be continued (I've some spare time tomorrow). |
I managed to (partially) fix the cubic, linear and Mitchell kernel with commit kleisauke/vips-issue-703@19b628e. The idea was to first calculate the kernel radius (rounded to the nearest integer). This integer is then used:
The whole patch can be found here. Here are the before/after results for these kernels: VIPS_KERNEL_LINEAR - before/afterLandscape before: VIPS_KERNEL_CUBIC - before/afterLandscape before: VIPS_KERNEL_MITCHELL - before/afterLandscape before: All portrait images seems to be properly fixed. The landscape images still produce a small pixel shift (unfortunately). This can be clearly spotted if an image is only vertically reduced: TL;DR: the only thing that needs to be resolved is the small pixel shift within |
Fix the pixel shift within reduce (#703)
This should be fixed in 8.10. I'll close. |
Discovered a strange bug when testing the auto rotation of EXIF orientation images, it looks like the pixels are shifting for some images.
Test images:
https://github.com/recurser/exif-orientation-examples
Test case:
bug.zip
Usage:
composer install
php test.php
Output as GIF slideshow:

It's GIF so horrible quality, but you clearly see the (random?) pixel shifts by the portrait images.
Tested with libvips
8.6.0-alpha1
and8.5.7
, the output is the same.The text was updated successfully, but these errors were encountered: