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

ERR_LIBHEIF format not supported #50

Open
zyktrcn opened this issue May 31, 2023 · 11 comments
Open

ERR_LIBHEIF format not supported #50

zyktrcn opened this issue May 31, 2023 · 11 comments

Comments

@zyktrcn
Copy link

zyktrcn commented May 31, 2023

we use heic2any to change heic to jpeg in Android 13, but get an error: ERR_LIBHEIF format not supported.

in our test, heic image is validate.
we have no idea about which type of heic image will get this error.

is there any unsupported heic image with heic2any?

@OlehLoda
Copy link

same issue

@MarianaKWork
Copy link

Getting the same issue here

@rookieDJ
Copy link

same issue

@amilich
Copy link

amilich commented Aug 8, 2023

also seeing this

@shabbir-hossain-ftdl
Copy link

Is there any solution found to this problem?

@ewrfli
Copy link

ewrfli commented Sep 7, 2023

same issue

@sandeep1995
Copy link

same here

@byronwall
Copy link

I struggled with this issue. Turns out I was feeding heic2any garbage data but didn't spot it immediately.

My issue is that I had source image data in a base64 data thing like data:image/heic;base64,blahblahblah. I was doing bad operations to get that data into this library. My context is the browser.

Things to keep an eye on:

  • base64 strings usually have a mime type at the front; you need to remove that
  • base64 data needs to be converted to uint8 array and then make a blob from that
  • you then reverse the process to get a base64 string from the blob created by this library

If you're in the same spot, actual working code looks like:

import heic2any from "heic2any";

export async function convertHEICToPNG(base64Data: string) {
  const uint8Array = convertBase64ToUInt8Array(base64Data);

  const blob = new Blob([uint8Array], { type: "image/heic" });

  let pngBlob = await heic2any({
    blob: blob,
    toType: "image/png",
  });

  // get single png blob if heic2any returns an array
  if (Array.isArray(pngBlob)) {
    pngBlob = pngBlob[0];
  }

  // return base 64 data
  return extractBase64FromBlob(pngBlob);
}

export function convertBase64ToUInt8Array(base64: string): Uint8Array {
  // this is basically a node buffer
  // can get an array buffer with bytes.buffer
  // remove data:image/jpeg;base64, from base64 string if present
  if (base64.startsWith("data:")) {
    base64 = base64.split(",")[1];
  }

  const binary_string = window.atob(base64);
  const len = binary_string.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
  }

  return bytes;
}

export async function extractBase64FromBlob(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onloadend = () => resolve(String(reader.result));
    reader.onerror = reject;

    reader.readAsDataURL(blob);
  });
}

If you want to see "proof that it works", you can visit where I am using this code: https://byroni.us/client-image-ops/

Relevant code pulled from: https://github.com/byronwall/client-image-ops/blob/bb5f2ba1694333c0ff7f532cd8bb6ee9885d00a4/src/utils/heic.ts#L5

@Sonupro1997
Copy link

Sonupro1997 commented Mar 5, 2024

I struggled with this issue. Turns out I was feeding heic2any garbage data but didn't spot it immediately.

My issue is that I had source image data in a base64 data thing like data:image/heic;base64,blahblahblah. I was doing bad operations to get that data into this library. My context is the browser.

Things to keep an eye on:

  • base64 strings usually have a mime type at the front; you need to remove that
  • base64 data needs to be converted to uint8 array and then make a blob from that
  • you then reverse the process to get a base64 string from the blob created by this library

If you're in the same spot, actual working code looks like:

import heic2any from "heic2any";

export async function convertHEICToPNG(base64Data: string) {
  const uint8Array = convertBase64ToUInt8Array(base64Data);

  const blob = new Blob([uint8Array], { type: "image/heic" });

  let pngBlob = await heic2any({
    blob: blob,
    toType: "image/png",
  });

  // get single png blob if heic2any returns an array
  if (Array.isArray(pngBlob)) {
    pngBlob = pngBlob[0];
  }

  // return base 64 data
  return extractBase64FromBlob(pngBlob);
}

export function convertBase64ToUInt8Array(base64: string): Uint8Array {
  // this is basically a node buffer
  // can get an array buffer with bytes.buffer
  // remove data:image/jpeg;base64, from base64 string if present
  if (base64.startsWith("data:")) {
    base64 = base64.split(",")[1];
  }

  const binary_string = window.atob(base64);
  const len = binary_string.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
  }

  return bytes;
}

export async function extractBase64FromBlob(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onloadend = () => resolve(String(reader.result));
    reader.onerror = reject;

    reader.readAsDataURL(blob);
  });
}

If you want to see "proof that it works", you can visit where I am using this code: https://byroni.us/client-image-ops/

Relevant code pulled from: https://github.com/byronwall/client-image-ops/blob/bb5f2ba1694333c0ff7f532cd8bb6ee9885d00a4/src/utils/heic.ts#L5

Didn't work for me. Is there any other solution to convert every heic images to jpeg?

@shabbir-hossain-ftdl
Copy link

shabbir-hossain-ftdl commented Mar 5, 2024

...
Didn't work for me. Is there any other solution to convert every heic images to a jpeg?

I fell into this issue earlier. Please feel free to check my comment above. I found a solution that I want to share...

const setUploadImage = async (variable: any, event: Event) => {
    const input = event.target as HTMLInputElement;
    if (input.files && input.files.length > 0) {
      const file = input.files[0];
      console.log('Selected file:', file);
      ...
      ...
      const heic2any = (await import('heic2any')).default;
      const heicToJpegResponse = await heic2any({
            blob: file,
            toType: 'image/jpeg',
            quality: 1,
      });

      const base64String = await blobToBase64Async(heicToJpegResponse as Blob);
      ...

I needed to convert it to a base64 string but you can take the idea and do what you want with it.

BTW, I used "heic2any": "^0.0.4" version.

@caffeinated-dj
Copy link

caffeinated-dj commented Jun 18, 2024

anyone has a workaround for this?

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