Donaldcwl / browser-image-compression

Image compression in web browser
MIT License
1.3k stars 160 forks source link

Image rotation issue in some cases #10

Closed ske99ey closed 5 years ago

ske99ey commented 5 years ago

When taking a photo on my iPhone X and running it through the imageCompression(file) method it results in a photo that is turned incorrectly. I did not specify the exifOrientation option myself as I see your code accounts for it already (THANK YOU!).

Ex: A portrait taken photo is rotated 90 degrees counter-clockwise (notch at top) or 90 degrees clockwise (notch at bottom). A landscape taken photo will either be correct (power button up) or upside down (power button down).

webnpm commented 5 years ago

me too! When I found out that the exifOrientation was 6 through the test code, the image would be rotated 90 degrees. Have you ever encountered it? 298811558583803_ pic 298821558583825_ pic

webnpm commented 5 years ago
WX20190523-120018@2x WX20190523-120039@2x
Donaldcwl commented 5 years ago

@ske99ey @a953043100 Hi friends, I have tested the library with some images with exifOrientation 6 and I cannot reproduce the issue.

I have added a preview of input and output image on the example webpage, you can try it with your own image: https://raw.githubusercontent.com/Donaldcwl/browser-image-compression/master/example/basic.html

I have used image from "https://github.com/recurser/exif-orientation-examples" Portrait_6.jpg to test and the result is as follow: image-exif-test

You can see that the input file is in wrong rotation while the output is correctly displayed.

Donaldcwl commented 5 years ago

@ske99ey @a953043100 You can also test with the latest release v1.0.5 which contains some fix related to EXIF orientation.

ske99ey commented 5 years ago

Sorry for the delay. I have tested with v1.0.5 in my site and continue to have the issue. I then served up your example via MAMP so I could test it on my phone and was not able to recreate the issue.

I will compare your example with my code and figure out what I am doing wrong. Will report back what I find.

ske99ey commented 5 years ago

@Donaldcwl, I was able to recreate the issue via the example you provided. Unfortunately, not able to get you much more to work with than the provided screenshots below.

Screen shot 1) Bad case of a photo I took Screen shot 2) Good case of a photo I took Screen shot 3) Your example photo from above

In order to recreate things, I hosted the example files via my laptop on a MAMP server and connected to it from my phone. My phone is an iPhone X running iOS 12.4. Using Firefox on my phone, I viewed the basic.html example and selected "Choose File" which prompts me to Take a Photo, Browse Photo Library, or browse file system. For screen shot 1 & 2, I choose to take a photo of the same content in the same orientation (phone in portrait with notch on top). The results vary each time I take a photo. I was able to see cases of both 1 & 2 with no pattern (seems to be random). Lastly, for screen shot 3 I choose file system and selected your photo that I had saved to iCloud storage to be able to select on my phone.

The main thing that caught my eye is in all the cases the input photo is correct and sometimes the output photo is incorrect. In your example posted above, the input photo is incorrect and the output photo is correct. I've never seen the input photo turned like that. It's as if there is some earlier processing (sometimes) on the photo taken that transforms it due to EXIF orientation but doesn't update the value of the EXIF orientation? This is the best guess I have and hope you may be able to track down something more.

Screen shot 1

IMG_5972

Screen shot 2

IMG_5974

Screen shot 3

IMG_5973

ske99ey commented 5 years ago

One additional detail I forgot to mention. The EXIF orientation for all 3 photos in the screenshots reported as 6.

webnpm commented 5 years ago

yeap.. When I used iphone 8 plus, iphone x and mac screenshots to test, I found that the value of exifOrientation is indeed a problem, I don't know if it is a hardware problem.

Donaldcwl commented 5 years ago

@ske99ey @a953043100 Sorry that I don't have a physical iPhone, I cannot follows your steps to reproduce the issue by "Take a Photo".

Can the issue be reproduced by "browse file system"? So that you can send me the photos for debugging. Thanks.

ske99ey commented 5 years ago

Continuing to try more things...making note of observed behavior.

Trying photos from the photo library on my phone reports exif orientations of 6, 1, 8, and 3. The image preview and the output preview are always both displayed correctly (I don't understand how this occurs). I'd expect at least the 6, 8, and 3 orientations to display incorrectly in the preview.

When I move these files to the file system to try them via "Browse", they all report exif orientations of 1.

I've attached the files I used. Let me know what the exif orientations report for you.

IMG_5976 IMG_5977 IMG_5978 IMG_5979

ske99ey commented 5 years ago

I'm still extremely baffled by the fact that the input preview always shows correct regardless of the output preview..even when it reports an exif orientation.

Donaldcwl commented 5 years ago

@ske99ey @a953043100 I just observed, with an IOS simulator, that iPhone will handle the exif orientation itself so the input preview always shows correctly.

So the problem now is why in some cases the output previews are in the wrong orientation. Can anyone upload the image file (pack with zip or rar) that will lead to wrong orientation in output preview? Thanks.

p.s. For now, PC, Mac, and Android do not have this issue. So it is IOS related.

ske99ey commented 5 years ago

I don't believe the issue is any longer associated with iOS. It took me way too long to see the difference so for the rest of this update ignore any previous discussion as its not relevant.

When testing with the example, on my iPhone or others Android devices the photo is always correct. Within where I am using your library, the photo is always incorrect regardless of device unless the photo is taken in an orientation of EXIF 1 since that requires no rotation.

In your example you specify: var options = { maxSizeMB: 1, maxWidthOrHeight: 1024, useWebWorker: useWebWorker }

In my use I specify: var options = { maxSizeMB: 2, useWebWorker: true };

The readme states:

// you should provide one of maxSizeMB, maxWidthOrHeight in the options const options = { maxSizeMB: number, // (default: Number.POSITIVE_INFINITY) maxWidthOrHeight: number, // compressedFile will scale down by ratio to a point that width or height is smaller than maxWidthOrHeight (default: undefined) useWebWorker: boolean, // optional, use multi-thread web worker, fallback to run in main-thread (default: true) maxIteration: number // optional, max number of iteration to compress the image (default: 10) }

It appears there is an issue by not specifying maxWidthOrHeight. If I change my use to specify maxWidthOrHeight then everything works. If I change your example to not specify maxWidthOrHeight then it no longer works.

I believe you will be able to reproduce this issue. Based on the readme stating one or the other should be provided, I'd expect things to work just be providing a maxSizeMB.

ske99ey commented 5 years ago

@Donaldcwl, after further testing and examination of the code I believe I have found what is perhaps the bug among all of this.

In image-compression.js when a file is going through the compressing loop, it is shrunk and then redrawn. On the redraw on line 44, the img is used - not the previously altered canvas that has had the img drawn and exif followed.

I suggest changing line 44 of image-compression.js: ctx.drawImage(img, 0, 0, newWidth, newHeight)

to: ctx.drawImage(canvas, 0, 0, newWidth, newHeight)

This resolved the funky turning issue for me.

Donaldcwl commented 5 years ago

@ske99ey Thanks for the investigation. I will update it in the next release.

ske99ey commented 5 years ago

@Donaldcwl, Thank you!

Do you have an idea of when the next release will be released?

Donaldcwl commented 5 years ago

@ske99ey I have just released v1.0.6. You can try this version ;)

ske99ey commented 5 years ago

Beautiful, works like a charm. Thank you so much yet again!