-
-
Notifications
You must be signed in to change notification settings - Fork 389
heif‐enc Command Line Tool
The heif-enc command line tool is an example application for converting images to HEIF files.
It can read JPEG, PNG, TIFF, and Y4M images and it writes all variants of HEIF like HEIC, AVIF, or JPEG-2000 and ISO23001-17 uncompressed content.
The basic syntax is:
heif-enc input.jpg -o output.heicTo switch between different encoding formats use the following command line switches:
| switch | compression format | suffix |
|---|---|---|
| --hevc (default) | H.265 (HEVC) | .heic |
| -A / --avif | AV1 | .avif |
| --avc | H.264 (AVC) | |
| --vvc | H.266 (VVC) | .vvic |
| --jpeg | JPEG | |
| --jpeg2000 | JPEG-2000 | .hej2 |
| --htj2k | HT-JPEG-2000 | |
| -U / --uncompressed | ISO 23001-17 |
Alternatively, heif-enc also sets the compression format when it recognizes the suffix of your output filename.
Despite its name, the 'uncompressed' codec can use lossless compression. You can specify the compression algorithm with --unci-compression METHOD, where METHOD is either deflate, zlib, or brotli (support for these formats may vary depending on how the libheif build was configured).
If you want to encode a high-resolution tiled image, heif-enc expects each tile image in a separate input image with filenames that contain two numbers to denote the tile row and column position.
For example: tile-2-3.jpg or image-002-003.jpg.
To switch heif-enc into tile input mode, use the option -T / --tiled-input and specify one tile image as input.
heif-enc will scan the directory to search for images with the same name pattern.
It will detect the number range for the row and column position. This means that the position numbers may start from 0 or 1 (or any other number).
It will also detect whether to use leading zeros for the numbers.
Usually, heif-enc expects that the first number is the vertical position and the second number the horizontal position. If you want to swap these, use --tiled-input-x-y.
The generated tiled image will have a size which is the sum of all the tile widths and heights. However, the input image might have some padding add the right and bottom border. In that case, you can overwrite the total image size with --tiled-image-width # and --tiled-image-height #.
Alternatively to providing the tile images as input, you can also just provide the whole input image in one piece and use the option --cut-tiles # to automatically cut it into tiles of the given size.
You can choose between three different tiling modes:
-
grid: this is the default method with the best decoder compatibility. However, it has the largest overhead and the maximum size is limited to 65535 tiles. -
tili: this is a more efficient tiling format with only little overhead and allowing practically unlimited number of tiles. Note: it is currently only supported by libheif. -
unci: this uses the internal tiling support of the ISO 23001-17 (uncompressed) image codec. It can only be used in connection of that codec. Liketili, it has little overhead and supports larger image sizes.
heif-enc can also encode a multi-resolution pyramid stack of images.
In this case, you just have to specify the input images for each resolution layer on the command line and provide the option --add-pyramid-group.
This also works with tiled images in each pyramid layer. An example command line would be:
heif-enc --tiled-input layer1-001-001.jpg layer2-01-01.jpg layer3-01-01.jpg -o output.heic --add-pyramid-groupThe input layer images can be specified in any order, heif-enc will take care to sort them by size and add them in the correct order to the pyramid group.
You can switch heif-enc to encoding image-sequences with the command line option -S/--sequence.
The input images can either be enumerated on the command line, or (if the filename contains a frame-number), heif-enc will automatically pull in all images with this numbering scheme. That means, if your directory contains the files ("img-01.png", "img-02.png", "img-03.png", ...), just specifying heif-enc -S img-01.png -o output.heics will encode all images into the sequence.
If you want to limit the number of frames to be encoded (e.g. for testing), you can use --max-frames #NUM, which will then encode only the #NUM first frames you have specified.
The frame-rate can either be specified with the base clock frequency --timebase # in Hz and the duration of each frame in timebase units --duration #. Or you can specify --fps # directly as a floating point value and heif-enc will choose the timebase and frame duration itself.
When the input images have alpha channels, the HEIF file will contain the main video track and an auxiliary track for the alpha channel.
The ISO23001-17 (uncompressed) codec will encode the alpha channel in the main track and does not need an auxiliary track.
If your input images contain an alpha channel, but you want to ignore it, use the option --no-alpha.
HEIF image-sequences can contain an edit-list to play back the stored video multiple times. By default, the sequence is stored without edit-list, but if you specify --repetitions #NUM, the player should play back the sequence #NUM times. #NUM=1 results in no edit-list and the special value #NUM=infinite will enable looping the video without end.
Using --gop-structure MODE you can choose between
-
intra-onlyencoding, without any motion-prediction (I frames), -
low-delayencoding, only using backwards references (P frames), -
unrestrictedencoding, which allows all frame types (including B frames and frame reordering).
Note that the option will accept any unique prefix for MODE. That means that intra or just i will also work. Moreover, you can use i, p, b as an alternative. Not all encoders will honor these modes, but libheif tries to configure the codec as close as possible to the desired mode.
Moreover, you can specify a minimum and maximum distance for keyframes with --min-keyframe-distance # and --max-keyframe-distance #.
However, many encoders will ignore this setting, especially the minimum distance.
HEIF image-sequences can hold timed metadata in two ways:
- as sample auxiliary data (SAI), which is metadata assigned to each frame, and
- as a separate metadata track, which can be timed independently from the video track. That means that metadata packets can be placed at times between video frames.
A metadata track can be added by providing a data file to the option --vmt-metadata-track FILE that follows the syntax of a VMT file. However, not the full syntax is supported. Your files have to follow this format:
00:00:00.000 -->
Text at start of video.
00:00:00.100 -->
Text after 100ms.
00:00:00.200 -->
Text after 200ms.
The ASCII text on the lines following the timestamp will be put into a metadata packet until the next empty line.
Alternatively, binary data can be inserted by writing the data as hex values and specifying the option --binary-metadata-track.
00:00:00.000 -->
23 f8 7e f4 21
00:00:00.100 -->
23 43 92 85 45
ee f8 7f f1
00:00:00.200 -->
fc cf 23
Currently, libheif can only add TAI timestamps and GIMI content IDs as SAI packets. These have to be specified in a data file following this format:
suid
stai 10000,200,432432,12
---
a81a8e3b-2ae9-4762-a89d-a6de9eabadf9
2346923647982
a81a8e3b-2ae9-4762-a89d-a6dea94bc76e
2346923647576,1,1
a81a8e3b-2ae9-4762-a89d-a6dea94bd9e2
2346923647571
This consists of a header part (until the --- line) and the main part.
Each header line enables one SAI type. Currently, this can be suid for content IDs or stai for ISO23001-17 TAI timestamps.
The numbers after stai are the tai_clock_info values in the order time_uncertainty, clock_resolution, clock_drift_rate, clock_type.
The main part repeats groups of lines in the same order as in the header. Each group defines the SAI for one frame.
In our case, a81a8e3b-2ae9-4762-a89d-a6de9eabadf9 is the content ID (ASCII) for the first frame and 2346923647982 is its timestamp.
The next two lines define the data for the second frame. The timestamp may be followed by up to three boolean (0,1) parameters that define the
synchronization_state, timestamp_generation_failure, and timestamp_is_modified flags for the timestamp.
The option to set this data file is --sai-data-file FILE.