Image variants or sets and addressing fragments (fMAP, fcTL, fdAT, aPAL)
Christoph Päper <[email protected]> Mon, 8 May 2017 13:26:25 +0200 (CEST)
| Newsgroups | gmane.comp.graphics.png.general |
|---|---|
| Message-ID | <301202734.8461.1494242785304.JavaMail.open-xchange@app06.ox.hosteurope.de> |
There are several reasons why and methods how people are putting multiple still images into a single file. PNG currently only supports some of them and only indirectly. Some use cases frequently require several very similar still bitmap images. They may only differ in a single color being substituted, which may be the background color or any other, or in a different palette being used which may be shared by several images. They may also differ simply by size or color mode, where lower resolution or low-fidelity versions are not necessarily the results of simple algorithmic transformations from the largest, most colorful image, cf. the ICO and other icon formats. I'm not at all interested in backporting everything found in MNG to PNG, but I only want PNG to 1. better support techniques already employed and 2. support multiple related variants of a semantically identical image. Sprite maps ------------ Regarding goal #1, PNGs are regularly used to contain a set of small images in a so-called sprite map (e.g. for a collection of emojis). Serving a single sprite map instead of many individual image files is more efficient when using HTTP 1.x. The authors of the MNG specification anticipated this use case when they wrote [Example 17: Storing an icon library](http://www.libpng.org/pub/mng/spec/#x17). In a sprite map, each icon is put into a virtual cell in a grid of vertical columns and horizontal rows. Their numbers and dimensions must be known and used externally. In CSS, this is traditionally achieved by using the `background-position` property for a PNG file included with the `background-image` property, but the recently added [`image()` notation](https://www.w3.org/TR/css3-images/#image-fragments) also requires support for spatial [Media Fragments], i.e. `#xywh=pixel:left-offset,top-offset,width,height` (`pixel:` is optional and `percent:` is also supported), which has some advantages, e.g. for repeated tiles. The [Media Fragments specification](https://www.w3.org/TR/media-frags/#naming-space), however, suggested that owners of media types like `image/png` (see [RFC2083]) should formally update their registration to include the `xywh` URL fragment (and/or query) parameter: > The Media Fragment WG has no authority to update registries of all targeted > media types. > We recommend media type owners to harmonize their existing schemes with the > ones proposed in this document > and update or add the fragment semantics specification to their media type > registration. It would be even more user-friendly if authors could reference sprites by a semantic name. The `IDAT` image resource within a PNG file does not have a natural language name, let alone multiple ones for arbitrary slices of it. I am proposing a new `fMAP` chunk below which may be able to achieve this, see the Github repository for details. I'm *not* proposing a method to directly reference cells in a grid, e.g. `#cell=2,6` or `#col=2;row=6`. <https://github.com/Crissov/PNG-extensions/blob/master/fcTL%2BfdAT.md> <https://github.com/Crissov/PNG-extensions/blob/master/fMAP.md> Please note that MNG does already support arbitrarily named views using the [`eXPI` chunk](http://www.libpng.org/pub/mng/spec/#mng-eXPI), but that adds some complexity not required for PNG: > The eXPI chunk takes a snapshot of a viewable object (either concrete or > abstract), > associates the name with that snapshot, > and makes the name available to the "outside world" (like a scripting > language). Sprite stack ------------ Sprite maps fall back to a planar overview of all available sprites. This is not desired in cases where there is a default image that has several variants. Emoji images of people, for instance, should usually come in a default gender-neutral, a female and a male variant, often identified either by a prefix `1f469`/`1F468` or a suffix `-2640`/`_2642` that is based upon the respective hexadecimal Unicode code point. Another example are "High DPI" or "Retina ready" bitmaps that come in multiple resolutions, which are either referred to by the pixel dimensions or by a (usually integer) scaling factor like `2x` that is often preceded by an at-sign in the file name, e.g. `[email protected]`, but other conventions also exist. A third use case is found in internationalization (i18n) or rather localization (l10n): some PNG files contain text and variants exists for other languages, which are currently often recorded in separate files with multiple dot-lead extensions based upon [BCP47], e.g. `map.en-us.png`. The default graphic should be found in `IDAT` chunks, but vanilla PNG does not have anything to put the alternatives in. I propose to take advantage of support in existing implementations by adopting the `fdAT` and `fcTL` chunks for this, which were introduced in the unofficial [APNG] extension currently maintained by Mozilla. Its proprietary `acTL` is not needed for this, because I'm *not* proposing to add animation support to PNG. The `fcTL` chunk type is only needed for unique numeric identifiers for each fragment, but I maintained compatibility with APNG by declaring some bytes reserved for future use. This means, `foo.png#2` should work, but, again, named fragments would be more user friendly, so the proposed `fMAP` chunk also applies to sprite stacks, so `dancing_emoji.png#male`, `icon.png#@3x` and `screenshot.png#UHD` would work. To make i18n more automatic, i.e. requiring less effort, `fMAP` should also support language tags, so implementations would, for instance, transparently and implicitly select `map.png#lang=en` if the embedding environment of the PNG file is tagged as `en-us`, while authors could still explicitly choose `map.png#french`. <https://github.com/Crissov/PNG-extensions/blob/master/fcTL%2BfdAT%2BfMAP.md> Layers --------- Layers are a can of worms that I don't want to open right now, but do think needs mentioning. A sprite stack where the default `IDAT` image has the largest dimensions and all `fdAT` fragments are partially transparent and all these chunks would be rendered at once would constitute a simple open layered image format with `IDAT` as the first or background layer. To be really useful, `fcTL` or another chunk type would need to learn to specify blending modes etc. This is stuff for a potential PNG 2.0, because the fallback to just the background seems inadequate in general. Palette manipulation ------------ Some image variants do not need additional bitmap data chunks at all. For example, each emoji that shows a body part or complete person comes in six variations for skin tones: non-human default, Fitzpatrick scale 1-2, 3, 4, 5 and 6 (darkest). Hair color and possibly eye color may also change with the complexion, but overall it's just about replacing the color values for some palette entries. PNG already supports suggested palettes with the `sPLT` chunk (and `PLTE`+`hIST` for the default), which can even be named, but these are tailored for dithering of true-color images on limited-color devices. I'm proposing to add a new `aPLT` chunk type with almost identical syntax to `sPLT` which would be used replace `PLTE` in color modes that use this chunk if requested by the user, e.g. via fragment identifiers `baby.png#pal=dark`. <https://github.com/Crissov/PNG-extensions/blob/master/aPLT.md> References ------------- [Media Fragments]: https://www.w3.org/TR/media-frags/ [RFC2083]: https://tools.ietf.org/html/rfc2083#section-8 "RFC 2083: PNG (Portable Network Graphics) Specification Version 1.0 (1997-03), section 8.2. Internet media type" [APNG]: https://wiki.mozilla.org/APNG_Specification [BCP47]: https://tools.ietf.org/html/bcp47 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot