bigcat88 / pillow_heif Goto Github PK
View Code? Open in Web Editor NEWPython library for working with HEIF images and plugin for Pillow.
License: BSD 3-Clause "New" or "Revised" License
Python library for working with HEIF images and plugin for Pillow.
License: BSD 3-Clause "New" or "Revised" License
If you have a PNG image with mode P
and a custom transparency
value, opacity information is lost when you convert to HEIC.
from PIL import Image, ImageDraw
from pillow_heif import register_heif_opener
register_heif_opener()
# Draw a basic checkerboard image
im = Image.new("P", size=(100, 100))
draw = ImageDraw.Draw(im)
draw.rectangle(xy=[(0, 0), (50, 50)], fill=255)
draw.rectangle(xy=[(50, 50), (100, 100)], fill=255)
# Save the image as a PNG, marking the 0'th colour in the palette as transparent
im.save("checkerboard.png", transparency=0)
# Open the image, then save it as an AVIF
opened_im = Image.open("checkerboard.png")
opened_im.save("checkerboard.heic", transparency=0)
An image with a simple 2×2 checkerboard pattern, with transparent squares in the bottom left and top right.
The HEIC is rendered as a solid black image, losing the transparency from the PNG.
3.11.8 (v3.11.8:db85d51d3e, Feb 6 2024, 18:02:37) [Clang 13.0.0 (clang-1300.0.29.30)]
macOS-13.6.6-x86_64-i386-64bit
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder 3.8.1', 'encoders': {'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder 3.8.1', 'mask': 'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder 3.8.1'}}
Using Python 3.8, Mac OS 12.0.1, M1 Max
Following the instructions,
➜ appsnacks git:(main) ✗ brew install libffi libheif
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
atmos fisher luau rizin tfmigrate
btop git-branchless mt32emu rustfmt tfproviderlint
cava java-service-wrapper [email protected] smug urlwatch
cgif kubeval pip-tools swiftplantuml
fastfec libsoup@2 regula symengine
==> Updated Formulae
Updated 1026 formulae.
==> Renamed Formulae
rt-audio -> rtaudio
==> Deleted Formulae
amap soundpipe
Warning: libffi 3.4.2 is already installed and up-to-date.
To reinstall 3.4.2, run:
brew reinstall libffi
Warning: libheif 1.12.0_1 is already installed and up-to-date.
To reinstall 1.12.0_1, run:
brew reinstall libheif
➜ appsnacks git:(main) ✗ pip3 install --upgrade pillow_heif
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pillow_heif in /Users/bob/Library/Python/3.8/lib/python/site-packages (0.1.3)
Collecting pillow_heif
Using cached pillow_heif-0.1.4.tar.gz (19.5 MB)
WARNING: Value for prefixed-purelib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal/lib/python3.8/site-packages
sysconfig: /Library/Python/3.8/site-packages
WARNING: Value for prefixed-platlib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal/lib/python3.8/site-packages
sysconfig: /Library/Python/3.8/site-packages
WARNING: Additional context:
user = False
home = None
root = None
prefix = '/private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal'
WARNING: Value for prefixed-purelib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay/lib/python3.8/site-packages
sysconfig: /Library/Python/3.8/site-packages
WARNING: Value for prefixed-platlib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay/lib/python3.8/site-packages
sysconfig: /Library/Python/3.8/site-packages
WARNING: Additional context:
user = False
home = None
root = None
prefix = '/private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay'
Installing build dependencies ... done
Getting requirements to build wheel ... done
Installing backend dependencies ... done
Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: Pillow in /Users/bob/Library/Python/3.8/lib/python/site-packages (from pillow_heif) (8.4.0)
Requirement already satisfied: cffi>=1.0.0 in /Users/bob/Library/Python/3.8/lib/python/site-packages (from pillow_heif) (1.15.0)
Requirement already satisfied: pycparser in /Users/bob/Library/Python/3.8/lib/python/site-packages (from cffi>=1.0.0->pillow_heif) (2.20)
Building wheels for collected packages: pillow-heif
Building wheel for pillow-heif (pyproject.toml) ... error
ERROR: Command errored out with exit status 1:
command: /Applications/Xcode.app/Contents/Developer/usr/bin/python3 /Users/bob/Library/Python/3.8/lib/python/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/tmpojyt2acz
cwd: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-install-bbaa9mji/pillow-heif_3ee714bb207345d0b75a1aa30b9915f3
Complete output (24 lines):
running bdist_wheel
running build
running build_py
creating build
creating build/lib.macosx-10.14-arm64-3.8
creating build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/error.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/as_opener.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/constants.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/__init__.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/reader.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
copying pillow_heif/writer.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
running build_ext
generating cffi module 'build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c'
creating build/temp.macosx-10.14-arm64-3.8
building 'pillow_heif._libheif' extension
creating build/temp.macosx-10.14-arm64-3.8/build
creating build/temp.macosx-10.14-arm64-3.8/build/temp.macosx-10.14-arm64-3.8
clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -iwithsysroot/System/Library/Frameworks/System.framework/PrivateHeaders -iwithsysroot/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Headers -arch arm64 -arch x86_64 -Werror=implicit-function-declaration -I/usr/local/include -I/usr/include -I/opt/local/include -I/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/include/python3.8 -c build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c -o build/temp.macosx-10.14-arm64-3.8/build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.o
build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c:570:15: fatal error: 'libheif/heif.h' file not found
#include "libheif/heif.h"
^~~~~~~~~~~~~~~~
1 error generated.
error: command 'clang' failed with exit status 1
----------------------------------------
ERROR: Failed building wheel for pillow-heif
Failed to build pillow-heif
ERROR: Could not build wheels for pillow-heif, which is required to install pyproject.toml-based projects
In this commit I have added an example of such heic file taken on iPhone.
Here is the primary image:
Here is the depth image:
Here is an Aux image(urn/apple_photo/2020/aux/hdrgainmap):
Does anyone need the opportunity to read them?
After this issue #53 and as this project comes closer to final stage, wrote small tests, and will post them here for now.
Hardware: mac Mini M1 and Intel 10900k.
When benchmarking version 0.9.0
I set default number of decode threads to 8
(for clarity), other versions do not support this parameter, but libheif defaults it to 4
.
There was a bug in libheif, when it was compiled with Cmake it had turned off multithreading and was working in single threaded mode. That was fixed in new upcoming release and you can see it on graphs(0.5.1
for Linux has no this bug, 0.6.0
has).
Temporary code that was written today:
import sys
from subprocess import run
from time import perf_counter
def measure_decode(image, n_iterations):
cmd = f"{sys.executable} {__file__} {n_iterations} {image}".split()
start_time = perf_counter()
run(cmd, check=True)
total_time = perf_counter() - start_time
return total_time / n_iterations
if __name__ == "__main__":
from PIL import Image
from pillow_heif import register_heif_opener, __version__
_args = {}
if __version__ != "0.1.6":
_args["decode_threads"] = 8
register_heif_opener(**_args)
for i in range(int(sys.argv[1])):
im = Image.open(sys.argv[2])
im.load()
sys.exit(0)
Two test images was taken from that issue and from this repo i took cat.hif
(HDR image, with 2 thumbnails)
Originally posted by dust-to-dust March 21, 2022
I tried to convert the format, but find this only😂😂😂.
def write_heif():
raise NotImplementedError("not done yet")
```</div>
This program will crash on my iMac:
from PIL import Image
import cv2
from pillow_heif import register_heif_opener
register_heif_opener()
with Image.open("10003860486.jpg") as img:
img.load()
img.save("2.heic")
No crash
10739 segmentation fault
I am on Mac. Note that if I remove the line import cv2
, or if I move it after from pillow_heif import register_heif_opener
, then the program runs normally.
{'version': {'libheif': '1.14.2', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder 3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}
exif_data = b"This_is_not_valid_EXIF_data"
out_im = BytesIO()
im.save(out_im, format="HEIF", exif=exif_data)
im = Image.open(out_im)
Should work without problems(currently it does not)
Needed for install on Raspberry Pi OS 32bit (Debian 11)
Wheels for arm 32bit architecture.
No response
No response
Originally posted by Soooda March 17, 2023
Hello all,
I tried to convert some of my HIF images into JPGs and found some of the images were throwing the below error:
ValueError: corrupted image(dimensions in header: (7008, 4672), decoded dimensions: (4672, 7008)
The root cause was that I had applied rotation to my images and on the IOS system, the rotation was applied to the EXIF rather than the image data itself.
I made use of exif_transpose()
to compensate for that. But the error is still popping up. It looks like pillow_heif
does not support exif_transpose()
and I wonder if this is an intended behaviour?
from PIL import Image, ImageOps
from pillow_heif import register_heif_opener
register_heif_opener()
def save_jpg(path, quality=100, subsampling=0):
temp, _ = path.split(".")
temp += ".jpg"
im = Image.open(path)
im = ImageOps.exif_transpose(im)
print(f"Saving to {temp}")
im.save(temp, quality=quality, subsampling=subsampling)
# for filename in sys.argv[1:]:
# save_jpg(filename)
name = "DSC03260.HIF"
save_jpg(name)
My sv-dlp project started using pillow-heif (0.5.1) on its latest version (2022.07.30). Turns out compiling it with pillow-heif on a (GitHub Actions) Linux environment doubles the size from 26.6MB to 43.7MB.
I tried using UPX, installing the required system modules that (libaom, libde265, libx265), but it was still doubling the size for whatever reason.
Weird thing is, Windows (19.8MB -> 24.7MB) and MacOS (23.4MB -> 31.6MB) builds don't seem seriously affected by this, but still rises.
Below I'll leave a sample of my build script, requirements file, and the build results comparison using a WSL Arch environment
I honestly don't know what to put here so I'll just put my build.py script
import PyInstaller.__main__
import platform
SYS_OS = platform.system()
SYS_ARCH = platform.architecture()[0][:2]
suffix = f"{'_macos' if SYS_OS == 'Darwin' else ''}{'_x86' if SYS_ARCH == '32' else ''}{'.exe' if SYS_OS == 'Windows' else ''}"
def main():
opts = [
'sv-dlp/__main__.py',
'--onefile',
f'--name=sv-dlp{suffix}'
]
print(f"Building sv-dlp for platform {SYS_OS} with architecture {SYS_ARCH}")
PyInstaller.__main__.run(opts)
if __name__ == '__main__':
main()
altgraph==0.17.2
certifi==2022.6.15
charset-normalizer==2.1.0
colorama==0.4.5
future==0.18.2
idna==3.3
pefile==2021.9.3
Pillow==9.2.0
pillow-heif==0.5.1
pyinstaller==4.10
pyinstaller-hooks-contrib==2022.3
pylance==0.0.1
pyproj==3.3.1
pywin32-ctypes==0.2.0
requests==2.28.1
tqdm==4.64.0
urllib3==1.26.11
protobuf==4.21.4
pycryptodome==3.15.0
sudo apt-get install libaom0 libde265-0 libx265-179 # ubuntu
sudo pacman -S aom libde265 x265 # arch
Building sv-dlp for platform Linux with architecture 64
84 INFO: PyInstaller: 4.10
84 INFO: Python: 3.10.5
85 INFO: Platform: Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
87 INFO: wrote /mnt/f/code/sv-dlp/sv-dlp.spec
89 INFO: UPX is available.
96 INFO: Extending PYTHONPATH with paths
['/mnt/f/code/sv-dlp/sv-dlp']
270 INFO: checking Analysis
271 INFO: Building Analysis because Analysis-00.toc is non existent
271 INFO: Initializing module dependency graph...
275 INFO: Caching module graph hooks...
279 INFO: Analyzing base_library.zip ...
3053 INFO: Caching module dependency graph...
3189 INFO: running Analysis Analysis-00.toc
3204 INFO: Analyzing /mnt/f/code/sv-dlp/sv-dlp/__main__.py
3271 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_safe_import_module/hook-urllib3.packages.six.moves.py'.
5354 INFO: Processing pre-find module path hook distutils from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
5371 INFO: distutils: retargeting to non-venv dir '/usr/lib/python3.10'
5776 INFO: Processing pre-safe import module hook win32com from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/pre_safe_import_module/hook-win32com.py'.
6751 INFO: Processing pre-find module path hook site from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-site.py'.
6752 INFO: site: retargeting to fake-dir '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/fake-modules'
7233 INFO: Processing module hooks...
7233 INFO: Loading module hook 'hook-pyproj.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7239 INFO: Loading module hook 'hook-appdirs.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7240 INFO: Loading module hook 'hook-cryptography.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7398 INFO: Loading module hook 'hook-pycparser.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7398 INFO: Loading module hook 'hook-Crypto.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7401 INFO: Loading module hook 'hook-certifi.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7402 INFO: Loading module hook 'hook-jaraco.text.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7403 INFO: Loading module hook 'hook-heapq.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7404 INFO: Loading module hook 'hook-pickle.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7405 INFO: Loading module hook 'hook-distutils.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7406 INFO: Loading module hook 'hook-setuptools.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7424 INFO: Loading module hook 'hook-distutils.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7432 INFO: Loading module hook 'hook-multiprocessing.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7433 INFO: Loading module hook 'hook-lib2to3.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7444 INFO: Loading module hook 'hook-xml.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7476 INFO: Loading module hook 'hook-difflib.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7477 INFO: Loading module hook 'hook-packaging.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7477 INFO: Loading module hook 'hook-PIL.Image.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7743 INFO: Loading module hook 'hook-PIL.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7750 INFO: Loading module hook 'hook-encodings.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7803 INFO: Loading module hook 'hook-pkg_resources.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7851 WARNING: Hidden import "pkg_resources.py2_warn" not found!
7852 WARNING: Hidden import "pkg_resources.markers" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.functools" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.context" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.text" not found!
7853 INFO: Loading module hook 'hook-sysconfig.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7853 INFO: Loading module hook 'hook-PIL.ImageFilter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7854 INFO: Loading module hook 'hook-PIL.SpiderImagePlugin.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7856 INFO: Loading module hook 'hook-setuptools.msvc.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7856 INFO: Loading module hook 'hook-_tkinter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 37, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
7903 ERROR: Tcl/Tk improperly installed on this system.
7916 INFO: Looking for ctypes DLLs
7936 INFO: Analyzing run-time hooks ...
7940 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
7941 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
7943 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py'
7945 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
7945 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgres.py'
7948 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/rthooks/pyi_rth_pyproj.py'
7955 INFO: Looking for dynamic libraries
8238 WARNING: Cannot find libmpdec.so.3 (needed by /usr/lib/python3.10/lib-dynload/_decimal.cpython-310-x86_64-linux-gnu.so)
8477 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpdemux-df590b8f.so.2.0.9)
8481 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpmux-625e1d4a.so.3.0.8)
8494 WARNING: Cannot find libXau-154567c4.so.6.0.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libxcb-4971137c.so.1.1.0)
8512 WARNING: Cannot find liblzma-96284f0d.so.5.2.5 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8512 WARNING: Cannot find libjpeg-a4c3d5e9.so.62.3.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
ldd: warning: you do not have execution permission for `/usr/lib/libgcc_s.so.1'
8529 WARNING: Cannot find libsqlite3-e6e8c34c.so.0.8.6 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8529 WARNING: Cannot find libtiff-40073f1f.so.5.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8529 WARNING: Cannot find libcurl-c54b2682.so.4.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8538 WARNING: Cannot find libnghttp2-62f02794.so.14.20.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libcurl-c54b2682.so.4.7.0)
8542 INFO: Looking for eggs
8542 INFO: Using Python library /usr/lib/libpython3.10.so.1.0
8548 INFO: Warnings written to /mnt/f/code/sv-dlp/build/sv-dlp/warn-sv-dlp.txt
8608 INFO: Graph cross-reference written to /mnt/f/code/sv-dlp/build/sv-dlp/xref-sv-dlp.html
8634 INFO: checking PYZ
8635 INFO: Building PYZ because PYZ-00.toc is non existent
8635 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz
9235 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz completed successfully.
9247 INFO: checking PKG
9248 INFO: Building PKG because PKG-00.toc is non existent
9248 INFO: Building PKG (CArchive) sv-dlp.pkg
19969 INFO: Building PKG (CArchive) sv-dlp.pkg completed successfully.
19975 INFO: Bootloader /home/juan/.local/lib/python3.10/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
19975 INFO: checking EXE
19976 INFO: Building EXE because EXE-00.toc is non existent
19976 INFO: Building EXE from EXE-00.toc
19977 INFO: Copying bootloader EXE to /mnt/f/code/sv-dlp/dist/sv-dlp
19980 INFO: Appending PKG archive to custom ELF section in EXE
21227 INFO: Building EXE from EXE-00.toc completed successfully.
Building sv-dlp for platform Linux with architecture 64
84 INFO: PyInstaller: 4.10
84 INFO: Python: 3.10.5
84 INFO: Platform: Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
86 INFO: wrote /mnt/f/code/sv-dlp/sv-dlp.spec
88 INFO: UPX is available.
95 INFO: Extending PYTHONPATH with paths
['/mnt/f/code/sv-dlp/sv-dlp']
260 INFO: checking Analysis
261 INFO: Building Analysis because Analysis-00.toc is non existent
261 INFO: Initializing module dependency graph...
264 INFO: Caching module graph hooks...
269 INFO: Analyzing base_library.zip ...
2932 INFO: Caching module dependency graph...
3073 INFO: running Analysis Analysis-00.toc
3086 INFO: Analyzing /mnt/f/code/sv-dlp/sv-dlp/__main__.py
3154 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_safe_import_module/hook-urllib3.packages.six.moves.py'.
5214 INFO: Processing pre-find module path hook distutils from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
5231 INFO: distutils: retargeting to non-venv dir '/usr/lib/python3.10'
5628 INFO: Processing pre-safe import module hook win32com from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/pre_safe_import_module/hook-win32com.py'.
6645 INFO: Processing pre-find module path hook site from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-site.py'.
6645 INFO: site: retargeting to fake-dir '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/fake-modules'
7126 INFO: Processing module hooks...
7126 INFO: Loading module hook 'hook-pyproj.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7131 INFO: Loading module hook 'hook-appdirs.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7132 INFO: Loading module hook 'hook-cryptography.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7292 INFO: Loading module hook 'hook-pycparser.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7292 INFO: Loading module hook 'hook-Crypto.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7295 INFO: Loading module hook 'hook-certifi.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7296 INFO: Loading module hook 'hook-jaraco.text.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7297 INFO: Loading module hook 'hook-heapq.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7298 INFO: Loading module hook 'hook-pickle.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7299 INFO: Loading module hook 'hook-distutils.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7300 INFO: Loading module hook 'hook-setuptools.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7318 INFO: Loading module hook 'hook-distutils.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7326 INFO: Loading module hook 'hook-multiprocessing.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7327 INFO: Loading module hook 'hook-lib2to3.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7337 INFO: Loading module hook 'hook-xml.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7369 INFO: Loading module hook 'hook-difflib.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7371 INFO: Loading module hook 'hook-packaging.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7371 INFO: Loading module hook 'hook-PIL.Image.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7643 INFO: Loading module hook 'hook-PIL.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7650 INFO: Loading module hook 'hook-encodings.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7703 INFO: Loading module hook 'hook-pkg_resources.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7752 WARNING: Hidden import "pkg_resources.py2_warn" not found!
7752 WARNING: Hidden import "pkg_resources.markers" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.functools" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.context" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.text" not found!
7754 INFO: Loading module hook 'hook-sysconfig.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7754 INFO: Loading module hook 'hook-PIL.ImageFilter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7755 INFO: Loading module hook 'hook-PIL.SpiderImagePlugin.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7756 INFO: Loading module hook 'hook-setuptools.msvc.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7757 INFO: Loading module hook 'hook-_tkinter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.10/tkinter/__init__.py", line 37, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
7802 ERROR: Tcl/Tk improperly installed on this system.
7815 INFO: Looking for ctypes DLLs
7835 INFO: Analyzing run-time hooks ...
7838 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
7839 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
7842 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py'
7843 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
7844 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgres.py'
7846 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/rthooks/pyi_rth_pyproj.py'
7853 INFO: Looking for dynamic libraries
8096 WARNING: Cannot find libmpdec.so.3 (needed by /usr/lib/python3.10/lib-dynload/_decimal.cpython-310-x86_64-linux-gnu.so)
ldd: warning: you do not have execution permission for `/usr/lib/libgcc_s.so.1'
8345 WARNING: Cannot find libaom-0a65f09e.so.3.4.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8345 WARNING: Cannot find libde265-f493bf68.so.0.1.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8345 WARNING: Cannot find libx265-a25050ad.so.204 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8370 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpmux-625e1d4a.so.3.0.8)
8374 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpdemux-df590b8f.so.2.0.9)
8383 WARNING: Cannot find liblzma-96284f0d.so.5.2.5 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8383 WARNING: Cannot find libjpeg-a4c3d5e9.so.62.3.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8387 WARNING: Cannot find libXau-154567c4.so.6.0.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libxcb-4971137c.so.1.1.0)
8405 WARNING: Cannot find libsqlite3-e6e8c34c.so.0.8.6 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8405 WARNING: Cannot find libtiff-40073f1f.so.5.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8405 WARNING: Cannot find libcurl-c54b2682.so.4.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8410 WARNING: Cannot find libnghttp2-62f02794.so.14.20.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libcurl-c54b2682.so.4.7.0)
8422 INFO: Looking for eggs
8422 INFO: Using Python library /usr/lib/libpython3.10.so.1.0
8428 INFO: Warnings written to /mnt/f/code/sv-dlp/build/sv-dlp/warn-sv-dlp.txt
8486 INFO: Graph cross-reference written to /mnt/f/code/sv-dlp/build/sv-dlp/xref-sv-dlp.html
8517 INFO: checking PYZ
8517 INFO: Building PYZ because PYZ-00.toc is non existent
8517 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz
9134 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz completed successfully.
9148 INFO: checking PKG
9149 INFO: Building PKG because PKG-00.toc is non existent
9149 INFO: Building PKG (CArchive) sv-dlp.pkg
25747 INFO: Building PKG (CArchive) sv-dlp.pkg completed successfully.
25753 INFO: Bootloader /home/juan/.local/lib/python3.10/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
25753 INFO: checking EXE
25754 INFO: Building EXE because EXE-00.toc is non existent
25754 INFO: Building EXE from EXE-00.toc
25755 INFO: Copying bootloader EXE to /mnt/f/code/sv-dlp/dist/sv-dlp
25758 INFO: Appending PKG archive to custom ELF section in EXE
27499 INFO: Building EXE from EXE-00.toc completed successfully.
3.10.5 (main, Jun 6 2022, 18:49:26) [GCC 12.1.0]
Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
0.5.1
{'version': {'libheif': '1.12.0', 'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder v3.4.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}
Hi there!
Recently I started to use pyheif-pillow-opener for one project to add support for heif/avif files. It was great until I faced with some issue, that I want to share with you, because I can see you start developing your addon a month ago and you hopefully can fix it faster on your side
So, in as_opener.py you have check_heif_magic
method. It checks, if 5-8 bytes of signature is ftyp or 9-12 bytes of signature is one of the listed brands, but I think it should be logical and
instead of logical or
in return statement and that's why:
I can't find too much info about HEIF/AVIF file signature, so maybe I'm wrong, but from my experience and from discussions above I assume, that this could be a bug
Thank you for your attention, would be gladful if you fix this, or tell me that I've missed something!
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
This repository currently has no open or pending branches.
.github/workflows/analysis-coverage.yml
actions/checkout v3
actions/cache v3
actions/cache v3
actions/upload-artifact v3
codecov/codecov-action v3
.github/workflows/build-cache-deps.yml
actions/checkout v3
docker/setup-qemu-action v2
actions/cache v3
actions/cache v3
actions/upload-artifact v3
.github/workflows/close-stale.yml
actions/stale v5
.github/workflows/create-release-draft.yml
actions/checkout v3
actions/upload-artifact v3
actions/checkout v3
msys2/setup-msys2 v2
actions/upload-artifact v3
actions/checkout v3
actions/upload-artifact v3
actions/checkout v3
docker/setup-qemu-action v2
actions/cache v3
actions/cache v3
actions/upload-artifact v3
actions/checkout v3
docker/setup-qemu-action v2
actions/cache v3
actions/cache v3
actions/upload-artifact v3
actions/checkout v3
codecov/codecov-action v3
actions/upload-artifact v3
actions/checkout v3
actions/download-artifact v3
ncipollo/release-action v1.10.0
.github/workflows/publish-pypi.yml
actions/checkout v3
i3h/download-release-asset v1
.github/workflows/test-src-build.yml
actions/checkout v3
.github/workflows/test-wheels.yml
actions/checkout v3
docker/setup-qemu-action v2
actions/checkout v3
actions/setup-python v4
actions/checkout v3
actions/setup-python v4
actions/checkout v3
actions/setup-python v4
docs/rtd_docs_requirements.txt
sphinx ==5.1.0
sphinx-issues ==3.0.1
sphinx-rtd-theme ==1.0.0
pillow-heif ==0.5.0
setup.cfg
cffi >=1.14.6
pillow >=6.2.0
sphinx >=4.4
sphinx-issues >=3.0.1
sphinx-rtd-theme >=1.0
pytest no version found
piexif no version found
defusedxml no version found
packaging no version found
pytest no version found
piexif no version found
defusedxml no version found
packaging no version found
numpy no version found
pympler no version found
pytest no version found
piexif no version found
defusedxml no version found
packaging no version found
numpy no version found
pympler no version found
opencv-python no version found
pre-commit no version found
pylint no version found
coverage no version found
Currently images get converted from "L" to "RGB" mode and saved using HeifChroma.INTERLEAVED_RGB
and HeifColorspace.RGB
Disadvantages:
L_color_mode_image.png
)I am loading an .HEIC "spatial photo" file coming from the VisionOS and I cannot see the relevant metadata in the metadata
array or anywhere else.
Here is my code:
if pillow_heif.is_supported("IMG_0009.HEIC"):
heif_file = pillow_heif.open_heif("IMG_0009.HEIC")
Here is an example file:
IMG_0009.zip
There is metadata related to the camera extrinsics and intrinsics. They can be seen in the "info" box on the Mac, but they are nowhere to be seen from pillow-heif as far as I can tell. The Mac and AVP are using this to flag the files as "spatial photos" (stereoscopic image).
Expected: inspecting the file variable the metadata should be accessible somewhere.
Saving the file right after opening should produce a file with similar metadata as the original.
I can see info.exif
, info.xmp
but info.metadata
is an empty array. I believe the metadata should be there.
3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.8.2', 'encoders': {'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.8.2', 'mask':
'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder v3.8.2'}}
With version pillow_heif==0.10.1, the code snip attached below worked perfectly. The EXIF data was read from a HEIC photo and added to a JPG.
With version pillow_heif==0.11.0, the EXIF data is no longer transferred correctly.
Please also compare the two file attachments.
for files in os.listdir(path_source):
if files.endswith('.HEIC'):
filename = files.split('.')[0]
heif_file = pillow_heif.open_heif(path_source + files, convert_hdr_to_8bit=False, bgr_mode=True)
np_array = np.asarray(heif_file)
cv2.imwrite(os.path.join(path_output, filename + '.jpg'), np_array)
# Add exif to new image
exif = heif_file.info['exif']
image_new = Image.open(os.path.join(path_output, filename + '.jpg'))
image_new.save(path_output + filename + '.jpg', 'JPEG', exif=exif)
The expected result, reproduced with version 0.10.1:
3.11.1 (tags/v3.11.1:a7a450f, Dec 6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}
3.11.1 (tags/v3.11.1:a7a450f, Dec 6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.11.0
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}
im = Image.new("L", size=(1, 1))
exif = im.getexif()
exif[Base.ImageDescription.value] = "description"
buf = BytesIO()
im.save(buf, format="HEIF", exif=exif) # <-- here
print(Image.open(buf).getexif())
If passed object is Pillow's Exif
then pillow-heif itself should call tobytes
method.
No response
Pillow itself supports such thing...
When trying to apply the getexif() method to HEIF images made with my phone (stock Xiaomi), I get the error described below. As an example I've attached one of the problematic images: image.zip (sorry for using the zip format, uploading .heic files is not allowed).
from PIL.Image import Exif, open as image_open
from pillow_heif import register_heif_opener
register_heif_opener()
with image_open("image.heic") as image:
exif: Exif = image.getexif()
print("Exif presents: {}".format(exif is not None))
Exif presents: True | Exif presents: False
Test machine 1:
Traceback (most recent call last):
File "path-to-script.py", line 7, in <module>
exif: Exif = image.getexif()
^^^^^^^^^^^^^^^
File "path-to-site-packages\PIL\Image.py", line 1455, in getexif
self._exif.load(exif_info)
File "path-to-site-packages\PIL\Image.py", line 3719, in load
self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "path-to-site-packages\PIL\TiffImagePlugin.py", line 507, in __init__
raise SyntaxError(msg)
SyntaxError: not a TIFF file (header b'\xff\xe18&Exif' not valid)
Test machine 2:
Traceback (most recent call last):
File "path-to-script.py", line 7, in <module>
exif: Exif = image.getexif()
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1275, in getexif
self._exif.load(self.info.get("exif"))
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 3237, in load
self._info = TiffImagePlugin.ImageFileDirectory_v1(self.head)
File "/usr/lib/python3/dist-packages/PIL/TiffImagePlugin.py", line 900, in __init__
super().__init__(*args, **kwargs)
File "/usr/lib/python3/dist-packages/PIL/TiffImagePlugin.py", line 466, in __init__
raise SyntaxError("not a TIFF file (header %r not valid)" % ifh)
SyntaxError: not a TIFF file (header b'if\x00\x00II*\x00' not valid)
Test machine 1:
3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}
Test machine 1 additional information:
UTF-8 enabled for the whole system
Amernime Zone AMD 3rd party drivers
Pillow 9.5.0
Test machine 2:
3.8.10 (default, Mar 13 2023, 10:26:41)
[GCC 9.4.0]
Linux-5.15.0-71-generic-x86_64-with-glibc2.29
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'AVIF': 'AOMedia Project AV1 Encoder v3.5.0'}
Test machine 2 additional information:
VirtualBox VM Xubuntu 20.04 (clean install)
Pillow 7.0.0
As running the example, there is an error happened while importing ffi, lib form pillow_heif.libheif. Any suggestion, plz?
from pillow_heif.libheif import ffi, lib # pylint: disable=import-error, no-name-in-module.
ImportError: DLL load failed while importing libheif:
Here will be information about changes for 0.10
version.
Release date: NEXT WEEK (21.02-23.02)
Main features of 0.10.0 version:
C
module, most parts of project were reworked.LA
& LA;16
modes.1.12.0
pillow_heif.libheif_info() was simplified to such dictionary:
{
'libheif': '1.14.2',
'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)',
'AVIF': 'AOMedia Project AV1 Encoder 3.5.0'
}
Changes when using as a Pillow plugin:
info
dictionary metadata.content_type
is now str
instead of bytes
.Changes when using as a standalone:
convert_to
method removed, instead optional bgr_mode
parameter to open_heif
& read_heif
added.
open_heif/read_heif with convert_hdr_to_8bit=False
will open 10/12 bit images in 16 bit mode automatically(and it faster now and takes less RAM during decoding).
BGR modes(OpenCV) - old code:
heif_file = pillow_heif.open_heif("images/rgb12.heif", convert_hdr_to_8bit=False)
heif_file.convert_to("BGRA;16" if heif_file.has_alpha else "BGR;16")
np_array = np.asarray(heif_file)
cv2.imwrite("rgb16.png", np_array)
->
heif_file = pillow_heif.open_heif("images/rgb12.heif", convert_hdr_to_8bit=False, bgr_mode=True)
np_array = np.asarray(heif_file)
cv2.imwrite("rgb16.png", np_array)
original_bit_depth
in info dictionary was renamed to bit_depth
, standalone bit_depth
was removed.
heif_file = pillow_heif.open_heif("images/rgb12.heif")
print("image bit depth:" , heif_file.bit_depth)
->
heif_file = pillow_heif.open_heif("images/rgb12.heif")
print("image bit depth:" , heif_file.info["bit_depth"])
it is standardized now and shows the bit-depth of image in file(not the decoded one, so it may differs from bit depth of mode), for both Pillow plugin and stand-alone usage.
thumbnails
was simplified, temporary remove ability for getting their data and now it is just a list with thumbnails boxes.
For both the Pillow plugin and standalone use, this list will be in the info
dictionary. It simply allows you to delete thumbnails or add new ones without being able to retrieve their data. (I can’t make it universal for both modes, when there is an idea how to do it without loss of performance, I’ll do it)
encode
function added.
def encode(mode: str, size: tuple, data, fp, **kwargs) -> None:
"""Encodes data in a ``fp``.
:param mode: `BGR(A);16`, `RGB(A);16`, LA;16`, `L;16`, `I;16L`, `BGR(A)`, `RGB(A)`, `LA`, `L`
:param size: tuple with ``width`` and ``height`` of an image.
:param data: bytes object with raw image data.
:param fp: A filename (string), pathlib.Path object or an object with ``write`` method."""
Useful in situations where you want just save one image to a new file.
Old code that do the same(it still will be worked):
cv_img = cv2.imread("images/jpeg_gif_png/RGBA_16.png", cv2.IMREAD_UNCHANGED)
heif_file = pillow_heif.from_bytes(
mode="BGRA;16",
size=(cv_img.shape[1], cv_img.shape[0]),
data=bytes(cv_img)
)
heif_file.save("RGBA_10bit.heic", quality=-1)
New alternative:
cv_img = cv2.imread("images/jpeg_gif_png/RGBA_16.png", cv2.IMREAD_UNCHANGED)
pillow_heif.encode(
mode="BGRA;16",
size=(cv_img.shape[1], cv_img.shape[0]),
data=bytes(cv_img),
fp="RGBA_10bit.heic",
quality=-1)
Both methods are faster now, as data passes directly to LibHeif(encode
will be faster as it does not create HeifFile
class).
elif frame.mode == "LA": # libheif doesnt not support INTERLEAVED_MONOCHROME mode
frame = frame.convert(mode="RGBA")
This is wrong, libheif supports adding MONOCHROME
plane and Alpha
plane for this situation.
And the resulted encoded image will be a bit smaller that case
Do not understand all code in this project, but maybe needed make some changes to:
@property
def data(self):
Is this possible?
No response
Not a big deal, but would be nice to see such improvement.
I put in an heic that I know is not weird.
I run the example code below, and it saves a jpg that looks weird and skewed.
# main.py
if __name__ == '__main__':
path = "C:\\Users\\whatever\\myimg.heic"
heif_file = pillow_heif.open_heif(path)
image = Image.frombytes(heif_file.mode, heif_file.size, heif_file.data, "raw")
image.save("hi.jpg")
Windows 10
0.7.0
{'version': {'libheif': '1.13.0', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.4.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}
Hi,
Thanks for developing this extension to Pillow. I had a question regarding performance converting a .heic to a .jpg file. Running heif-convert
is about twice as fast as doing:
import pillow_heif.HeifImagePlugin
img = Image.open(path_heic)
img.save(path_jpg)
The command line I used was:
for file in *.heic; do heif-convert $file ${file/%.heic/.jpg}; done
Is this expected? For 100 images (of the smaller variety I attached), heif-convert took 42 seconds, pillow_heif took 75 seconds (threaded), and 208 seconds using one thread.
I've attached two files from two datasets I've observed this on.
Thanks,
import pillow_heif.HeifImagePlugin
img = Image.open(path_heic)
img.save(path_jpg)
Performance should mirror heif-converte
About two times slower.
0.8.0
{'version': {'libheif': '1.14.0', 'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder v3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}
Will try to add this as an option.NATIVE_MODE
which will be set by default to False
to not break any compatibility.
If image will be opened by read_heif
NATIVE_MODE will be set to True
for that image. (So behaviour of read_heif will be different)
For Pillow plugin and open_heif
it will be available to change option with register_*_opener or by setting
options.NATIVE_MODE = True
Also this will allow to get and set in info
dictionary original image subsampling
value(currently it has name chroma
in pillow_heif)
That will allow to read monochromic images in monochrome mode and not in RGB(A)/BGR(A)
Divided #83 topic into two separate.
Briefly: I can easy add AUX image support whenI will have any non iPhone image, with different auxiliary_type
(e.g. non hdrgainmap
)
Or when I get information from here: strukturag/libheif/issues/926
Currently we can not determine image mode, and I need to know, can all aux images be decoded as grayscales ones or not.
Cause if not, then algorithm will be a little bit weird, need first to try to decode as Greyscale and if decodes fails, then decode it as RGB/RGBA...
Hello, I'm trying to build this in a flatpak environment which has no network access, I added the necessary libraries listed in
pillow_heif/libheif/linux_build_libs.py
Lines 12 to 15 in 7319c50
But it still seems to try downloading them for some reason. Is a fully offline build not possible?
========================================================================
Building module python3-pillow-heif in /srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1
========================================================================
�]2;flatpak-builder: Building python3-pillow-heif��]2;flatpak-builder: Installing python3-pillow-heif�Running: pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif>=0.12.0" --no-build-isolation
FB: Running 'flatpak build --die-with-parent --env=FLATPAK_BUILDER_BUILDDIR=/run/build/python3-pillow-heif --nofilesystem=host:reset --filesystem=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1 --bind-mount=/run/build/python3-pillow-heif=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1 --build-dir=/run/build/python3-pillow-heif --bind-mount=/run/ccache=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/ccache --unshare=network --env=SOURCE_DATE_EPOCH=1691637318 '--env=CFLAGS=-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer ' '--env=CXXFLAGS=-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer ' '--env=LDFLAGS=-L/app/lib -Wl,-z,relro,-z,now -Wl,--as-needed ' --env=BASEAPP_REMOVE_WEBENGINE=1 --env=CCACHE_DIR=/run/ccache/disabled --env=PATH=/app/bin:/usr/bin --env=LD_LIBRARY_PATH=/app/lib --env=PKG_CONFIG_PATH=/app/lib/pkgconfig:/app/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig --env=FLATPAK_BUILDER_N_JOBS=64 /srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/rofiles/rofiles-wxYmbx /bin/sh -c 'pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif>=0.12.0" --no-build-isolation'' on host
Using pip 23.1.2 from /usr/lib/python3.10/site-packages/pip (python 3.10)
Looking in links: file:///run/build/python3-pillow-heif
Processing ./pillow_heif-0.13.0.tar.gz
Running command Preparing metadata (pyproject.toml)
running dist_info
creating /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info
writing /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/PKG-INFO
writing dependency_links to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/dependency_links.txt
writing requirements to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/requires.txt
writing top-level names to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/top_level.txt
writing manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
listing git files failed - pretending there aren't any
reading manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files found matching '*.yaml'
warning: no previously-included files found matching '*.yml'
warning: no previously-included files found matching '.cirrus.star'
no previously-included directories found matching 'ci'
no previously-included directories found matching 'docs'
no previously-included directories found matching 'docker'
no previously-included directories found matching 'benchmarks'
warning: no previously-included files matching '*' found under directory 'pi-heif'
adding license file 'LICENSE.txt'
adding license file 'LICENSES_bundled.txt'
writing manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
creating '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif-0.13.0.dist-info'
Preparing metadata (pyproject.toml) ... �[?25l�[?25hdone
Requirement already satisfied: pillow>=9.1.1 in /app/lib/python3.10/site-packages (from pillow-heif>=0.12.0) (10.0.0)
Building wheels for collected packages: pillow-heif
Running command Building wheel for pillow-heif (pyproject.toml)
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-cpython-310
creating build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/options.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/misc.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/heif.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/constants.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/as_plugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/_version.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/_lib_info.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/_deffered_error.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/__init__.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/HeifImagePlugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
copying pillow_heif/AvifImagePlugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
running build_ext
Tool cmake with version 3.26.4 satisfy requirements.
Tool nasm with version 2.16.01 satisfy requirements.
tar: /tmp/ph_build_stuff/x265/download.tar.gz: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
Traceback (most recent call last):
File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
return _build_backend().build_wheel(wheel_directory, config_settings,
File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 416, in build_wheel
return self._build_with_temp_dir(['bdist_wheel'], '.whl',
File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 401, in _build_with_temp_dir
self.run_setup()
File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 487, in run_setup
super(_BuildMetaLegacyBackend,
File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 338, in run_setup
exec(code, locals())
File "<string>", line 143, in <module>
File "/usr/lib/python3.10/site-packages/setuptools/__init__.py", line 107, in setup
return distutils.core.setup(**attrs)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 185, in setup
return run_commands(dist)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
dist.run_commands()
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
self.run_command(cmd)
File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
super().run_command(command)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/usr/lib/python3.10/site-packages/wheel/bdist_wheel.py", line 325, in run
self.run_command("build")
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
self.distribution.run_command(command)
File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
super().run_command(command)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/command/build.py", line 131, in run
self.run_command(cmd_name)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
self.distribution.run_command(command)
File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
super().run_command(command)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/usr/lib/python3.10/site-packages/setuptools/command/build_ext.py", line 84, in run
_build_ext.run(self)
File "/usr/lib/python3.10/site-packages/Cython/Distutils/old_build_ext.py", line 186, in run
_build_ext.build_ext.run(self)
File "/usr/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py", line 345, in run
self.build_extensions()
File "<string>", line 112, in build_extensions
File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 226, in build_libs
build_lib_linux(LIBX265_URL, "x265", _is_musllinux)
File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 136, in build_lib_linux
download_extract_to(url, _lib_path)
File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 56, in download_extract_to
run(_tar_cmd.split(), check=True)
File "/usr/lib/python3.10/subprocess.py", line 526, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['tar', '-xf', '/tmp/ph_build_stuff/x265/download.tar.gz', '-C', '/tmp/ph_build_stuff/x265', '--strip-components', '1']' returned non-zero exit status 2.
error: subprocess-exited-with-error
× Building wheel for pillow-heif (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: /usr/bin/python3 /usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py build_wheel /tmp/tmpm1kufndh
cwd: /tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6
Building wheel for pillow-heif (pyproject.toml) ... �[?25l�[?25herror
ERROR: Failed building wheel for pillow-heif
Dependencies I added:
See the minimal manifest below
flatpak install org.freedesktop.Platform//22.08
, flatpak install org.freedesktop.Sdk//22.08
app-id: com.example.test
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
modules:
- name: libaom
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DBUILD_SHARED_LIBS=1
- -DENABLE_EXAMPLES=OFF
- -DENABLE_TESTDATA=OFF
- -DENABLE_TESTS=OFF
- -DENABLE_TOOLS=OFF
sources:
- type: archive
url: https://storage.googleapis.com/aom-releases/libaom-3.6.1.tar.gz
sha256: 42b862f58b3d00bd3902d2dc469526574f5b012e5b178e6a9652845a113d6887
- name: libde265
buildsystem: cmake-ninja
sources:
- type: archive
url: https://github.com/strukturag/libde265/archive/v1.0.12/libde265-1.0.12.tar.gz
sha256: c7e5443c9387ef2ee7bd3a25b4cfeb1a66d038584cf0ab21a4a28db64f224584
cleanup:
- /bin
- name: x265
builddir: true
subdir: source
buildsystem: cmake-ninja
config-opts:
- -DBUILD_SHARED_LIBS=ON
sources:
- type: archive
url: https://bitbucket.org/multicoreware/x265_git/downloads/x265_3.5.tar.gz
sha256: e70a3335cacacbba0b3a20ec6fecd6783932288ebc8163ad74bcc9606477cae8
- name: libheif
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DAOM_ENCODER=ON
- -DWITH_EXAMPLES=OFF
sources:
- type: archive
url: https://github.com/strukturag/libheif/archive/v1.16.2/libheif-1.16.2.tar.gz
sha256: d207f2ff5c86e6af3621c237f186130b985b7a9ff657875944b58ac5d27ba71c
- name: python3-pillow-heif
buildsystem: simple
build-commands:
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif" --no-build-isolation
sources:
- type: file
url: https://files.pythonhosted.org/packages/0f/8b/2ebaf9adcf4260c00f842154865f8730cf745906aa5dd499141fb6063e26/Pillow-10.0.0.tar.gz
sha256: 9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396
- type: file
url: https://files.pythonhosted.org/packages/52/27/39f219e702744c6d7075626517de4ffe331550229e95897a26ba3e55b979/pillow_heif-0.13.0.tar.gz
sha256: be337495d0be5accf4d6ea6614f61293c40c86dc8d3e5e6eb63661f90f472362
flatpak-builder build --force-clean test.yaml
It should find that libaom, libde265, libheif and x265 are already installed
Tries to download them
0.13.0
Based on this thread:
Tested it, and indeed it crashes the whole process.
Will try fix it in 0.10.0
upcoming release, will add additional check for image size after decoding.
When running the test suite on aarch64-darwin in nixpkgs, we see test_heif_primary_image[AVIF]
cause a SIGILL and crash the whole python interpreter.
Run the test suite on MacOS.
> sw_vers ~
ProductName: macOS
ProductVersion: 14.4.1
BuildVersion: 23E224
The test suite should succeed or show errors, not crash the interpreter.
============================= test session starts ==============================
platform darwin -- Python 3.12.3, pytest-8.1.1, pluggy-1.4.0 -- /nix/store/2r8fbgpabanb42zbdm4lngayc35wby8i-python3-3.12.3/bin/python3.12
cachedir: .pytest_cache
rootdir: /private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source
configfile: pyproject.toml
testpaths: tests
collected 913 items / 2 deselected / 1 skipped / 911 selected
tests/basic_test.py::test_libheif_info PASSED [ 0%]
tests/basic_test.py::test_pillow_register_avif_plugin SKIPPED (Only when
AVIF support missing.) [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path0] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path1] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path2] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path3] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path4] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path5] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path6] PASSED [ 0%]
tests/basic_test.py::test_get_file_mimetype[img_path7] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path8] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path9] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path10] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path11] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path12] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path13] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path14] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path15] PASSED [ 1%]
tests/basic_test.py::test_get_file_mimetype[img_path16] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path17] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path18] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path19] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path20] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path21] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path22] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path23] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path24] PASSED [ 2%]
tests/basic_test.py::test_get_file_mimetype[img_path25] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path26] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path27] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path28] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path29] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path30] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path31] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path32] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path33] PASSED [ 3%]
tests/basic_test.py::test_get_file_mimetype[img_path34] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path35] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path36] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path37] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path38] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path39] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path40] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path41] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path42] PASSED [ 4%]
tests/basic_test.py::test_get_file_mimetype[img_path43] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path44] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path45] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path46] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path47] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path48] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path49] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path50] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path51] PASSED [ 5%]
tests/basic_test.py::test_get_file_mimetype[img_path52] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path53] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path54] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path55] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path56] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path57] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path58] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path59] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path60] PASSED [ 6%]
tests/basic_test.py::test_get_file_mimetype[img_path61] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path62] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path63] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path64] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path65] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path66] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype[img_path67] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype_not_supported PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype_invalid[] PASSED [ 7%]
tests/basic_test.py::test_get_file_mimetype_invalid[\x00\x00\x00$ftyp] PASSED [ 8%]
tests/basic_test.py::test_get_file_mimetype_invalid[\x00\x00\x00$ftypheiZ] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path0] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path1] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path2] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path3] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path4] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path5] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path6] PASSED [ 8%]
tests/basic_test.py::test_is_supported[img_path7] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path8] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path9] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path10] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path11] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path12] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path13] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path14] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path15] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path16] PASSED [ 9%]
tests/basic_test.py::test_is_supported[img_path17] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path18] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path19] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path20] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path21] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path22] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path23] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path24] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path25] PASSED [ 10%]
tests/basic_test.py::test_is_supported[img_path26] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path27] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path28] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path29] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path30] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path31] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path32] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path33] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path34] PASSED [ 11%]
tests/basic_test.py::test_is_supported[img_path35] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path36] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path37] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path38] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path39] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path40] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path41] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path42] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path43] PASSED [ 12%]
tests/basic_test.py::test_is_supported[img_path44] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path45] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path46] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path47] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path48] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path49] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path50] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path51] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path52] PASSED [ 13%]
tests/basic_test.py::test_is_supported[img_path53] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path54] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path55] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path56] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path57] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path58] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path59] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path60] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path61] PASSED [ 14%]
tests/basic_test.py::test_is_supported[img_path62] PASSED [ 15%]
tests/basic_test.py::test_is_supported[img_path63] PASSED [ 15%]
tests/basic_test.py::test_is_supported[img_path64] PASSED [ 15%]
tests/basic_test.py::test_is_supported[img_path65] PASSED [ 15%]
tests/basic_test.py::test_is_supported[img_path66] PASSED [ 15%]
tests/basic_test.py::test_is_supported[img_path67] PASSED [ 15%]
tests/basic_test.py::test_is_supported_fails[] PASSED [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$] PASSED [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$ftyp] PASSED [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$ftypheiZ] PASSED [ 16%]
tests/basic_test.py::test_is_supported_fails[img4] PASSED [ 16%]
tests/basic_test.py::test_heif_str PASSED [ 16%]
tests/basic_test.py::test_full_build SKIPPED (Only when building full
release) [ 16%]
tests/basic_test.py::test_light_build SKIPPED (Only when building light
release) [ 16%]
tests/basic_test.py::test_load_plugin SKIPPED (Only when plugins
present) [ 16%]
tests/leaks_test.py::test_open_save_objects_leaks[image0] PASSED [ 16%]
tests/leaks_test.py::test_open_save_objects_leaks[image1] PASSED [ 16%]
tests/leaks_test.py::test_open_to_numpy_mem_leaks SKIPPED (run only on
x86_64) [ 16%]
tests/leaks_test.py::test_color_profile_leaks[images/heif_other/cat.hif-NCLX] SKIPPED [ 17%]
tests/leaks_test.py::test_color_profile_leaks[images/heif_other/arrow.heic-ICC] SKIPPED [ 17%]
tests/leaks_test.py::test_metadata_leaks SKIPPED (run only on x86_64) [ 17%]
tests/leaks_test.py::test_pillow_plugin_leaks SKIPPED (run only on
x86_64) [ 17%]
tests/metadata_etc_test.py::test_heif_primary_image[HEIF] PASSED [ 17%]
tests/metadata_etc_test.py::test_heif_primary_image[AVIF] Fatal Python error: Illegal instruction
Current thread 0x00000001f3a73ac0 (most recent call first):
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/misc.py", line 405 in _finish_add_image
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/misc.py", line 379 in add_image
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/heif.py", line 574 in _encode_images
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/heif.py", line 362 in save
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/tests/helpers.py", line 142 in create_heif
File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/tests/metadata_etc_test.py", line 17 in test_heif_primary_image
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/python.py", line 195 in pytest_pyfunc_call
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/python.py", line 1772 in runtest
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 172 in pytest_runtest_call
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 240 in <lambda>
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 340 in from_call
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 239 in call_and_report
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 134 in runtestprotocol
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 364 in pytest_runtestloop
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 339 in _main
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 285 in wrap_session
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 332 in pytest_cmdline_main
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/config/__init__.py", line 174 in main
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/config/__init__.py", line 197 in console_main
File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/pytest/__main__.py", line 7 in <module>
File "<frozen runpy>", line 88 in _run_code
File "<frozen runpy>", line 198 in _run_module_as_main
Extension modules: PIL._imaging, PIL._imagingmath, _pillow_heif, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, PIL._webp, cv2, PIL._imagingcms, _testcapi (total: 20)
/nix/store/cgbhb3fyw74b3y1i5lm22ypz5hl9qmf0-pytest-check-hook/nix-support/setup-hook: line 53: 55863 Illegal instruction: 4 /nix/store/2r8fbgpabanb42zbdm4lngayc35wby8i-python3-3.12.3/bin/python3.12 -m pytest -k "not test_decode_threads and not test_opencv_crash" -vvv
3.11.9 (main, Apr 2 2024, 08:25:04) [Clang 16.0.6 ]
macOS-14.4.1-arm64-arm-64bit
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'AVIF': 'AOMedia Project AV1 Encoder 3.9.0', 'encoders': {'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder 3.9.0', 'mask': 'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder 3.9.0'}}
As we come closer to 1.0.0
version we need more consistent API for setting options.
Was looking how it is done in Pillow
and liked it.
Current code:
pillow_heif.options().thumbnails = False
in new version will be changed to:
pillow_heif.options.THUMBNAILS= False
Usage when it is used a plugin will not be changed, old code will work the same way:
from pillow_heif import register_heif_opener
register_heif_opener(thumbnails=False)
It will require less code from me to support, will not break API for plugin use, and such code will be a bit faster.
Changes for code when use it not as a plugin:
pillow_heif.options().thumbnails=False
-> pillow_heif.options.THUMBNAILS=False
pillow_heif.options().quality=100
-> pillow_heif.options.QUALITY=100
pillow_heif.options().save_to_12bit=True
-> pillow_heif.options.SAVE_HDR_TO_12BIT=True
New IMPORTANT options (list will be updated as I currently working on this):
DECODE_THREADS=4
Option to set number of decode threads(when it is possible). Benchmarks will be posted after update released.
Usage of option for register_heif_opener
:
register_heif_opener(decode_threads=10)
or
pillow_heif.options.DECODE_THREADS= 10
libheif has released a new version that has a number of new codec plugins, notably ffmpeg which would allow hardware accelerated encoding.
Using the dynamically compiled option for the plugins and having an option in the python library to specify the codec plugin to use.
No response
No response
Did not find the function call heif_nclx_color_profile_free
in the sources, look like i missed it. :(
im_heif = pillow_heif.open_heif("../tests/images/heif_other/cat.hif") # from this repo
for i in range(10000000):
nclx = pillow_heif.private.read_color_profile(im_heif[0]._handle)
Eats 500mb of RAM at the end... ~60 bytes for each opening of image with nclx
profile.
Affected Versions: This leak is present in all versions. Will add test for this...
When trying to install using PIP I get a very long error
Try to install on raspberry pi using:
python3 -m pip install pi-heif
succesfull install
pi@frame:~ $ python3 -m pip install pi-heif
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pi-heif
Using cached pi_heif-0.12.0.tar.gz (14.8 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting pillow>=8.4.0 (from pi-heif)
Using cached https://www.piwheels.org/simple/pillow/Pillow-9.5.0-cp37-cp37m-linux_armv6l.whl (820 kB)
Building wheels for collected packages: pi-heif
Building wheel for pi-heif (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for pi-heif (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [162 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-armv6l-cpython-37
creating build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/constants.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_deffered_error.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_version.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/HeifImagePlugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_lib_info.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/init.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/as_plugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/AvifImagePlugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/options.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/misc.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/heif.py -> build/lib.linux-armv6l-cpython-37/pi_heif
running build_ext
libheif is already present.
building '_pi_heif' extension
creating build/temp.linux-armv6l-cpython-37
creating build/temp.linux-armv6l-cpython-37/pi_heif
arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -flto -fuse-linker-plugin -ffat-lto-
objects -fPIC -I/usr/include -I/usr/local/include -I/usr/include/python3.7m -c pi_heif/_pi_heif.c -o build/temp.linux-armv6l-cpython-37/pi_heif/_pi_heif.o -Ofast -Werror
pi_heif/_pi_heif.c: In function ‘check_error’:
pi_heif/_pi_heif.c:31:14: error: ‘heif_error_Color_profile_does_not_exist’ undeclared (first use in this function); did you mean ‘heif_error_Input_does_not_exist’?
case heif_error_Color_profile_does_not_exist:
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_error_Input_does_not_exist
pi_heif/_pi_heif.c:31:14: note: each undeclared identifier is reported only once for each function it appears in
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_add_plane’:
pi_heif/_pi_heif.c:110:76: error: ‘heif_chroma_interleaved_RRGGBBAA_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
if ((self->chroma == heif_chroma_interleaved_RGBA) || (self->chroma == heif_chroma_interleaved_RRGGBBAA_LE)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_icc_profile’:
pi_heif/_pi_heif.c:474:13: error: implicit declaration of function ‘heif_image_set_raw_color_profile’; did you mean ‘heif_image_get_colorspace’? [-Werror=implicit-function-declaration]
error = heif_image_set_raw_color_profile(self->image, type, buffer.buf, (int)buffer.len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_colorspace
pi_heif/_pi_heif.c:474:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_image_set_raw_color_profile(self->image, type, buffer.buf, (int)buffer.len);
^
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_nclx_profile’:
pi_heif/_pi_heif.c:490:58: error: implicit declaration of function ‘heif_nclx_color_profile_alloc’ [-Werror=implicit-function-declaration]
struct heif_color_profile_nclx* nclx_color_profile = heif_nclx_color_profile_alloc();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:490:58: error: initialization of ‘struct heif_color_profile_nclx *’ from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
pi_heif/_pi_heif.c:491:23: error: dereferencing pointer to incomplete type ‘struct heif_color_profile_nclx’
nclx_color_profile->color_primaries = color_primaries;
^~
pi_heif/_pi_heif.c:495:13: error: implicit declaration of function ‘heif_image_set_nclx_color_profile’; did you mean ‘heif_image_get_colorspace’? [-Werror=implicit-function-declaration]
error = heif_image_set_nclx_color_profile(self->image, nclx_color_profile);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_colorspace
pi_heif/_pi_heif.c:495:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_image_set_nclx_color_profile(self->image, nclx_color_profile);
^
pi_heif/_pi_heif.c:496:5: error: implicit declaration of function ‘heif_nclx_color_profile_free’ [-Werror=implicit-function-declaration]
heif_nclx_color_profile_free(nclx_color_profile);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_metadata’:
pi_heif/_pi_heif.c:567:13: error: implicit declaration of function ‘heif_context_add_generic_metadata’; did you mean ‘heif_context_add_exif_metadata’? [-Werror=implicit-function-declaration]
error = heif_context_add_generic_metadata(ctx_write->ctx, self->handle, buffer.buf, (int)buffer.len, type, content_type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_context_add_exif_metadata
pi_heif/_pi_heif.c:567:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_context_add_generic_metadata(ctx_write->ctx, self->handle, buffer.buf, (int)buffer.len, type, content_type);
^
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_create’:
pi_heif/_pi_heif.c:654:9: error: implicit declaration of function ‘heif_image_set_premultiplied_alpha’; did you mean ‘heif_image_get_plane_readonly’? [-Werror=implicit-function-declaration]
heif_image_set_premultiplied_alpha(image, 1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_plane_readonly
pi_heif/_pi_heif.c: In function ‘_CtxImage’:
pi_heif/_pi_heif.c:719:33: error: implicit declaration of function ‘heif_image_handle_is_premultiplied_alpha’; did you mean ‘heif_image_handle_is_primary_image’? [-Werror=implicit-function-declarat
ion]
strcat(ctx_image->mode, heif_image_handle_is_premultiplied_alpha(handle) ? "a" : "A");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_is_primary_image
pi_heif/_pi_heif.c:720:23: error: implicit declaration of function ‘heif_image_handle_get_luma_bits_per_pixel’; did you mean ‘heif_image_get_bits_per_pixel’? [-Werror=implicit-function-declaration]
ctx_image->bits = heif_image_handle_get_luma_bits_per_pixel(handle);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_bits_per_pixel
pi_heif/_pi_heif.c: In function ‘_CtxImage_color_profile’:
pi_heif/_pi_heif.c:760:10: error: variable ‘profile_type’ has initializer but incomplete type
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:760:49: error: implicit declaration of function ‘heif_image_handle_get_color_profile_type’; did you mean ‘heif_image_handle_get_metadata_type’? [-Werror=implicit-function-declara
tion]
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_type
pi_heif/_pi_heif.c:760:34: error: storage size of ‘profile_type’ isn’t known
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~
pi_heif/_pi_heif.c:761:25: error: ‘heif_color_profile_type_not_present’ undeclared (first use in this function); did you mean ‘heif_color_profile_type’?
if (profile_type == heif_color_profile_type_not_present)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_size 13:15:12 [10/255]
pi_heif/_pi_heif.c:803:30: error: implicit declaration of function ‘heif_image_handle_get_raw_color_profile’; did you mean ‘heif_image_handle_get_metadata_size’? [-Werror=implicit-function-declarat
ion]
if (!check_error(heif_image_handle_get_raw_color_profile(self->handle, data)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_size
pi_heif/_pi_heif.c:803:30: error: incompatible type for argument 1 of ‘check_error’
if (!check_error(heif_image_handle_get_raw_color_profile(self->handle, data)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:13:35: note: expected ‘struct heif_error’ but argument is of type ‘int’
int check_error(struct heif_error error) {
~~~~~~~~~~~~~~~~~~^~~~~
pi_heif/_pi_heif.c:760:34: error: unused variable ‘profile_type’ [-Werror=unused-variable]
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~
pi_heif/_pi_heif.c: In function ‘decode_image’:
pi_heif/_pi_heif.c:903:19: error: ‘struct heif_decoding_options’ has no member named ‘convert_hdr_to_8bit’
decode_options->convert_hdr_to_8bit = self->hdr_to_8bit;
^~
pi_heif/_pi_heif.c:918:22: error: ‘heif_chroma_interleaved_RRGGBBAA_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
chroma = heif_chroma_interleaved_RRGGBBAA_LE;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c:922:22: error: ‘heif_chroma_interleaved_RRGGBB_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
chroma = heif_chroma_interleaved_RRGGBB_LE;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c:941:25: error: implicit declaration of function ‘heif_image_get_primary_width’; did you mean ‘heif_image_get_width’? [-Werror=implicit-function-declaration]
int decoded_width = heif_image_get_primary_width(self->heif_image);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_width
pi_heif/_pi_heif.c:942:26: error: implicit declaration of function ‘heif_image_get_primary_height’; did you mean ‘heif_image_get_height’? [-Werror=implicit-function-declaration]
int decoded_height = heif_image_get_primary_height(self->heif_image);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_height
pi_heif/_pi_heif.c: In function ‘setup_module’:
pi_heif/_pi_heif.c:1181:52: error: ‘heif_compression_AV1’ undeclared (first use in this function); did you mean ‘heif_compression_AVC’?
if (heif_context_get_encoder_descriptors(NULL, heif_compression_AV1, NULL, &encoder_descriptor, 1))
^~~~~~~~~~~~~~~~~~~~
heif_compression_AVC
cc1: all warnings being treated as errors
error: command '/usr/bin/arm-linux-gnueabihf-gcc' failed with exit code 1
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for pi-heif
Failed to build pi-heif
ERROR: Could not build wheels for pi-heif, which is required to install pyproject.toml-based projects
> import platform, sys, pillow_heif
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pillow_heif'
The script below works with pillow-10.1.0 but throws an error with Pillow-SIMD-9.0.0.post1
from PIL import Image
from pillow_heif import register_heif_opener
register_heif_opener()
im = Image.open('testimage.heic')
im.thumbnail((200, 200))
im.save('test.jpg', 'jpeg')
No error is thrown using Pillow-SIMD
PIL.UnidentifiedImageError: cannot identify image file "/Users/testuser/testimage.heic"
3.11.5 (main, Sep 1 2023, 11:37:07) [Clang 14.0.3 (clang-1403.0.22.14.1)]
macOS-13.6.1-x86_64-i386-64bit
0.13.1
{'libheif': '1.16.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder 3.7.0'}
Most changes are already present in last pillow-heif release, but anyway...
Approximately one to three weeks until the new release
The LICENSE says Apache2, the setup.cfg says GPL2. The underlying libheif
is LGPL3. Found this by digging into the list of projects from this comment on numpy/numpy#24138. Did I read things right here?
In version 9.3.0 Pillow allows to save EXIF for WEBP format without firsts 6 bytes b'Exif\x00\x00'
python-pillow/Pillow#6582
This code
pillow_heif/pillow_heif/private.py
Line 162 in 0430fcb
pillow_heif/pillow_heif/misc.py
Line 37 in 0430fcb
New LibHeif release
Brew PR
MSYS2 PR
LibHeif 1.14.0 will be included in 0.8.0
version.
Estimated time for release approximately 3-5 days.
Notes:
SVT
binaries will not be included, for now.add XMP header compression (using zlib)
- will still be missed, do not want to remove ability to build this project with 1.12.0
versionorigin:as_opener.py line58
extensions = [".heic", ".hif"]
I think it may be follow:
extensions = [".heic", ".heif"]
none
none
none
none
I'm trying to add the "nclx_profile" metadata to a new HEIC file.
I'm setting this key as a dict in pil_image.info
, but when I save and load the photo the data isn't there.
Full example code to reproduce:
import numpy as np
import pillow_heif
from PIL import Image
from io import BytesIO
from pillow_heif import register_heif_opener
register_heif_opener()
nclx_profile = {
'color_primaries': 1,
'transfer_characteristics': 2,
'matrix_coefficients': 1,
'full_range_flag': 1,
'color_primary_red_x': 0.0,
'color_primary_red_y': 0.0,
'color_primary_green_x': 0.0,
'color_primary_green_y': 0.0,
'color_primary_blue_x': 0.0,
'color_primary_blue_y': 0.0,
'color_primary_white_x': 0.0,
'color_primary_white_y': 0.0
}
# create a new, blank image
pil_image = Image.fromarray(np.ones((16, 16, 3)).astype(np.uint8))
# sset nclx_profile
pil_image.info['nclx_profile'] = nclx_profile
# save to an in-memory file (works if we save to disk too)
tmp = BytesIO()
pil_image.save(tmp, format="heif")
# re-open the image and see if nclx_profile is there
Image.open(tmp).info['nclx_profile'] # KeyError!
def register_heif_opener():
...
Image.register_mime(HeifImageFile.format, "image/heic")
Image.register_mime(HeifImageFile.format, "image/heic-sequence")
Image.register_mime(HeifImageFile.format, "image/heif")
Image.register_mime(HeifImageFile.format, "image/heif-sequence")
...
In the end format HEIF
has registered mimetype
to image/heif-sequence
The main question, what mimetype
choose for HEIF
format: image/heic
or image/heif
?
We can choose only one...
Hi,
I was trying to build a wheel for armhf on ubuntu focal and it never completes successfully. Then I tried to build it for amd64 to rule out 32bit related issues and that also fails (with the option --no-binary pillow_heif
).
The official wheels seem to work, but since there are no wheels for armhf, I have to compile.
I do have the listed build deps libffi
, libheif-dev
and libde265-dev
installed (along with a whole lot of other build deps for other wheels). For reference, I'm using this dockerfile: https://github.com/linuxserver/wheelie/blob/main/Dockerfile
Here's the output of pip wheel --wheel-dir=/build --no-cache-dir -v --no-binary pillow_heif pillow_heif
on ubuntu focal amd64:
https://pastebin.com/vngx8kqx
Am I missing another build dep? Any ideas?
Thanks
Impossible to build x265 dependency on freebsd 13.2.
Missing the <sys/stat.h> header in ringmem.cpp
Fix it in tmp directory is useless because the build script at each call replace in tmp dir with the buggy x265.
Clone this repo on freebsd with python 3.9 and clang 15.0.7 x265 will fail.
X265 be build.
[ 98%] Building CXX object common/CMakeFiles/common.dir/ringmem.cpp.o 1 warning generated. /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:27: error: use of undeclared identifier 'S_IRUSR' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:37: error: use of undeclared identifier 'S_IWUSR' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:47: error: use of undeclared identifier 'S_IRGRP' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:57: error: use of undeclared identifier 'S_IWGRP' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:67: error: use of undeclared identifier 'S_IROTH' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:77: error: use of undeclared identifier 'S_IWOTH' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^
Imposible to install pillow_heif.
Fail to decode image just because of some invalid bytes in XMP.
from PIL import Image
from pillow_heif import register_heif_opener
register_heif_opener()
im = Image.open("images/input.heic") # do whatever need with a Pillow image
input.heic: https://easyupload.io/2p5p0d
No error is thrown or warning prompt.
3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]
Windows-10-10.0.19041-SP0
0.9.2
{'version': {'libheif': '1.14.2', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}
background
Initially, pillow_heif contained such a feature, in versions 0.9.x
it was, by default all 10/12 bit files were opened in 10/12 bit mode, and after that you could optionally convert the image to 16 bit with the call to convert_to
As I did not see any code that uses this, and OpenCV
uses 16 bit for HDR by default, I made an assumption that make a default 16 bit mode is fine and removed that possibility to open images in 10/12 bit mode( RGB;10
, BGR;10
, etc if someone remeber).
As in that time there was a request to make version without cffi
with native C
module, I moved all that conversions to C
module and it even did not get slower(with additional shifting of 10/12 bit images to 16 bit, I mean)
currently
I was very impressed to see this message: strukturag/libheif#562 (comment)
There is shifting before saving and after opening.
What made me think, is it possible to return the native modes of 10/12 bits from versions 0.9.x?
In the way that there would be no loss of compatibility with what is already here, because idea to open images in 16 bit mode by default.
And I can reply to myself after small investigation, that yes, it is possible and will be useful in future.
Changes:
Currently there is a hidden parameter postprocess
to open_heif
/read_heif
.
It will be removed (it was not documented)
Two new parameters that will instead appears:
remove_stride - default True
(this will be still undocumented, cause I do not know cases when someone will wanted this behaviour off)
hdr_to_16bit - default True
(this will be documented)
This change is fully compatible with 0.10-0.11
versions, no need to change anything.
This allows rewrite code from post without shifting, just do:
im = pillow_heif.open_heif("image.heic", convert_hdr_to_8bit =False, hdr_to_16bit=False)
If image was HDR, then it will be opened in 10 or 12 bit mode(in that bitness in which it is).
Also restore ability to accept RGB,BGR,10,12
bit and so on. See commit: 129d9f8
I wanted to make this usable on a system where I can't run pip
to install this. I did the usual python3 setup.py bdist_egg
and got an .egg file.
But upon trying to import something, I get:
File "/etc/hooks/myScript.py", line 13, in <module>
from pillow_heif import register_heif_opener
File "/etc/hooks/./pillow_heif.egg/pillow_heif/__init__.py", line 7, in <module>
File "/etc/hooks/./pillow_heif.egg/pillow_heif/_lib_info.py", line 5, in <module>
ModuleNotFoundError: No module named '_pillow_heif_cffi'
Same result with building a .whl with python3 -m build
Package as .egg and try to import it a pillow_heif module.
I can use pillow_heif.
I can't use pillow_heif.
Python 3.10, Linux 64-bit, latest pillow_heif release
When calling Image.verify()
on a .heic
image, the program raise an AttributeError
exception with the following message:
AttributeError: 'NoneType' object has no attribute 'close'
You can reproduce the error with the following code.
from PIL import Image
from pillow_heif import register_heif_opener
register_heif_opener()
image = Image.open("filename.heic")
image.verify()
Currently investigating if it is needed...
Adding file to pass to register as a plugin with Sigal
Registration of plugins-modules in Sigal
for plugin in settings['plugins']:
try:
if isinstance(plugin, str):
mod = importlib.import_module(plugin)
mod.register(settings)
else:
plugin.register(settings)
logger.debug('Registered plugin %s', plugin)
Will be good if someone who uses Sigal, says how to use it in proper way. And when to register module
and when a plugin
.
Like @Simon566 for example.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.