How to work with HEIC image file types in Python

后端 未结 6 1002
醉梦人生
醉梦人生 2021-01-31 18:08

The High Efficiency Image File (HEIF) format is the default when airdropping an image from an iPhone to a OSX device. I want to edit and modify these .HEIC files with Python.

相关标签:
6条回答
  • 2021-01-31 18:19

    I was quite successful with Wand package : Install Wand: https://docs.wand-py.org/en/0.6.4/ Code for conversion:

       from wand.image import Image
       import os
    
       SourceFolder="K:/HeicFolder"
       TargetFolder="K:/JpgFolder"
    
       for file in os.listdir(SourceFolder):
          SourceFile=SourceFolder + "/" + file
          TargetFile=TargetFolder + "/" + file.replace(".HEIC",".JPG")
        
          img=Image(filename=SourceFile)
          img.format='jpg'
          img.save(filename=TargetFile)
          img.close()
    
    0 讨论(0)
  • 2021-01-31 18:22

    You guys should check out this library, it's a Python 3 wrapper to the libheif library, it should serve your purpose of file conversion, extracting metadata:

    https://github.com/david-poirier-csn/pyheif

    https://pypi.org/project/pyheif/

    Example usage:

     import whatimage
     import pyheif
     from PIL import Image
    
    
     def decodeImage(bytesIo):
    
        fmt = whatimage.identify_image(bytesIo)
        if fmt in ['heic', 'avif']:
             i = pyheif.read_heif(bytesIo)
    
             # Extract metadata etc
             for metadata in i.metadata or []:
                 if metadata['type']=='Exif':
                     # do whatever
    
             # Convert to other file format like jpeg
             s = io.BytesIO()
             pi = Image.frombytes(
                    mode=i.mode, size=i.size, data=i.data)
    
             pi.save(s, format="jpeg")
    
      ...
    
    0 讨论(0)
  • 2021-01-31 18:22

    This will do go get the exif data from the heic file

    import pyheif
    import exifread
    import io
    
    heif_file = pyheif.read_heif("file.heic")
    
    for metadata in heif_file.metadata:
    
        if metadata['type'] == 'Exif':
            fstream = io.BytesIO(metadata['data'][6:])
    
        exifdata = exifread.process_file(fstream,details=False)
    
        # example to get device model from heic file
        model = str(exifdata.get("Image Model"))
        print(model)
    
    0 讨论(0)
  • 2021-01-31 18:34

    Simple solution after going over multiple responses from people.
    Please install whatimage, pyheif and PIL libraries before running this code.


    [NOTE] : I used this command for install.

    python3 -m pip install Pillow
    

    Also using linux was lot easier to install all these libraries. I recommend WSL for windows.


    • code
    import whatimage
    import pyheif
    from PIL import Image
    import os
    
    def decodeImage(bytesIo, index):
        with open(bytesIo, 'rb') as f:
        data = f.read()
        fmt = whatimage.identify_image(data)
        if fmt in ['heic', 'avif']:
        i = pyheif.read_heif(data)
        pi = Image.frombytes(mode=i.mode, size=i.size, data=i.data)
        pi.save("new" + str(index) + ".jpg", format="jpeg")
    
    # For my use I had my python file inside the same folder as the heic files
    source = "./"
    
    for index,file in enumerate(os.listdir(source)):
        decodeImage(file, index)
    
    0 讨论(0)
  • 2021-01-31 18:37

    I am facing the exact same problem as you, wanting a CLI solution. Doing some further research, it seems ImageMagick requires the libheif delegate library. The libheif library itself seems to have some dependencies as well.

    I have not had success in getting any of those to work as well, but will continue trying. I suggest you check if those dependencies are available to your configuration.

    0 讨论(0)
  • 2021-01-31 18:38

    Adding to the answer by danial, i just had to modify the byte array slighly to get a valid datastream for further work. The first 6 bytes are 'Exif\x00\x00' .. dropping these will give you a raw format that you can pipe into any image processing tool.

    import pyheif
    import PIL
    import exifread
    
    def read_heic(path: str):
        with open(path, 'rb') as file:
            image = pyheif.read_heif(file)
            for metadata in image.metadata or []:
                if metadata['type'] == 'Exif':
                    fstream = io.BytesIO(metadata['data'][6:])
    
        # now just convert to jpeg
        pi = PIL.Image.open(fstream)
        pi.save("file.jpg", "JPEG")
    
        # or do EXIF processing with exifread
        tags = exifread.process_file(fstream)
    

    At least this worked for me.

    0 讨论(0)
提交回复
热议问题