GithubHelp home page GithubHelp logo

alexcorvi / heic2any Goto Github PK

View Code? Open in Web Editor NEW
575.0 8.0 74.0 7.38 MB

Converting HEIF/HEIF image formats to PNG/GIF/JPEG in the browser

Home Page: https://alexcorvi.github.io/heic2any/

License: MIT License

JavaScript 25.93% HTML 29.83% TypeScript 44.25%
heic heic-to-jpg image-conversion

heic2any's Introduction

HEIC2ANY

Demo, Documentation & more

Client-side (browser-side, using Javascript) conversion of HEIC/HEIF image files to JPEG, PNG, or GIF.

What is HEIC format?

High Efficiency Image File Format (HEIC) is a new image container format from the developers of MPEG, a popular audio and video compression standard. HEIC will be used by default on new photos on iOS 11, and it’s designed to save you storage space. As it’s a new container format, there will be some incompatibilities along the way, and Apple does a good job at handling most of these. iOS 11 will automatically share HEIC files as the default JPEG format for apps, so you won’t notice anything when you share a photo on Twitter or Instagram. iOS 11 also offers to automatically transfer photos and videos in a compatible format for Mac or PC users, useful if you’re simply plugging your iPhone into your laptop or PC. theverge.com

Why you might need it?

While developing some web-based application that should be able to handle mobile uploads, I've come across a problem where browsers can not display certain images uploaded from the iPhone, after investigating through the issue, I noticed that that my iPhone was giving a heic formatted image.

Currently there are zero web browsers that support HEIC photos. Even Apple's latest-greatest version of Safari can't decode HEIC and doesn't recognize the "image/heic" mimetype. A solution that came across my mind is to utilize the benefits of high resolution and low storage of heic images when storing in the server and client-side conversion to JPEG for viewing on the browser.

Usage and limitations

This library would typically be used for viewing purposes, as currently it's not focusing on copying any metadata from the original heic file to the output jpeg, gif or png. The development process of this library is focusing on viewing a browser-consumable version of an heic file, and doing it quickly, asynchronously (using web workers) and accurately. This library would even convert heic containers that have multiple heic images into an animated gif.

However, if you're planning on storing the files (not just viewing them), I'd suggest you look for a server-side tool, or you try to get your hands dirty and contribute to this library and make it capable of storing metadata.

Last but not least, this tool is specifically for the browser environment, it will not work in node environment.

Known issues

Those are the known issues of the library, pull requests are welcome:

  1. Library doesn't take any metadata from the original file, resulting file doesn't have any metadata.
  2. Library can convert bursts into an animated gif, however when a heic animation is given (like the stars animation in the demo) library will only take the first shot of the animation.
  3. Support for IE11 is not here yet.
  4. The library requires a browser-like environment to work, i.e. it needs the existence of the DOM and window object.

heic2any's People

Contributors

alexcorvi avatar madsmadsen avatar zzarcon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

heic2any's Issues

Conversion slow

Converting a 1.6mb HEIC image is taking about 5 seconds. Is this normal? And is there any way to speed it up?

My code:
...
const start = window.performance.now();
let image = await heic2any({ blob:file });
const stop = window.performance.now();
console.log('Elapsed time for heic2any: ${(stop - start) / 1000}s');
...

Result in console log:
Elapsed time for heic2any: 5.121s

For the sake of comparison, I tried converting the same image to PNG before uploading, which resulted in a 14.6mb file and it still only took 0.1 seconds for the entire upload.

react native; ERROR ReferenceError: Property 'Worker' doesn't exist, js engine: hermes

I having this issue while running this code:

const a = fetch(pickerResult.fileCopyUri)
          .then(res => res.blob())
          .then(blob => {
            console.info(blob);
            return heic2any({
              blob,
              toType: 'image/jpeg',
              quality: 0.5, // cuts the quality and size by half
            });
          })
          .then(conversionResult => {
           // conversionResult is a BLOB
           // of the JPEG formatted image
           // with low quality
           })
          .catch(e => {
            console.error('Error at onPressStart()', e);
            // see error handling section
          });

console log:

 ERROR  ReferenceError: Property 'Worker' doesn't exist, js engine: hermes

at file heic2any.js (23:33)

Converted file size is too big

Converted file size from regular image shot by Iphone camera is 10 times larger in result comparing 1.8mb & 16mb in result.

Uncaught SyntaxError: Invalid or unexpected token

When including this package in my vue3 app, I get the following error:
Uncaught SyntaxError: Invalid or unexpected token (at

Which points to this line: https://github.com/alexcorvi/heic2any/blob/3428539e643e112323a5b8a2c77c6402cb1372f6/dist/heic2any.js#L21

The workerString is too big, but here is the specific spot it is failing on:
isWindows:!(bA=\"data:application/octet-stream;base6

I think this workerString should be a dependency. Where is it's sourcecode? This one single line is 1.3MB in size...

Cannot assign to read only property stack of object 'Error: No such file or directory'

I'm getting the below error when triging to use it in an angular application. Any reason why & if it's supposed to be used in that way?

What I did:
Import in package.json
"heic2any": "0.0.2"
In a component, copy the exact code from the typescript tutorial.

index.js:1 Uncaught TypeError: Cannot assign to read only property 'stack' of object 'Error: No such file or directory'
    at index.js:1
    at Array.forEach (<anonymous>)
    at Object.ensureErrnoError (index.js:1)
    at Object.staticInit (index.js:1)
    at Object.<anonymous> (index.js:1)
    at Object../node_modules/heic2any/dist/index.js (index.js:430)
    at __webpack_require__ (bootstrap:79)
    at Module../src/app/image-converter/image-converter.component.ts (main.js:588)
    at __webpack_require__ (bootstrap:79)
    at Module../src/app/app-routing.module.ts (main.js:341)

Content Security Policy error

Hi,
I'm getting this error:

Content Security Policy: The page’s settings blocked the loading of a resource at
blob:https://localhost/e674b31d-9638-6947-880b-d26cbd237e8d (“worker-src”).

what could be the reason and the solution?

Argument of type 'Blob | Blob[]' is not assignable to parameter of type 'Blob'.

I'm doing:

        const heicReader = new FileReader();

        heicReader.onload = async () => {
          const heicImageString = heicReader.result;

          const { download_url } = await uploadPhotoToGcs({
            base64: heicImageString,
            type: 'image/png',
          });
          this.onSubmitImageMessage(download_url);
        };

        const blobUrl = URL.createObjectURL(imageData);
        const blobRes = await fetch(blobUrl);
        const imgBlob = await blobRes.blob();
        const convertedFile = await heic2any({ blob: imgBlob });

        heicReader.readAsDataURL(convertedFile);
        return;

And the heicReader.readAsDataURL(convertedFile); complains about:

const convertedFile: Blob | Blob[]
Argument of type 'Blob | Blob[]' is not assignable to parameter of type 'Blob'.
  Type 'Blob[]' is missing the following properties from type 'Blob': size, type, arrayBuffer, stream, text

Does not work on Safari

Here is my convertHeic function:

export async function convertHeic(heicFile: File) {
  const heic2any = require("heic2any");
  const convertedBlob = await heic2any({ blob: heicFile });
  const convertedFile = new File([convertedBlob], `${uuidv4()}.png`, {
    type: "image/png",
  });
  return { convertedBlob, convertedFile };
}

Here is my convertedFile:

convertedFile = {
    lastModified: 1702502344687,
    name: "23b275b5-b261-4fa2-b240-3c878d9047b8.png",
    size: 213143,
    type: "image/png",
    webkitRelativePath: ""
}

Working beautifully on Chrome. Breaks on Safari --> photo simply displays as a transparent box.

Using NextJS.

@alexcorvi any thoughts?

我得到了一个错误的图片

1
myHeicFile.zip
我的heic图片转换完后是这个样子的?是否是因为图片的编码不同还是有些必要的参数我没有填写?

十分感谢

Here is machine translation:

What does my Heic image look like after conversion? Is it because the encoding of the images is different or are there some necessary parameters that I did not fill in?

Performance

One of the problems i see is that this library can not change the file dimensions.
It processes 4k image to 4k image. Could be cool if it could also rescale the image size

Reference error: Blob is not defined

Hi , I'm trying to implement heic2any in my project , but the very first thing that blocks me from moving on is the error in my log that shows Reference error : Blob is not defined .
image

I have no idea how to fix this and can't find related resources online .

Really appreciate if someone could help!

Thanks

No Support for Server Side Rendering.

Hi, #@alexcorvi
can you please help me out with this library to be used in server-side Rendering Cases as no Single-page Application Supports Meta-Sharing without server-side rendering. So can you help me in just adding few checks for Browser Side Rendering?

ERR_LIBHEIF format not supported

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?

EXIF GPS latitude and longitude are lost when HEIC is converted to jpeg

Here is the file that I tried to convert to jpeg (please unzip it to get the original HEIC image) and output jpeg does not contain EXIF GPS data.

cheers.heic.zip

The code is as follows:

        const HEICBlobFile: Blob = await this.makeImageIntoBlob(heicImagePath);

        const JPEGBlobFile: Blob = await heic2any({
            // required: the HEIF blob file
            blob: HEICBlobFile,
            // (optional) MIME type of the target file
            // it can be "image/jpeg", "image/png" or "image/gif"
            // defaults to "image/png"
            toType: 'image/jpeg',
            // conversion quality
            // a number ranging from 0 to 1
            quality: 0.8
        });

and then I save the jpeg file and it has no GPS data in EXIF.

convert to JPEG in Demo.

I'm curious why this converts to GIF (which is not designed for photos) rather than to JPEG (which is what most people want).

Either JPG should be the default or there should be a pull-down to allow people to select.

  • Enhancement (I can't give this issue a label)

"ReferenceError: Blob is not defined" error when using with NextJS

Getting "ReferenceError: Blob is not defined" error when doing a build in NextJS. Works fine in development and my .heic image is converted on the client side like I want but when doing a build to deploy it to production I get this error.

Here is where I use it in my code:

  const onDrop = useCallback(async (files) => {
    setFiles(
      await Promise.all(
        files.map(async (file) => {
          let result;
          if (file.type === "image/heic") {
            setConvertingImage(true);
            result = await heic2any({
              blob: file,
              toType: "image/jpeg",
            });
            setConvertingImage(false);
          } else {
            result = file;
          }

          return Object.assign(file, {
            preview: URL.createObjectURL(result),
          });
        })
      )
    );
  }, []);

I'm thinking it may have to do with the fact that NextJS is Server Side Rendered and when heic2any is executed on the server something funny happens?

Not working on Chrome for android

It looks like call to heic2any in Chrome for android never finishes execution. Same on iOS.

const jpegBlob = await heic2any({
// required: the HEIF blob file
blob: file,
// (optional) MIME type of the target file
// it can be "image/jpeg", "image/png" or "image/gif"
// defaults to "image/png"
toType: 'image/jpeg',
// conversion quality
// a number ranging from 0 to 1
quality: 0.5,
});

Did anyone manage to make it work on mobile browsers?

Memory leak in decodeBuffer

The following code creates a new function reference and never frees it.

heic2any/src/heic2any.ts

Lines 202 to 212 in 3222e59

((window as any).__heic2any__worker as Worker).addEventListener(
"message",
(message) => {
if (message.data.id === id) {
if (message.data.error) {
return reject(message.data.error);
}
return resolve(message.data.imageDataArr);
}
}
);

Subsequent calls to heic2any will create a new instance of the message handler. Both handlers will be called. Converting Nth image will create Nth event handler and all N handler will receive message notifications.

Proposed fix: chebum@c6fab0a

Fixed heic2any.js is available here: https://github.com/chebum/heic2any/tree/master/dist

The fix also includes pull request #27

distorted image

I am using the library to upload images to the server. very occasionally a client uploads an image and it appears distorted.
searching about the problem I found this:

filecoin-project/slate#200

The exact same thing happens to me in the image.

Error on IE 11

Hello, it's me again.
Wish you a good day.
Today I have a problem with IE. It looks like heic2any does not support IE 11. I also tried running your demo in IE 11 and also encountered an error. I wish you could review it
Thank!

ERROR : Can't resolve 'fs'

Thank you for the tool!
I had an error adding the library to my component.
"ERROR in ./node_modules/heic2any/dist/index.js
Module not found: Error: Can't resolve 'fs' in 'D:\projects\myproject\node_modules\heic2any\dist'
"

Can you suggest how to fix it?

Does not work on iPhone

It works on Chrome browser on my laptop but does not wok on Safari on iPhone. Does it expected behavior?

Converted image has less than 3 channels

How many channels does resulted image have?
After converting file with heic2any I send it to machine learning script on server & it is constantly returns error with reason: Image should have at least 3 channels

converted image url comes back undefined

Hi!

Thanks for creating this library, I've been tearing my hair out wondering how to display heic images, but I am having some issues using the library locally.

Here is a repo that you can run locally and check what the issue is, and this is the code where I try to convert the image:

  useEffect(() => {
    const heic2any = require('heic2any');
    if (typeof window !== 'undefined') {
      fetch('https://alexcorvi.github.io/heic2any/demo/14.heic')
        .then((res) => res.blob())
        .then((blob) =>
          heic2any({
            blob,
          })
        )
        .then((conversionResult) => {
          setImg(URL.createObjectURL(conversionResult));
        })
        .catch((e) => {
          console.log(e);
        });
    }
  }, []);

Essentially, when I try use URL.createObjectURL, the url that is created for the image returns a 404 page not found when I try to open it.

Would appreciate any help with this!

Web workers

Hi,

The description indicates that the library can be used asynchronously using web workers.

When importing a library into a web worker, I got an error:
Uncaught ReferenceError: window is not defined.

Is there a solution?

Any plans of an ECMAscript version of heic2any?

We are using heic2any in our Angular 11 project, and we love it since it solved the issues we had with images uploaded from iOS.

But using commonJS can raise some drawbacks that we would like to avoid. So I am wondering if you have any plans of creating an ECMAscript version of heic2any... e.g. heic2any-es?

This is the warning I get when compiling the Angular project:

Warning: /home/xyz/myApp/src/app/_components/message-composer/message-composer.component.ts depends on 'heic2any'. 
CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

I know this warning is not the end of the world, but I like to keep things clean :-)

Not Working With MS Edge Browser

Hi,

I have also tried this plugin on Edge browser but this is coming as a outcome- "TypeError: Object doesn't support property or method 'toBlob'"

Any Suggestions would be appreciated!!!

Script Freezes on production deploy

Hello, thanks for creating this heic2any library for us.

I'm using nuxtjs, and running the nuxt build command to minify and prepare the project source code for a production deploy. See: https://nuxtjs.org/guide/commands#server-side-rendered-deployment-universal-ssr-

This is the minimal code I'm using at the moment:

var heic2any = require('heic2any');
file = await heic2any({
    blob: file,
    toType: "image/jpeg",
    quality: 0.75,
});

In dev-mode is works fine, though once in production mode my whole browser freezes and my cpu usage goes through the roof. This happens on all browsers and can be reproduced on other people's devices as well.
Also, there is no errors in the console

( Mac High Sierra 10.13 - on Firefox, Chrome, and Safari)

Also, on mobile IOS devices via Safari, it still breaks, though the image conversion breaks and the resulting output image is a broken image. See below:
image

Any idea whats going on?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.