{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/codecs/images/avif",
  "collection": "docs",
  "title": "AVIF",
  "description": "AVIF stores AV1-coded still images and animations in a HEIF container, with strong lossy compression, HDR, alpha, and support in every current browser.",
  "canonicalUrl": "https://encode.wiki/codecs/images/avif/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/codecs/images/avif.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/codecs/images/avif.md",
  "status": "current",
  "tags": [
    "migrated",
    "images",
    "avif"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "libavif v1.4.2 avifenc implementation and options",
      "url": "https://github.com/AOMediaCodec/libavif/blob/v1.4.2/apps/avifenc.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libavif v1.4.2 SVT-AV1 adapter",
      "url": "https://github.com/AOMediaCodec/libavif/blob/v1.4.2/src/codec_svt.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libavif v1.4.2 changelog",
      "url": "https://github.com/AOMediaCodec/libavif/blob/v1.4.2/CHANGELOG.md",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libavif v1.4.0 release article (tune IQ default)",
      "url": "https://aomedia.org/blog%20posts/Libavif_v1_4_0-Boasts-Major-Updates-to-Encoder-Technology/",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libaom 3.12.0 release article (tune IQ)",
      "url": "https://aomedia.org/blog%20posts/Libaom-3_12_0-Now-Available-from-Codec-Working-Group/",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "AVIF specification v1.2.0",
      "url": "https://aomediacodec.github.io/av1-avif/v1.2.0.html",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libheif v1.23.6 AV1 plugins",
      "url": "https://github.com/strukturag/libheif/tree/v1.23.6/libheif/plugins",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "MDN browser compatibility data for AVIF",
      "url": "https://github.com/mdn/browser-compat-data/blob/main/mediatypes/image/avif.json",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "Android supported media formats",
      "url": "https://developer.android.com/media/platform/supported-formats",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "provenance": {
    "originUrl": "https://github.com/av1-community-contributors/codec-wiki/blob/37c3317fd058b23c71a87679bed5619a98f77752/docs/images/AVIF.mdx",
    "originCommit": "37c3317fd058b23c71a87679bed5619a98f77752",
    "migratedAt": "2026-08-21T00:00:00.000Z",
    "modified": true,
    "originPath": "docs/images/AVIF.mdx"
  },
  "headings": [
    {
      "depth": 2,
      "text": "Strengths and weaknesses",
      "anchor": "strengths-and-weaknesses"
    },
    {
      "depth": 2,
      "text": "Support",
      "anchor": "support"
    },
    {
      "depth": 2,
      "text": "Encode with avifenc",
      "anchor": "encode-with-avifenc"
    },
    {
      "depth": 3,
      "text": "Chroma: 4:4:4 or 4:2:0",
      "anchor": "chroma-444-or-420"
    },
    {
      "depth": 3,
      "text": "Tuning",
      "anchor": "tuning"
    },
    {
      "depth": 3,
      "text": "Backends",
      "anchor": "backends"
    },
    {
      "depth": 2,
      "text": "Alpha, HDR and animation",
      "anchor": "alpha-hdr-and-animation"
    },
    {
      "depth": 2,
      "text": "Pitfalls",
      "anchor": "pitfalls"
    },
    {
      "depth": 2,
      "text": "Other encoders",
      "anchor": "other-encoders"
    },
    {
      "depth": 2,
      "text": "Related pages",
      "anchor": "related-pages"
    },
    {
      "depth": 2,
      "text": "Full option reference",
      "anchor": "full-option-reference"
    },
    {
      "depth": 2,
      "text": "avifenc 1.4.2 complete parameter reference",
      "anchor": "avifenc-142-complete-parameter-reference"
    },
    {
      "depth": 2,
      "text": "libheif AVIF plugin references",
      "anchor": "libheif-avif-plugin-references"
    },
    {
      "depth": 3,
      "text": "libheif AOM plugin parameters",
      "anchor": "libheif-aom-plugin-parameters"
    },
    {
      "depth": 3,
      "text": "libheif rav1e plugin parameters",
      "anchor": "libheif-rav1e-plugin-parameters"
    },
    {
      "depth": 3,
      "text": "libheif SVT-AV1 plugin parameters",
      "anchor": "libheif-svt-av1-plugin-parameters"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/_preamble.md",
      "checksum": "01bf5c42ba6759669163f36571fdbe10e09d66116fe02afc94ada25f777f725f",
      "bytes": 526
    },
    {
      "id": "strengths-and-weaknesses",
      "title": "Strengths and weaknesses",
      "depth": 2,
      "anchor": "strengths-and-weaknesses",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#strengths-and-weaknesses",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/strengths-and-weaknesses.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/strengths-and-weaknesses.md",
      "checksum": "520c2e4ac2ec56960c93732db32c56f552847b8f02c4538c9c38a442313feab7",
      "bytes": 1483
    },
    {
      "id": "support",
      "title": "Support",
      "depth": 2,
      "anchor": "support",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#support",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/support.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/support.md",
      "checksum": "33ea962c845f4217b85a14c04190e580acc79509c1cd11c2a7d8b4927dcd8c85",
      "bytes": 1753
    },
    {
      "id": "encode-with-avifenc",
      "title": "Encode with avifenc",
      "depth": 2,
      "anchor": "encode-with-avifenc",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#encode-with-avifenc",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/encode-with-avifenc.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/encode-with-avifenc.md",
      "checksum": "2ed5f0da26dd08c1e2e8453f255ed8bed36d505433b5d41d29c6078a098a0757",
      "bytes": 5190
    },
    {
      "id": "chroma-444-or-420",
      "title": "Chroma: 4:4:4 or 4:2:0",
      "depth": 3,
      "anchor": "chroma-444-or-420",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#chroma-444-or-420",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/chroma-444-or-420.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/chroma-444-or-420.md",
      "checksum": "210904a1affb15b5b10af8e266f9d3b248098fb0f21707ecb336ca33daded8ca",
      "bytes": 400
    },
    {
      "id": "tuning",
      "title": "Tuning",
      "depth": 3,
      "anchor": "tuning",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#tuning",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/tuning.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/tuning.md",
      "checksum": "a42d16f6ea3be72848fee7307a9802aa45201d1bbd4fe4e5823cba2fc699a1f3",
      "bytes": 720
    },
    {
      "id": "backends",
      "title": "Backends",
      "depth": 3,
      "anchor": "backends",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#backends",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/backends.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/backends.md",
      "checksum": "73c1bc50dede3b65a461fa5f1575d2f2ad30e7f534e16efe1cf2bd5d0002a0a7",
      "bytes": 1294
    },
    {
      "id": "alpha-hdr-and-animation",
      "title": "Alpha, HDR and animation",
      "depth": 2,
      "anchor": "alpha-hdr-and-animation",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#alpha-hdr-and-animation",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/alpha-hdr-and-animation.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/alpha-hdr-and-animation.md",
      "checksum": "b71a5996772b7f33ecde14c6a74b2bb9d689d680bba2c536075e254f6b08b807",
      "bytes": 710
    },
    {
      "id": "pitfalls",
      "title": "Pitfalls",
      "depth": 2,
      "anchor": "pitfalls",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#pitfalls",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/pitfalls.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/pitfalls.md",
      "checksum": "0f3132e7c01d92b5af2d4808a5d1adaab4990da9aed55aab3366f3af1bb480a8",
      "bytes": 488
    },
    {
      "id": "other-encoders",
      "title": "Other encoders",
      "depth": 2,
      "anchor": "other-encoders",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#other-encoders",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/other-encoders.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/other-encoders.md",
      "checksum": "e63f57696cbb522a5915674d0e2472d61bf4532a4eaa48110131dfa870c6a11e",
      "bytes": 348
    },
    {
      "id": "related-pages",
      "title": "Related pages",
      "depth": 2,
      "anchor": "related-pages",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#related-pages",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/related-pages.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/related-pages.md",
      "checksum": "4eb8c3df0d35533ca3d0b22d9e189a6d2a84baaf213911f17e23a4287fedacef",
      "bytes": 333
    },
    {
      "id": "full-option-reference",
      "title": "Full option reference",
      "depth": 2,
      "anchor": "full-option-reference",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#full-option-reference",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/full-option-reference.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/full-option-reference.md",
      "checksum": "4c516e4f9d788150448e7249d1eacf20414e089496b50245241efc99e2d5312f",
      "bytes": 197
    },
    {
      "id": "avifenc-142-complete-parameter-reference",
      "title": "avifenc 1.4.2 complete parameter reference",
      "depth": 2,
      "anchor": "avifenc-142-complete-parameter-reference",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#avifenc-142-complete-parameter-reference",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/avifenc-142-complete-parameter-reference.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/avifenc-142-complete-parameter-reference.md",
      "checksum": "f4f2c3a4786899941685b0d27f7f41303b59cbf7113379c13b9ecb3af5fbb926",
      "bytes": 13322
    },
    {
      "id": "libheif-avif-plugin-references",
      "title": "libheif AVIF plugin references",
      "depth": 2,
      "anchor": "libheif-avif-plugin-references",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#libheif-avif-plugin-references",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-avif-plugin-references.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-avif-plugin-references.md",
      "checksum": "818c9a802e132ba767c3314c21807f58be684eec4c9ef069b1f4ac0d4453ba10",
      "bytes": 6422
    },
    {
      "id": "libheif-aom-plugin-parameters",
      "title": "libheif AOM plugin parameters",
      "depth": 3,
      "anchor": "libheif-aom-plugin-parameters",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#libheif-aom-plugin-parameters",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-aom-plugin-parameters.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-aom-plugin-parameters.md",
      "checksum": "f30c7eae9bbb40dfe108735a68d68f0263aa73baa4eb81eaf3e6a16e95ad2d83",
      "bytes": 2582
    },
    {
      "id": "libheif-rav1e-plugin-parameters",
      "title": "libheif rav1e plugin parameters",
      "depth": 3,
      "anchor": "libheif-rav1e-plugin-parameters",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#libheif-rav1e-plugin-parameters",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-rav1e-plugin-parameters.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-rav1e-plugin-parameters.md",
      "checksum": "e5729a28e1af8089a5a93459d930ebc16f7a8b3c0c88655ab78d2256cb23fb23",
      "bytes": 1692
    },
    {
      "id": "libheif-svt-av1-plugin-parameters",
      "title": "libheif SVT-AV1 plugin parameters",
      "depth": 3,
      "anchor": "libheif-svt-av1-plugin-parameters",
      "canonicalUrl": "https://encode.wiki/codecs/images/avif/#libheif-svt-av1-plugin-parameters",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-svt-av1-plugin-parameters.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/codecs/images/avif/libheif-svt-av1-plugin-parameters.md",
      "checksum": "75885500e79a3323be21325d02b2c317eb937bf4077d46824375efa3d5f64d35",
      "bytes": 1900
    }
  ],
  "outboundReferences": [
    "/codecs/images/heic/",
    "/codecs/images/heic/#heif-enc-1236-complete-frontend-reference",
    "/codecs/images/jpeg/",
    "/codecs/images/jxl/",
    "/codecs/images/webp/",
    "/codecs/video/av1/",
    "/reference/encoder-parameters/",
    "/reference/image-audio-support/",
    "/reference/metrics/ssimulacra2/",
    "/tools/software-encoders/aomenc/",
    "/tools/software-encoders/rav1e/",
    "/tools/software-encoders/svt-av1/",
    "https://developer.android.com/media/platform/supported-formats",
    "https://github.com/AOMediaCodec/libavif",
    "https://github.com/mdn/browser-compat-data/blob/main/mediatypes/image/avif.json",
    "https://github.com/rachelplusplus/tinyavif"
  ],
  "checksum": "6649f626c8ccebb5f8e813163a9928a12fcd593643fd26f72a73841ac515f97f",
  "contentFormat": "markdown",
  "markdown": "AVIF is AV1 intra-frame coding stored in a HEIF/ISO-BMFF container. It is the format to reach for when you want the smallest lossy images that every current browser can display, and it also gives you 10- and 12-bit depth, HDR signalling, alpha and animation. It is a poor choice for lossless archival, and encoding is slower than JPEG or WebP.\n\nThe container is the same family as [HEIC](/codecs/images/heic/); the payload is the [AV1](/codecs/video/av1/) video codec, so any AV1 encoder can in principle produce AVIF images.\n\n## Strengths and weaknesses\n\n**Strengths**\n\n- Very good lossy compression on photos and on flat graphics. At low and medium bitrates it beats [JPEG](/codecs/images/jpeg/) and [WebP](/codecs/images/webp/) by a wide margin; against [JPEG XL](/codecs/images/jxl/) it usually produces smaller files at web-delivery quality, while JPEG XL pulls ahead at very high quality and in lossless.\n- 8-, 10- and 12-bit, 4:2:0 / 4:2:2 / 4:4:4 / monochrome, wide gamut and HDR signalling (PQ, HLG), ICC or CICP colour, and a separate alpha plane.\n- Animation using real inter-frame video coding, which makes it a far better animated format than GIF or animated WebP for most clips.\n- Royalty-free, and supported by every current browser.\n\n**Weaknesses**\n\n- Slower encoding than JPEG, WebP or JPEG XL. libaom at its slowest speeds (`-s 0`–`3`) and on large images takes seconds to minutes per file.\n- Weak lossless mode. It is usually larger than lossless WebP or JPEG XL, and sometimes larger than PNG.\n- No JPEG-style progressive decode: a plain AVIF shows nothing until enough of the file has arrived. Layered \"progressive\" files exist in the AVIF 1.2 spec and `avifenc --progressive` can write them, but check your target decoders before relying on them.\n- Smooth gradients can band and fine texture can smear at low bitrates, and 4:2:0 bleeds saturated colour edges and small coloured text.\n- Very large images need tiling or a grid, which costs a little efficiency and can leave faint seams.\n\n## Support\n\n| Platform                    | Still AVIF                                                | Notes                                             |\n| --------------------------- | --------------------------------------------------------- | ------------------------------------------------- |\n| Chrome                      | 85+                                                       | Other Chromium browsers follow their Chromium version |\n| Firefox                     | 93+                                                       | Animated AVIF from Firefox 113                    |\n| Edge                        | 121+                                                      |                                                   |\n| Safari                      | 16.4+ on macOS, 16.1+ on iOS                              | Safari 16.1–16.3 on macOS worked only on Ventura  |\n| Android system decoder      | Android 12+ (8-bit)                                       | 10-bit decoding is optional per device            |\n\nBrowser versions are from [MDN's AVIF data](https://github.com/mdn/browser-compat-data/blob/main/mediatypes/image/avif.json) and Android's [supported media formats](https://developer.android.com/media/platform/supported-formats). Desktop OS thumbnailers, editors and messaging apps are patchier than browsers; see [image and audio support](/reference/image-audio-support/) for how to check a given file.\n\nProfiles matter less than they used to, but they still bound what a conservative decoder accepts. The Baseline brand (`MA1B`) is AV1 Main profile (8/10-bit, 4:2:0 or monochrome) at level 5.1 or lower; the Advanced brand (`MA1A`) is High profile (adds 4:4:4) up to level 6.0. Larger images are built from a grid of tiles.\n\n## Encode with avifenc\n\n`avifenc` from [libavif](https://github.com/AOMediaCodec/libavif) is the standard encoder. It takes PNG, JPEG or Y4M input and calls an AV1 backend (libaom, SVT-AV1 or rav1e, whatever your build includes).\n\n```sh\navifenc -q 65 -s 4 input.png output.avif\n```\n\n`-q` and `-s` are the two knobs you will actually turn. The defaults are `-q 60` and `-s 6`. Pick the quality by eye at a fast speed, then encode the final file at `-s 4` or slower; speeds below 4 cost a lot of time for a small gain.\n\n| Option                | What it does                                                                                                                                  |\n| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| `-q 0..100`           | Colour quality; 100 is lossless AV1 coding. Not comparable between backends or libavif releases.                                              |\n| `--qalpha 0..100`     | Alpha quality, inherited from `-q` unless set. Use `--qalpha 100` if the alpha edge must stay clean.                                           |\n| `-s 0..10`            | Speed; lower is slower and smaller. Default 6.                                                                                                |\n| `-d 8/10/12`          | Output bit depth; follows 8-bit input by default. Use 10 for HDR and high-bit-depth sources. `-d 10` is also common for 8-bit sources because it reduces banding in smooth gradients. |\n| `-y 444/422/420/400`  | Chroma format. `auto` gives 4:4:4 for PNG, keeps the subsampling of a JPEG and uses 4:0:0 for greyscale PNG.                                  |\n| `--sharpyuv`          | Sharper RGB→4:2:0 conversion; only does anything with `-y 420`.                                                                               |\n| `-c aom/svt/rav1e`    | Choose the backend.                                                                                                                           |\n| `-j N`                | Worker threads (default `all`).                                                                                                               |\n| `-a KEY=VALUE`        | Pass a backend option, e.g. `-a tune=iq`. libaom keys can be limited to one plane with `color:` or `alpha:`.                                  |\n| `-l`                  | Lossless: sets RGB-identity, full-range, 4:4:4 defaults.                                                                                      |\n| `--cicp P/T/M`, `--icc` | Signal colour primaries/transfer/matrix or attach an ICC profile.                                                                             |\n\n### Chroma: 4:4:4 or 4:2:0\n\n`avifenc` keeps 4:4:4 for PNG input, and libaom handles 4:4:4 well, so the extra chroma usually costs little. Keep it for screenshots, UI, line art and coloured text, where 4:2:0 visibly bleeds colour. Use `-y 420` (plus `--sharpyuv`) when you need the smallest photo files or files that stay within the Baseline brand and AV1 Main profile that hardware decoders support.\n\n### Tuning\n\nSince libavif 1.4.0, `avifenc` with libaom 3.13 or newer encodes still images (YUV, not RGB-matrix) with `tune=iq` by default, and maps `-q` to quantizers with a formula designed for it. `tune=iq` is libaom's still-image mode, added in 3.12: it was developed with [SSIMULACRA2](/reference/metrics/ssimulacra2/) as a guide and checked visually, and uses Variance Boost, adaptive CDEF and quantization matrices. Alpha is encoded with `tune=psnr`, because `tune=ssim` causes ringing on alpha.\n\nThe older recipe of `-a tune=ssim -a end-usage=q -a cq-level=…` is obsolete: use `-q` and leave the tune alone. Because `tune=iq` was shaped around SSIMULACRA2, check comparisons against other tunes by eye as well.\n\n### Backends\n\n| Backend      | Notes                                                                                                                                                                                     |\n| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| libaom       | The default and the usual best choice for stills: full chroma and bit-depth support, `tune=iq`, and the most intra-coding work behind it.                                                    |\n| SVT-AV1      | Faster, but libavif's SVT adapter is 4:2:0 only, 8/10-bit. A PNG defaults to 4:4:4, so `-c svt` without `-y 420` fails with \"Only support 420 now\". The libaom `-a` keys do not apply. |\n| rav1e        | Works, but is slow for stills and lacks libaom's still-image tuning.                                                                                                                         |\n\nlibheif's `heif-enc --avif` is a second frontend with the same backends and its own defaults (quality 50); its plugin parameter tables are in the reference below. AVIF is also writable from FFmpeg and ImageMagick, which go through libavif or libheif.\n\n## Alpha, HDR and animation\n\n- **Alpha** is stored as a separate monochrome AV1 image, so it has its own quality (`--qalpha`). Use `-p` only if you intend premultiplied (associated) alpha.\n- **HDR**: keep the source's real transfer function and primaries (`--cicp 9/16/9` for PQ BT.2020, `9/18/9` for HLG) and encode at 10 bit or more. Tagging SDR pixels as PQ does not make them HDR. In builds with gain-map support, `avifenc` converts gain maps embedded in JPEG input (`--qgain-map`, `--ignore-gain-map`).\n- **Animation**: pass several PNGs with `--fps`, or pipe Y4M from FFmpeg: `ffmpeg -i in.mp4 -pix_fmt yuv420p -f yuv4mpegpipe - | avifenc --stdin out.avif`. Firefox plays animated AVIF from version 113.\n\n## Pitfalls\n\n- A lossless AV1 stream does not make the file lossless: RGB→YUV conversion and 4:2:0 are lossy unless you use `-l`.\n- `avifenc` copies Exif, XMP and ICC from PNG and JPEG input and turns the Exif orientation into AVIF `irot`/`imir` transforms. Use `--ignore-exif`, `--ignore-xmp` or `--ignore-icc` to drop them; dropping the ICC profile of a wide-gamut source changes its colours.\n- Re-encoding an AVIF from a previous lossy AVIF compounds loss; keep the original source.\n\n## Other encoders\n\nAny AV1 encoder can produce AVIF; see [aomenc](/tools/software-encoders/aomenc/), [SVT-AV1](/tools/software-encoders/svt-av1/) and [rav1e](/tools/software-encoders/rav1e/). Rachel Barker's [tinyavif](https://github.com/rachelplusplus/tinyavif) is a minimal AVIF encoder written to show how AVIF and AV1 work, not for production.\n\n## Related pages\n\n- [AV1](/codecs/video/av1/) is the video codec underneath.\n- [JPEG XL](/codecs/images/jxl/) has lossless JPEG recompression and a stronger lossless and high-quality story.\n- [WebP](/codecs/images/webp/) is the older, faster, 8-bit-only alternative.\n- [HEIC](/codecs/images/heic/) uses the same container with HEVC.\n\n## Full option reference\n\nThe tables below are the full `avifenc` and libheif AVIF plugin parameter references. [Reading option tables](/reference/encoder-parameters/) explains the Default column.\n\n## avifenc 1.4.2 complete parameter reference\n\n<details>\n<summary>INPUT to --target-size</summary>\n\n| Parameter / aliases                                                    | Type or accepted values   | Default                                    | Purpose and constraints                                                                                                          |\n| ---------------------------------------------------------------------- | ------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |\n| `INPUT`                                                                | path(s)                   | required                                   | JPEG, PNG or Y4M input. Several inputs make an animated sequence, or the layers/cells with --layered/--grid. |\n| `OUTPUT`                                                               | path                      | required, unless --output is used          | Output .avif. Taken from the last positional argument unless --output is given. |\n| `--help`, `-h`                                                         | action                    | not requested                              | Print usage and the compiled-in codec versions. |\n| `--version`, `-V`                                                      | action                    | not requested                              | Print the libavif and codec library versions. |\n| `--qcolor`, `-q`, `--qcolor:u`, `--qcolor:update`, `-q:u`, `-q:update` | integer 0–100             | 60                                         | Colour quality, 0–100. 100 is lossless AV1 coding, though RGB→YUV conversion can still be lossy. The :u forms apply only to the inputs after them. |\n| `--qalpha`, `--qalpha:u`, `--qalpha:update`                            | integer 0–100             | same as qcolor | Alpha quality, 0–100. Follows --qcolor unless set. |\n| `--speed`, `-s`                                                        | 0–10, default or d        | 6                                          | Encoder speed, 0 (slowest) to 10, or default/d for the codec's own default. Slower is smaller. |\n| `--jobs`, `-j`                                                         | positive integer or all   | all detected CPUs                          | Worker threads, or all. What it controls depends on the codec. |\n| `--no-overwrite`                                                       | flag                      | false                                      | Fail instead of replacing an existing output file. |\n| `--output`, `-o`                                                       | path                      | final positional filename                  | Output path, instead of the last positional argument. |\n| `--lossless`, `-l`                                                     | flag                      | false                                      | Set lossless defaults: quality 100, full range, 4:4:4 and identity matrix. Warns when the input can't be stored losslessly. |\n| `--depth`, `-d`                                                        | D[,extension]             | input-dependent                            | Output bit depth, 8, 10 or 12. A second value (8,8 / 12,4 / 12,8) adds a hidden extension image for 16-bit output. Y4M keeps its own depth. |\n| `--yuv`, `-y`                                                          | auto, 444, 422, 420, 400  | auto                                       | Chroma format: auto, 444, 422, 420 or 400. auto keeps a JPEG's subsampling, uses 400 for greyscale PNG and 444 otherwise; Y4M keeps its format. |\n| `--premultiply`, `-p`                                                  | flag                      | false                                      | Multiply colour by alpha before encoding and mark alpha as premultiplied. Changes pixel values. |\n| `--sharpyuv`                                                           | flag                      | false                                      | Sharper RGB→4:2:0 conversion (needs libsharpyuv). No effect on Y4M or non-4:2:0 output. |\n| `--stdin`                                                              | flag                      | false                                      | Read one stream (Y4M by default) from standard input. No other input paths are allowed; the output path is still required. |\n| `--input-format`                                                       | auto, jpg, jpeg, png, y4m | auto for paths; y4m for stdin              | Force the input type: jpeg/jpg, png, y4m or auto. Needed only when the extension is misleading. |\n| `--cicp`, `--nclx`                                                     | P/T/M integers            | 2/2/6 before input-specific handling       | Colour primaries/transfer/matrix as three numbers (H.273); 2 means unspecified. Tags the file; samples are not converted. |\n| `--range`, `-r`                                                        | full/f or limited/l       | full for JPEG/PNG; retained for Y4M        | YUV range, full or limited. Y4M input keeps its own range. |\n| `--target-size`                                                        | positive bytes            | disabled                                   | Aim for this file size in bytes by searching over quality. Up to 7× slower; conflicts with fixed --qcolor/--qalpha. |\n\n</details>\n\n<details>\n<summary>--progressive to --irot</summary>\n\n| Parameter / aliases                | Type or accepted values   | Default                            | Purpose and constraints                                                                                           |\n| ---------------------------------- | ------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- |\n| `--progressive`                    | flag                      | false                              | Write a two-layer image that can render progressively from one input. Needs --qcolor of at least 10; support is limited. |\n| `--layered`                        | flag                      | false                              | Encode two to four inputs as layers of one image. Not an animation. |\n| `--grid`, `-g`                     | columns x rows            | disabled                           | Write a grid of COLSxROWS cells, from identical inputs or one image split evenly. |\n| `--codec`, `-c`                    | build-specific encoder ID | auto                               | Pick the AV1 encoder, for example aom, rav1e or svt. Decoder-only IDs can't encode. |\n| `--exif`                           | payload path              | preserve input metadata if present | Use this Exif payload instead of any embedded Exif. |\n| `--xmp`                            | payload path              | preserve input metadata if present | Use this XMP payload instead of any embedded XMP. |\n| `--icc`                            | profile path              | preserve input profile if present  | Use this ICC profile instead of any embedded one. Tags the image; samples are not converted. |\n| `--timescale`, `--fps`             | positive integer          | 30; may inherit Y4M timing         | Sequence ticks per second. With one-tick frames this is the frame rate. Y4M frame rate is used if unset. |\n| `--creation-time`                  | nonnegative Unix seconds  | 0: use modification time           | Sequence creation time in Unix seconds. 0 uses the modification time. |\n| `--modification-time`              | nonnegative Unix seconds  | 0: use current time                | Sequence modification time in Unix seconds. 0 uses the current time. |\n| `--keyframe`, `-k`                 | integer                   | 0: disabled                        | Maximum keyframe interval for sequences, in frames. 0 disables the limit. |\n| `--ignore-exif`                    | flag                      | false                              | Drop embedded Exif. |\n| `--ignore-xmp`                     | flag                      | false                              | Drop embedded XMP. |\n| `--ignore-icc`, `--ignore-profile` | flag                      | false                              | Drop the embedded ICC profile. |\n| `--ignore-gain-map`                | build-gated flag          | false                              | Drop an embedded JPEG gain map. Needs a libavif built with gain-map conversion. |\n| `--qgain-map`                      | build-gated integer 0–100 | 60                                 | Gain map quality, 0–100. Needs a gain-map build; takes no :u form. |\n| `--pasp`                           | H,V positive spacing      | absent                             | Pixel aspect ratio as H,V. Metadata only. |\n| `--crop`                           | x,y,width,height          | absent                             | Clean-aperture crop as x,y,width,height. Applied at display time; pixels are not removed. |\n| `--clap`                           | eight rational components | absent                             | Clean aperture as eight numerator/denominator values: width, height, horizontal offset, vertical offset. |\n| `--irot`                           | integer 0–3               | absent                             | Rotation in 90° steps anticlockwise (0–3). Stored as a transform. |\n\n</details>\n\n<details>\n<summary>--imir to --</summary>\n\n| Parameter / aliases                                                          | Type or accepted values         | Default                   | Purpose and constraints                                                                              |\n| ---------------------------------------------------------------------------- | ------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- |\n| `--imir`                                                                     | 0 or 1                          | absent                    | Mirror axis: 0 top-to-bottom, 1 left-to-right. Stored as a transform. |\n| `--clli`                                                                     | MaxCLL,MaxPALL                  | absent                    | MaxCLL,MaxPALL content light level metadata. Doesn't make the image HDR. |\n| `--repetition-count`                                                         | nonnegative integer or infinite | infinite                  | How many times a sequence plays, or infinite. |\n| `--tilerowslog2`, `--tilerowslog2:u`, `--tilerowslog2:update`                | integer 0–6                     | 0 before automatic tiling | log2 of the number of tile rows (0–6). Setting it switches to manual tiling. |\n| `--tilecolslog2`, `--tilecolslog2:u`, `--tilecolslog2:update`                | integer 0–6                     | 0 before automatic tiling | log2 of the number of tile columns (0–6). Setting it switches to manual tiling. |\n| `--autotiling`, `--autotiling:u`, `--autotiling:update`                      | flag                            | true                      | Choose AV1 tiling automatically. This is the starting mode; it is separate from a HEIF grid. |\n| `--min`, `--min:u`, `--min:update`                                           | deprecated quantizer 0–63       | 0                         | Deprecated minimum quantizer (0–63). Use --qcolor. |\n| `--max`, `--max:u`, `--max:update`                                           | deprecated quantizer 0–63       | 63                        | Deprecated maximum quantizer (0–63). Use --qcolor. |\n| `--minalpha`, `--minalpha:u`, `--minalpha:update`                            | deprecated quantizer 0–63       | 0                         | Deprecated minimum alpha quantizer (0–63). Use --qalpha. |\n| `--maxalpha`, `--maxalpha:u`, `--maxalpha:update`                            | deprecated quantizer 0–63       | 63                        | Deprecated maximum alpha quantizer (0–63). Use --qalpha. |\n| `--scaling-mode`, `--scaling-mode:u`, `--scaling-mode:update`                | positive N[/D]                  | 1/1                       | Frame or layer scaling as N[/D], for example 1/2. |\n| `--duration`, `--duration:u`, `--duration:update`                            | positive clock ticks            | 1; may inherit Y4M timing | Frame duration in timescale ticks for the following inputs. Applies with or without :u. |\n| `--advanced`, `-a`, `--advanced:u`, `--advanced:update`, `-a:u`, `-a:update` | KEY[=VALUE], repeatable         | none                      | Pass KEY[=VALUE] straight to the codec, for example -a tune=ssim. Repeatable. Keys are the codec's own. |\n| `--mini`                                                                     | build-gated flag                | false                     | Compact-header writer. Needs a build with AVIF_ENABLE_EXPERIMENTAL_MINI; not in current binaries. |\n| `--`                                                                         | separator                       | not used                  | End of options; later arguments are filenames. |\n\n</details>\n\n## libheif AVIF plugin references\n\nPlugin parameters for `heif-enc --avif -e aom|rav1e|svt`, set with `-p NAME=VALUE`. The full `heif-enc` frontend reference is on the [HEIC page](/codecs/images/heic/#heif-enc-1236-complete-frontend-reference).\n\n### libheif AOM plugin parameters\n\n| Parameter / aliases | Type or accepted values | Default                                          | Purpose and constraints                                                                      |\n| ------------------- | ----------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------- |\n| `realtime`          | boolean                 | false                                            | Use libaom's realtime mode instead of good-quality mode. Faster, larger. |\n| `speed`             | integer 0–9             | 6                                                | libaom cpu-used, 0 is slowest. Realtime mode changes what the values mean. |\n| `threads`           | integer 1–64            | CPU count, max 64 (4 if undetectable) | Worker threads. |\n| `quality`           | integer 0–100           | 50                                               | Colour quality. |\n| `lossless`          | boolean                 | false                                            | Lossless colour coding. |\n| `chroma`            | 420, 422 or 444         | 420                                              | Chroma subsampling. Lossless RGB needs 444. |\n| `tune`              | auto, psnr, ssim or iq  | auto                                             | auto picks by image type (still, sequence, alpha). iq can't be combined with lossless. |\n| `min-q`             | integer 0–63            | 0                                                | Lowest quantizer index the encoder may use. |\n| `max-q`             | integer 0–63            | 63                                               | Highest quantizer index the encoder may use. |\n| `alpha-quality`     | integer 0–100           | same as quality | Alpha quality. Follows the colour quality if unset. |\n| `alpha-min-q`       | integer 0–63            | same as min-q | Lowest alpha quantizer. Follows min-q if unset. |\n| `alpha-max-q`       | integer 0–63            | same as max-q | Highest alpha quantizer. Follows max-q if unset. |\n| `lossless-alpha`    | boolean                 | false                                            | Code alpha losslessly while colour stays lossy. |\n| `auto-tiles`        | boolean                 | false                                            | Let libaom choose the tile layout. |\n| `enable-intrabc`    | boolean                 | true                                             | Allow intra block copy, which helps screen content. |\n\n### libheif rav1e plugin parameters\n\n| Parameter / aliases | Type or accepted values      | Default                                            | Purpose and constraints                                                                                                         |\n| ------------------- | ---------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| `speed`             | integer 0–10                 | 8                                                  | rav1e speed, 0 is slowest. |\n| `threads`           | integer 1–16                 | 4                                                  | Worker threads. |\n| `tile-rows`         | 1, 2, 4, 8, 16, 32, 64       | 4                                                  | Number of tile rows (a count, not the log2 value avifenc uses). |\n| `tile-cols`         | 1, 2, 4, 8, 16, 32, 64       | 4                                                  | Number of tile columns (a count, not log2). |\n| `chroma`            | 420, 422 or 444              | 420                                                | Chroma subsampling. |\n| `min-q`             | integer 0–255                | 0                                                  | Lowest quantizer rav1e may use. |\n| `quality` | integer 0–100, -q only | 50 (set by heif-enc) | Set with heif-enc -q and mapped to a 0–255 quantizer. Not in the parameter list, so -p quality= is rejected. |\n| `lossless` | not settable | unsupported | No lossless mode: -L falls back to lossy with a warning, and -p lossless= is rejected. |\n\n### libheif SVT-AV1 plugin parameters\n\n| Parameter / aliases | Type or accepted values     | Default                     | Purpose and constraints                                                                           |\n| ------------------- | --------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- |\n| `speed`             | integer 0–13                | 12                          | SVT-AV1 preset. Lower is slower and smaller. |\n| `threads`           | integer 1–16                | 4                           | Thread hint, not a guaranteed worker count. |\n| `tile-rows`         | 1, 2, 4, 8, 16, 32, 64      | 4                           | Number of tile rows. |\n| `tile-cols`         | 1, 2, 4, 8, 16, 32, 64      | 4                           | Number of tile columns. |\n| `quality`           | integer 0–100               | 50                          | Quality, converted to a QP unless qp is set. |\n| `lossless` | boolean, SVT ≥3 | false | Lossless coding, SVT-AV1 3 or newer. heif-enc -L on RGB input (PNG, JPEG) exits with 'Unsupported encoder parameter' because it also sets chroma=444, which this plugin lacks. |\n| `qp`                | integer 0–63                | unset: derived from quality | Quantizer. Overrides quality when set. |\n| `min-q`             | integer 0–63                | 0                           | Lowest quantizer SVT-AV1 may use. |\n| `max-q`             | integer 0–63                | 63                          | Highest quantizer SVT-AV1 may use. |\n| `tune`              | vq, psnr, ssim, iq, ms-ssim | psnr                        | SVT-AV1 tune: vq, psnr, ssim, iq, ms-ssim. iq and ms-ssim need SVT-AV1 4 or newer. |\n| `chroma` | fixed 420 | 420 | Not a parameter: the plugin always encodes YCbCr 4:2:0, and -p chroma= is rejected. |\n"
}
