Exif orientation issue #533

Open
opened 2016-12-14 14:37:11 +00:00 by smsoo · 10 comments
smsoo commented 2016-12-14 14:37:11 +00:00 (Migrated from github.com)

Does ng2-file-upload have an option to apply exif orientation on the client side? When a photo is uploaded from the iPhone, it is always rotated 90 degrees. Not sure if there is a workaround for this issue. Any suggestions would be appreciated.

Does ng2-file-upload have an option to apply exif orientation on the client side? When a photo is uploaded from the iPhone, it is always rotated 90 degrees. Not sure if there is a workaround for this issue. Any suggestions would be appreciated.
Gillardo commented 2017-05-26 08:56:49 +00:00 (Migrated from github.com)

I have the same issue when files are uploaded. Is this a bug?

I have the same issue when files are uploaded. Is this a bug?
raeef-refai commented 2017-08-20 11:01:48 +00:00 (Migrated from github.com)

The same issue here

The same issue here
emersonlimap commented 2018-05-07 14:29:39 +00:00 (Migrated from github.com)

Does anybody found the fix for this issue? I'm with the same problen.

Regards.

Does anybody found the fix for this issue? I'm with the same problen. Regards.
livthomas commented 2018-12-17 13:39:49 +00:00 (Migrated from github.com)

I have managed to rotate the image using blueimp-load-image library:

  1. Instal the library by running npm i blueimp-load-image.
  2. Add the following script to your angular.json file:
{
  "projects": {
    "my-project": {
      "architect": {
        "build": {
          "options": {
            "scripts": ["./node_modules/blueimp-load-image/js/load-image.all.min.js"]

Or alternatively, you can include just necessary parts which should result in smaller bundle size:

"scripts": [
  "./node_modules/blueimp-load-image/js/load-image.js",
  "./node_modules/blueimp-load-image/js/load-image-scale.js",
  "./node_modules/blueimp-load-image/js/load-image-meta.js",
  "./node_modules/blueimp-load-image/js/load-image-orientation.js",
  "./node_modules/blueimp-load-image/js/load-image-exif.js"
]
  1. Define this function in some utils file:
declare let loadImage: any;

export function rotateImageBasedOnExifData(file: File): Promise<Blob> {
  return new Promise((resolve, reject) => {
    loadImage.parseMetaData(file, (data) => {
      const orientation = data.exif ? data.exif.get('Orientation') : 0;
      loadImage(
        file,
        (canvas) => canvas.toBlob((blob) => resolve(blob), 'image/jpeg'),
        { canvas: true, orientation }
      );
    });
  });
}
I have managed to rotate the image using [blueimp-load-image](https://www.npmjs.com/package/blueimp-load-image) library: 1. Instal the library by running `npm i blueimp-load-image`. 2. Add the following script to your `angular.json` file: ```json { "projects": { "my-project": { "architect": { "build": { "options": { "scripts": ["./node_modules/blueimp-load-image/js/load-image.all.min.js"] ``` Or alternatively, you can include just necessary parts which should result in smaller bundle size: ```json "scripts": [ "./node_modules/blueimp-load-image/js/load-image.js", "./node_modules/blueimp-load-image/js/load-image-scale.js", "./node_modules/blueimp-load-image/js/load-image-meta.js", "./node_modules/blueimp-load-image/js/load-image-orientation.js", "./node_modules/blueimp-load-image/js/load-image-exif.js" ] ``` 3. Define this function in some utils file: ```typescript declare let loadImage: any; export function rotateImageBasedOnExifData(file: File): Promise<Blob> { return new Promise((resolve, reject) => { loadImage.parseMetaData(file, (data) => { const orientation = data.exif ? data.exif.get('Orientation') : 0; loadImage( file, (canvas) => canvas.toBlob((blob) => resolve(blob), 'image/jpeg'), { canvas: true, orientation } ); }); }); } ```
aharris commented 2019-03-13 01:12:08 +00:00 (Migrated from github.com)

Thanks @livthomas This worked perfectly!

Thanks @livthomas This worked perfectly!
mzane42 commented 2019-06-03 10:43:01 +00:00 (Migrated from github.com)

@livthomas can u add the 4th step, which is how to use this function, do you override thefileitem._file ? if yes, why would you convert this File to a Blob ?

@livthomas can u add the 4th step, which is how to use this function, do you override the` fileitem._file ` ? if yes, why would you convert this File to a Blob ?
livthomas commented 2019-06-03 11:39:59 +00:00 (Migrated from github.com)

@mzane42 Sure, I use it like this to show the image which is being uploaded:

export class MyComponent implements OnInit, OnDestroy {
  public imageUrl$ = new BehaviorSubject<string>('');
  private imageObjectUrl: string;

  private uploader: FileUploader;

  constructor(private domSanitizer: DomSanitizer) {}

  public ngOnInit() {
    this.uploader.onAfterAddingFile = (itemFile) => {
      itemFile.formData = { description: '' };
      rotateImageBasedOnExifData(itemFile._file).then((blob) => {
        this.imageObjectUrl = URL.createObjectURL(blob);
        const imageUrl = this.domSanitizer.bypassSecurityTrustUrl(this.imageObjectUrl);
        this.imageUrl$.next(imageUrl);
      });
    };
  }

  public ngOnDestroy() {
    freeImageObjectUrl(this.imageObjectUrl);
  }
}

And freeImageObjectUrl used in the code above is another of my util functions:

export function freeImageObjectUrl(imageObjectUrl: string) {
  if (!imageObjectUrl) {
    return;
  }

  try {
    URL.revokeObjectURL(imageObjectUrl);
  } catch (e) {
    console.error(e);
  }
}

HTMLCanvasElement has only toBlob method and no toFile. That's the reason why return value type is Blob.

@mzane42 Sure, I use it like this to show the image which is being uploaded: ```typescript export class MyComponent implements OnInit, OnDestroy { public imageUrl$ = new BehaviorSubject<string>(''); private imageObjectUrl: string; private uploader: FileUploader; constructor(private domSanitizer: DomSanitizer) {} public ngOnInit() { this.uploader.onAfterAddingFile = (itemFile) => { itemFile.formData = { description: '' }; rotateImageBasedOnExifData(itemFile._file).then((blob) => { this.imageObjectUrl = URL.createObjectURL(blob); const imageUrl = this.domSanitizer.bypassSecurityTrustUrl(this.imageObjectUrl); this.imageUrl$.next(imageUrl); }); }; } public ngOnDestroy() { freeImageObjectUrl(this.imageObjectUrl); } } ``` And `freeImageObjectUrl` used in the code above is another of my util functions: ```typescript export function freeImageObjectUrl(imageObjectUrl: string) { if (!imageObjectUrl) { return; } try { URL.revokeObjectURL(imageObjectUrl); } catch (e) { console.error(e); } } ``` `HTMLCanvasElement` has only `toBlob` method and no `toFile`. That's the reason why return value type is `Blob`.
mzane42 commented 2019-06-03 11:44:01 +00:00 (Migrated from github.com)

@livthomas Thanks for your fast reply, you're awesome man \o/

@livthomas Thanks for your fast reply, you're awesome man \o/
amartinezg2001 commented 2019-12-18 12:28:17 +00:00 (Migrated from github.com)

Thanks @livthomas
I have this same problem. I have tried to implement the fix you propose, but something I am not doing well.
After step 3, what do I have to do to finish implementing it?

Thanks @livthomas I have this same problem. I have tried to implement the fix you propose, but something I am not doing well. After step 3, what do I have to do to finish implementing it?
livthomas commented 2019-12-18 14:59:18 +00:00 (Migrated from github.com)

@amartinezg2001 You just need to create an object URL, pass it to Angular DOM sanitizer and then use the result as an image source URL in your template. I explained that in my previous comment.

But it's been a year since I posted it here and new versions of both libraries were released in the meantime so there's a chance something has changed and it doesn't work anymore.

@amartinezg2001 You just need to create an object URL, pass it to Angular DOM sanitizer and then use the result as an image source URL in your template. I explained that in my [previous comment](https://github.com/valor-software/ng2-file-upload/issues/533#issuecomment-498222204). But it's been a year since I posted it here and new versions of both libraries were released in the meantime so there's a chance something has changed and it doesn't work anymore.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dc/ng2-file-upload#533