Skip to content
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

No response (success nor error) with HEIC format. #59

Open
scott-schibli opened this issue Jul 16, 2021 · 9 comments
Open

No response (success nor error) with HEIC format. #59

scott-schibli opened this issue Jul 16, 2021 · 9 comments

Comments

@scott-schibli
Copy link

Hello, I am running into problems with compressing a .heic image. It seems that all other image formats work perfectly, but when I use a .heic image, I do not get a response - neither a success or error in my catch.

I guess my question is, I don't seem to find anywhere how to specifically reject the returned promise from the 'resizeFile' method from the Resizer.imageFileResizer() method, how can I do that? Does this package even support heic (I cant find anything online about .heic files relating to this package at all -- curious).

This is my resizeFile method:

const resizeFile = (file: File) => {
return new Promise((resolve) => {
Resizer.imageFileResizer(
file,
1080,
1080,
'JPEG',
80,
0,
(uri) => {
resolve(uri);
},
'base64',
);
});
};

And this is my try catch which I am calling it from:

files.forEach(async (file, i) => {
try {
const image = await resizeFile(file);
const newFile = dataURIToBlob(image);
formData.append(file.name, newFile);
} catch (err) {
console.log(err);
}
});

Expected behavior
I expect a response, either an error or success from passing any type of image.

Desktop (please complete the following information):

  • OS: [e.g. iOS]: Catalina 10.15.5
  • Browser [e.g. chrome, safari]: Chrome
  • Version [e.g. 22]: 91.0.4472.114
@boythan
Copy link

boythan commented Sep 20, 2021

I have same problem.

@dylancrockett
Copy link

dylancrockett commented Oct 13, 2021

I believe it might have something to do with these two lines in the library

b64Data.toString().replace(/^data:image\/(png|jpeg|jpg|webp);base64,/, "")

let fileNameWithoutFormat = fileName.toString().replace(/(png|jpeg|jpg|webp)$/i, "");

As I have looked into this further it is also due to the fact that pretty much no browser apart from Safari supports HEIC as a valid image format (so if you are using Chromium based browsers the fix I mention below wont work). If you are not on safari it looks like you would need some other method for converting from HEIC to something like png, jpeg, or webp first before resizing.

Possible Solution (For Browsers which support HEIC)

I believe I came up with a solution which fixes this problem, which not only applies to heic files but any other image file which is not a png, jpeg, or webp (such as svg).

Change line 95 to be:
b64Data.toString().replace(/^data:image\/(.*);base64,/, "")

Then line 169 to be:
let fileNameWithoutFormat = fileName.toString().replace(/\.[^.]*$/, "").concat(".");

And it should now be able to handle any file which has a mime type like image/*, I wouldn't say this guarantees the file is resized correctly, the file still needs to be able to be displayed on a canvas object to be manipulated (at least I believe this is how the file manipulation is done from looking through the code).

I made these changes to my local version of the library and it is now working with file types like heic and svg. I am not sure what other impacts this might have or what errors may come of this but I think the changes I mentioned are worth looking into.

@mbyrne00
Copy link

mbyrne00 commented Jun 2, 2023

Hey @onurzorluer - any chance of incorporating this suggested fix? Would be nice to support heic in this great simple-to-use lib.

@mbyrne00
Copy link

mbyrne00 commented Jun 2, 2023

This has become less urgent for me, as I forgot that when you don't explicitly accept heic files with your file input and you do accept jpg, then iOS converts them first.

@jovana
Copy link

jovana commented Aug 24, 2023

I have also a workaround, which is very easy to use. Using the heic2any script: https://www.npmjs.com/package/heic2any

Before running the resizer check the image type and convert:

if (file.type === 'image/heic') {
        // file conversion takes a bit.
        file = await heic2any({
            blob: file,
            quality: 0.5
        });
    }

@Andriy-Kulak
Copy link

This has become less urgent for me, as I forgot that when you don't explicitly accept heic files with your file input and you do accept jpg, then iOS converts them first.

Can you explain what you mean by this? I don't get it. iOS on phones converts HEIC to JPEG on the fly? that doesn't make sense

@Andriy-Kulak
Copy link

I have also a workaround, which is very easy to use. Using the heic2any script: https://www.npmjs.com/package/heic2any

Before running the resizer check the image type and convert:

if (file.type === 'image/heic') {
        // file conversion takes a bit.
        file = await heic2any({
            blob: file,
            quality: 0.5
        });
    }

When I try to resize the result of this I get the same error as the original Post on here. Do you do anything specific afterwards?

@mbyrne00
Copy link

mbyrne00 commented Nov 18, 2023

This has become less urgent for me, as I forgot that when you don't explicitly accept heic files with your file input and you do accept jpg, then iOS converts them first.

Can you explain what you mean by this? I don't get it. iOS on phones converts HEIC to JPEG on the fly? that doesn't make sense

Asking for help and telling someone their comment "doesn't make sense" isn't always the best strategy ;-).

Anyway, I don't have the code at hand but if you search around you will see there are various scenarios where iOS devices will automatically convert HEIC to JPG if it's for image requests that do not accept HEIC. For example comments like the one below. I can't remember in the context of this component, but I had a similar experience from memory. For my use cases, this was enough. There may still be valid reasons others want to do it explicitly, however.

Tried a standard input tag with the proper accept attribute
<input type="file" accept="image/jpeg,image/png" />
Selected a HEIC file from Photos in Safari, the selected image was automatically converted to JPEG.

@Andriy-Kulak
Copy link

This has become less urgent for me, as I forgot that when you don't explicitly accept heic files with your file input and you do accept jpg, then iOS converts them first.

Can you explain what you mean by this? I don't get it. iOS on phones converts HEIC to JPEG on the fly? that doesn't make sense

Asking for help and telling someone their comment "doesn't make sense" isn't always the best strategy ;-).

Anyway, I don't have the code at hand but if you search around you will see there are various scenarios where iOS devices will automatically convert HEIC to JPG if it's for image requests that do not accept HEIC. For example comments like the one below. I can't remember in the context of this component, but I had a similar experience from memory. For my use cases, this was enough. There may still be valid reasons others want to do it explicitly, however.

Tried a standard input tag with the proper accept attribute
<input type="file" accept="image/jpeg,image/png" />
Selected a HEIC file from Photos in Safari, the selected image was automatically converted to JPEG.

You're right. sorry wasn't in the best headspace yesterday. thanks for calling my attitude out and quick response/tip to help me resolve this. The solution that seems to work is specifically defining accept image file types to png jpeg, example below.

  const {
    ...
    acceptedFiles,
  } = useDropzone({
    accept: {
      "image/jpeg": [],
      "image/png": [],
    }
  });

<input type="file" accept="image/jpeg,image/png" /> as you suggested will probably work just as well.

just tested and seems to work on mobile iphones well. if the desire is to add ability for people to upload HEIC images from desktop, then something like heic2any will likely be needed although it's not a priority for me either.

Cheers!

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

No branches or pull requests

6 participants