sekoyo / react-image-crop

A responsive image cropping tool for React
ISC License
3.88k stars 344 forks source link

Exif orientation/rotation is being ignored #181

Closed raphaelbeckmann closed 6 years ago

raphaelbeckmann commented 6 years ago

If the image is rotated or flipped via Exif data, this information is not taken care of. As a result, the image is not shown properly in the cropper.

Example images: https://github.com/recurser/exif-orientation-examples

sekoyo commented 6 years ago

What do you mean by not shown properly? All this library does is pass the image source into an image src tag.

raphaelbeckmann commented 6 years ago

Try loading one of the rotated images of the given link into the cropper, e.g. Landscape_6.jpg, and you will see what I mean by saying "not shown properly".

bartoszboruta commented 6 years ago

I can confirm that, for example image captured from iphone: vertical: is in exif orientation 6 horizontal: in exif orientation 1 cropping doesn't work correctly.

https://imgur.com/a/7o6TRBo There is a screenshot, at up left corner You can see image uploaded from iphone (made in vertical phone orientation), at bottom is canvas with crop

sekoyo commented 6 years ago

Sorry I'm still not sure what I'm supposed to be seeing here, Landscape_6 is rotated right? If I look at in GitHub or if I add it to my crop I get the same result?:

screen shot 2018-06-08 at 18 41 17

bartoszboruta commented 6 years ago

@DominicTobias Try to get result in canvas as u showed in example. Image in canvas is displayed in another orientation than in

sekoyo commented 6 years ago

@bartoszboruta so which one is correct? The canvas isn't correct?

bartoszboruta commented 6 years ago

@DominicTobias yes, canvas on ios is in different orientation that original , and when you crop image which is vertical on , cropped fragment is in horizontal orientation, so the cropped fragment is not same as you chose

sekoyo commented 6 years ago

So it sounds like a bug with the browser. This library doesn't do anything special it just displays the image source in an <img> element and by the looks of it the orientation is correct. If you think canvas isn't displaying the right orientation that isn't a result of this library.

From a google search and answers like this https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images

It seems you have to manually rotate the canvas according to the exif orientation: https://github.com/blueimp/JavaScript-Load-Image/blob/master/js/load-image-orientation.js#L54

Here's a blog about using that library if you're stuck: https://nsulistiyawan.github.io/2016/07/11/Fix-image-orientation-with-Javascript.html

abel30567 commented 6 years ago

To solve this issue you need to use the JavaScript Load Image image loader instead of file reader. The blog provided was excellent. Make sure orientation: true is set up as an option when you use the image loader.

nirfuchs73 commented 5 years ago

To solve the issue you need to use the JavaScript-Load-Image library: https://github.com/blueimp/JavaScript-Load-Image and load the input file as follows: loadImage( event.target.files[0], (img) => { var base64data = img.toDataURL('image/jpeg'); this.setState({ imgSrc: base64data }); }, { orientation: true, } );

prashantpatil14 commented 4 years ago

loadImage( event.target.files[0], (img) => { var base64data = img.toDataURL('image/jpeg'); this.setState({ imgSrc: base64data }); }, { orientation: true, } );

"TypeError: img.toDataURL is not a function" When i use JavaScript-Load-Image , Do you have any codepen example

nirfuchs73 commented 4 years ago

Did you import blueimp-load-image ? import loadImage from 'blueimp-load-image/js';

davidbasalla commented 4 years ago

@prashantpatil14 I was having the same issue. When I added canvas: true (which will force img to be a canvas object instead of html img tag) to the options, it worked.

desduvauchelle commented 4 years ago

@nirfuchs73 Did you end up finding out how to import it?

nirfuchs73 commented 4 years ago

@desduvauchelle yes import loadImage from 'blueimp-load-image/js';

desduvauchelle commented 4 years ago

I posted a stackoverflow question for the issue, as it could help other people: https://stackoverflow.com/questions/61327357/react-image-crop-image-rotation-issue-only-in-portrait-mode-of-iphone

mmarcotte commented 4 years ago

I was getting the same error that @prashantpatil14 was reporting with the correct import, and I also observe it on the stackoverflow example @desduvauchelle posted.

I had to add canvas: true to the options object.

I was able to get it to work using this snippet:


  const onSelectFile = (e) => {
    if (e.target.files && e.target.files.length > 0) {
      loadImage(
        e.target.files[0],
        (img) => {
          var base64data = img.toDataURL(`image/jpeg`);
          setUpImg(base64data);
        },
        { orientation: true, canvas: true }
      );
      // const reader = new FileReader();
      // reader.addEventListener('load', () => setUpImg(reader.result));
      // reader.readAsDataURL(e.target.files[0]);
    }
  };