···11+# Postcard components
22+33+This format describes having images for each side of your postcard. If you're scanning postcards and preparing them for use elsewhere with this tool then you'll be starting with this.
44+55+If you convert _to_ this format then you'll receive one image file for each side of the postcard. If you convert _from_ this format then you'll need one photo for each side you want to include _and_ a [metadata](yaml.md) file. The filenames _will all have_ (for output) or _must all have_ (for input) a common structure: `{name}-{type}.{ext}`. Eg:
66+77+| Side files | `{name}` | Web file |
88+|---------------------------------------------------------|-------------|--------------------------|
99+| `mine-front.jpg`<br>`mine-back.png`<br>`mine-meta.yaml` | `postcard` | `mine.postcard.webp` |
1010+| `a-pc-front.png`<br>`a-pc-back.png`<br>`a-pc-meta.json` | `a-pc` | `a-pc.postcard.webp` |
1111+| `one-sided-only.jpg`<br>`one-sided-meta.yaml` | `one-sided` | `one-sided.postcard.jpg` |
1212+1313+## Notes
1414+1515+- Metadata can be provided in YAML, JSON or XMP format, as desired — YAML is the easiest to write by hand, use `postcards init mine-front.jpg` to create a `mine-meta.yaml` file with examples & comments to help you.
1616+- The front & back can be in any supported image format, but their _physical dimensions_ must be close to each other
1717+- Hyphens can be used in the `{name}` part, so long as the suffix is present (eg. `-front`)
1818+- Transparency is preserved in input images (representing the postcard's shape). If present the mask should probably be the same (but suitably flipped) between the front and the back of the postcard (because they're two sides of the same object). This isn't enforced, but may cause issues with the [3D output formats](usdz.md).
1919+- A metadata file must be present, and meet the minimum requirements as defined in the [metadata definition](yaml.md)
+13-1
docs/formats/css.md
···11# CSS
2233-This output format produces the same `postcards.css` file every time, which can be used in conjunction with the [html](./html.md) format to display [./web.md] format postcards beautifully on the web.
33+This output format produces the same `postcards.css` file every time, which can be used in conjunction with the [html](html.md) format to display [web.md] format postcards beautifully on the web.
4455The CSS is modern, and makes use of [nesting](https://caniuse.com/css-nesting), so you may need to do some extra work if your target audience uses older browsers.
66+77+## Example
88+99+The following three output formats will create an HTML file that uses the CSS file to show the postcard in a visually appealing way.
1010+1111+```sh
1212+$ postcards -f css,html,web pyramids-front.jpg
1313+⚙︎ Converting 1 postcard into 3 different formats…
1414+pyramids-front.jpg (Component files) → (CSS) postcards.css
1515+pyramids-front.jpg (Component files) → (HTML) pyramids.html
1616+pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg
1717+```
+16-2
docs/formats/html.md
···11# HTML
2233-Used in conjunction with the [css](./css.md) format, this output format creates a sample `{name}.html` file with an HTML fragment that's suitable to display the postcard being converted.
33+Used in conjunction with the [css](css.md) and [web](web.md) formats, this output format creates a sample `{name}.html` file with an HTML fragment that's suitable to display the postcard being converted.
44+55+The HTML fragment produced has two sections separated by `\n\n` (the only `\n\n` in the file). The first of these sections can be discarded if you're injecting the HTML into an already established postcards page.
66+77+In the unlikely even that the CSS being produced by the [css](css.md) format changes in a backwards incompatible way (which will only happen after a breaking change release of this tool) then any HTML previously produced by this format may also need to be updated. Details on how to manually make the needed changes will be in the release notes for this tool.
4855-In the unlikely even that the CSS being produced by the [css](./css.md) format changes in a backwards incompatible way (which will only happen after a breaking change release of this tool) then any HTML previously produced by this format may also need to be updated. Details on how to manually make the needed changes will be in the release notes for this tool.
99+## Example
1010+1111+The following three output formats will create an HTML file that makes use of the CSS & web files to show the postcard in a visually appealing way.
1212+1313+```sh
1414+$ postcards -f html,css,web pyramids-front.jpg
1515+⚙︎ Converting 1 postcard into 3 different formats…
1616+pyramids-front.jpg (Component files) → (HTML) pyramids.html
1717+pyramids-front.jpg (Component files) → (CSS) postcards.css
1818+pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg
1919+```
+1-1
docs/formats/metadata.md
docs/formats/yaml.md
···11-# Postcard metadata
11+# Postcard metadata (YAML)
2233The native format for postcard metadata can be losslessly stored in [YAML](https://en.wikipedia.org/wiki/YAML) or [JSON](https://en.wikipedia.org/wiki/JSON) formats. When produced they will be called `{name}-meta.{ext}`.
-18
docs/formats/sides.md
···11-# Postcard sides
22-33-This format describes having images for each side of your postcard. If you're scanning postcards and preparing them for use elsewhere with this tool then you'll be starting with this.
44-55-If you convert _to_ this format then you'll receive one image file for each side of the postcard. If you convert _from_ this format then you'll need one photo for each side you want to include _and_ a [metadata](metadata.md) file. The filenames _will all have_ (for output) or _must all have_ (for input) a common structure: `{name}-{type}.{ext}`. Eg:
66-77-| Side files | `{name}` | Web file |
88-|---------------------------------------------------------------------|-------------|------------------|
99-| `postcard-front.jpg`<br>`postcard-back.png`<br>`postcard-meta.yaml` | `postcard` | `postcard.webp` |
1010-| `a-pc-front.png`<br>`a-pc-back.png`<br>`a-pc-meta.json` | `a-pc` | `a-pc.webp` |
1111-| `one-sided-only.jpg`<br>`one-sided-meta.yaml` | `one-sided` | `one-sided.webp` |
1212-1313-Notes:
1414-- The front & back can be in any supported image format, but their _physical dimensions_ must be relatively similar to each other
1515-- Hyphens can be used in the `{name}` part, so long as the suffix is present (eg. `-front`)
1616-- Transparency is preserved in input images (representing the postcard's shape). If present the mask should probably be the same (but suitably flipped) between the front and the back of the postcard (because they're two sides of the same object). This isn't enforced, but may cause issues with the [3D output format](usdz.md).
1717-- Metadata can be provided in JSON or YAML format, as desired
1818-- A metadata file must be present, and meet the minimum requirements as defined in the [metadata definition](./metadata.md)
+12
docs/formats/usd.md
···11+# Universal Scene Description 3D format
22+33+The component parts of a [USDZ file](usdz.md).
44+55+## Example
66+77+```sh
88+$ postcards -f usd pyramids-front.jpg
99+⚙︎ Converting 1 postcard into 1 different format…
1010+pyramids-front.jpg (Component files) → (USD 3D model) pyramids.postcard.usd
1111+pyramids-front.jpg (Component files) → (USD 3D model) pyramids.postcard-texture.jpg
1212+```
+11-3
docs/formats/usdz.md
···11-# USDZ format
11+# Universal Scene Description (zip) format
2233-The [Universal Scene Description format](https://en.wikipedia.org/wiki/Universal_Scene_Description) is a 3D modelling format that this tool can produce using postcard images and metadata, and convert from. When produced these files will be called `{name}.usdz`.
33+[USDZ](https://en.wikipedia.org/wiki/Universal_Scene_Description) is a 3D modelling format used extensively by Pixar and Apple. Postcards are created with the correct physical dimensions for augmented reality usage.
4455For postcards with only one side stored in the file the produced model will (by default) have the same image on both sides.
6677-Alongside the 3D model data the zip file that is the produced USDZ holds the [web](./web.md) format postcard in JPEG form. This is used directly as the texture file for the 3D model — it can be extracted manually if needed, but this tool will do this while performing consistency checks.
77+Alongside the 3D model data the zip file that is the produced USDZ holds the [web](web.md) format postcard in JPEG form. This is used directly as the texture file for the 3D model — it can be extracted manually if needed, but this tool will do this while performing consistency checks.
8899## Requirements
10101111USDZ creation requires that the `usdzip` tool is installed on yours system (see [OpenUSD](https://openusd.org/) for information). If you don't have access to that tool, you can still export in the `usd` format, which produces both the unzipped (and text-formatted) version of USD and the necessary texture file.
1212+1313+## Example
1414+1515+```sh
1616+$ postcards -f usdz pyramids-front.jpg
1717+⚙︎ Converting 1 postcard into 1 different format…
1818+pyramids-front.jpg (Component files) → (USDZ 3D model) pyramids.postcard.usdz
1919+```
+19
docs/formats/web.md
···11+# Web postcard format
22+33+The most versatile of the formats, the Web format holds both sides of the postcard within one image (the front above the back). The image contains [XMP](xmp.md) metadata that fully describes the postcard, so this format is also suitable for archive purposes.
44+55+If the postcard is 'heteroriented' (the back and front have different orientations) then the lower half will be rotated 90º clockwise (for left-hand flip postcards), or 90º anti-clockwise (for right-hand flip postcards), so that a Web format postcard is always the same width as the front of the postcard, and twice the height of the front.
66+77+By default this format uses lossy JPEGli compression and resizing to make a small but high quality image. If your input images use transparency, or if you request an 'archival' quality postcard, then it will produce a WebP format image that can support what you've requested.
88+99+## Example
1010+1111+The following three output formats will create a Web format postcard that makes use of the HTML & CSS files to show the postcard in a visually appealing way.
1212+1313+```sh
1414+$ postcards -f web,css,html pyramids-front.jpg
1515+⚙︎ Converting 1 postcard into 3 different formats…
1616+pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg
1717+pyramids-front.jpg (Component files) → (CSS) postcards.css
1818+pyramids-front.jpg (Component files) → (HTML) pyramids.html
1919+```
+16-6
docs/formats/xmp.md
···11# XMP Metadata
2233-Postcard metadata can be stored in [XMP format](https://en.wikipedia.org/wiki/Extensible_Metadata_Platform), which can be output directly using the `xmp` format, and is stored inside the images produced with the [web](web.md) format. When output they'll be called `{name}-meta.xmp`
33+Postcard metadata can be stored in [XMP format](https://en.wikipedia.org/wiki/Extensible_Metadata_Platform). Usually this is stored inside the images produced with the [web](web.md) output format.
44+55+Some features of metadata (particularly the location of secrets) assumes that the image being described is laid out like a Web format postcard — the front above the back, and the back rotated as in the Web format. When output directly with `-f xmp` a file `{name}-meta.xmp` will be produced — you may need to rename it to match the name of the postcard file (`{name}.postcard.xmp`) for other tools to recognise the association.
66+77+## Structure
4859The following XMP fields are used to store Postcard metadata. Some of them don't match _perfectly_ semantically (eg. the time the postcard was sent being represented by the tag usually used for when a photo was taken, or the GPS coordinates for the location the postcard references) — but they're close enough for human use. Postcard-specific machine uses should convert them according to the following guide:
6101111+Note that the TIFF schema fields (relating to image size) are omitted for XMP output directly (with `postcards -f xmp`), as image size information is only relevant when attached to a specific image.
1212+713| XMP field | Schema | Postcard metadata | Use |
814|-----------------------------|----------------|-----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
99-| ImageWidth | TIFF | (from source images) | The pixel width of the combined image |
1515+| ImageWidth | TIFF | (from source images) | The pixel width of the combined image. |
1016| ImageLength | TIFF | (from source images) | The pixel height of the combined image |
1117| XResolution | TIFF | (from source images) | The cm width of the combined image (always the width of the front of the postcard) |
1218| YResolution | TIFF | (from source images) | The cm height of the combined image (always twice the height of the front of the postcard) |
···1824| GPSLongitude | Exif | location.longitude | The longitude of that location |
1925| AltTextAccessibility | IPTC4 XMP Core | front.description, back.transcription | Generated text suitable to be used as alt text for the postcard |
2026| Transcript | IPTC4 XMP Ext | back.transcription, front.transcription | The transcript of any writing on the the postcard. A § character will divide the back and the front (in that order), if needed |
2121-| ImageRegionName | IPTC4 XMP Ext | - | A generic description of why an area of the postcard which has been masked as "secret" |
2727+| ImageRegionName | IPTC4 XMP Ext | - | Always "Private information" for secrets |
2228| ImageRegionBoundaryVertices | IPTC4 XMP Ext | front.secrets, back.secrets | The (normalized) x, y positions of the edges of the secret region |
2323-| ImageRegionBoundaryUnit | IPTC4 XMP Ext | - | Always "relative" (the vertex values are normalized to the width and height of the image) |
2929+| ImageRegionBoundaryUnit | IPTC4 XMP Ext | - | Always "relative" (the vertex values are normalized to the width and height of the **image**, not the side) |
2430| Flip | Postcard | flip | Which way the postcard should flip (book, calendar, left-hand, right-hand). **This field should be the one used to detect a postcard image** |
2531| Sender | Postcard | sender | The name (and possibly URL) of the sender of the postcard |
2632| Recipient | Postcard | recipient | The name (and possibly URL) of the recipient of the postcard |
2727-| Context | Postcard | context.description | Any context provided about the postcard |
3333+| Context | Postcard | context.description | Any context provided about the postcard. Always has `xml:lang` attribute, which is the `locale` of the metadata for the postcard. |
2834| ContextAuthor | Postcard | context.author | The name (and possibly URL) of the author of the context |
2929-| - | - | locale | This metadata field is used to pick a suitable language for any fields above that are localised |
3535+| ThicknessMM | Postcard | physical.thickness_mm | The thickness of the postcard, if different to the standard 0.4mm |
3636+| DescriptionFront | Postcard | front.description | An alt-text style description of the front of the postcard |
3737+| DescriptionBack | Postcard | back.description | An alt-text style description of the back of the postcard |
3838+| TranscriptionFront | Postcard | front.transcription | The JSON blob representing the transcription of the front of the postcard (with annotations) |
3939+| TranscriptionBack | Postcard | back.transcription | The JSON blob representing the transcription of the back of the postcard (with annotations) |
+2-88
docs/use-cases.md
···2233When I'm archiving images of a postcard
44 I want to store the front, back, and context/metadata (physical size, how it flips) together
55- So that the component parts aren't accidentally lost/separated.
55+ So that I don't accidentally lose/separate the different parts.
6677 I want to be able to mark areas as private and tastefully hide the information within them
88 So that I can hide my address when sharing or displaying.
···2121 So that I get around to actually displaying it.
22222323 I want to be able to convert my postcard into a 3D format (eg. USDZ)
2424- So that the physicality of the postcard is preserved.
2424+ So that I can preserve the physicality of the postcard.
25252626 I want to be able to extract metadata in easy to process formats (eg. JSON, YAML)
2727 So that I can create static sites that show off the metadata as well as the front/back.
2828-2929-## Command line tool
3030-3131-Example uses:
3232-3333-```bash
3434-$ postcards --help
3535-Usage: postcards [--output list,of,formats] [flags] postcard1-front.jpg [postcard2.yaml]
3636-3737-$ tree
3838-.
3939-├── postcard1-front.jpg
4040-├── postcard1-back.jpg
4141-├── postcard2.webp
4242-├── postcard3.usdz
4343-├── postcard4-only.png
4444-└── postcard4-meta.yaml
4545-4646-# To build a postcard from scratch put a 'postcard1-front.{jpg,png,web}' and
4747-# a matching 'postcard1-back.{web,png,jpg}' in the same directory together and
4848-# request a metadata format (json or yaml) to have a template created for you
4949-$ postcards --output yaml postcard1-front.png
5050-postcard1: skipped, as metadata is missing
5151-↪ Wrote new metadata file to postcard1-meta.yaml
5252-ℹ Edit this text file with information about your postcard
5353-5454-$ tree
5555-.
5656-├── postcard1-front.jpg
5757-├── postcard1-back.jpg
5858-├── postcard1-meta.yaml
5959-├── postcard2.webp
6060-├── postcard3.usdz
6161-├── postcard4-only.png
6262-└── postcard4-meta.yaml
6363-6464-# Create combined 'web' postcards from constituent parts, and display easily on the web
6565-$ postcards --output web,json,css postcard1-front.jpg
6666-postcard1: 10cm x 15cm (136 dpi)
6767-↪ Wrote web postcard file to postcard1.webp
6868-↪ Wrote metadata file to postcard1.json
6969-↪ Wrote standard postcard CSS file to postcards.css
7070-ℹ This CSS expects your postcard HTML to be an image wrapped in a postcard div:
7171- <div class="postcard"><img src="your-postcard.webp" /></div>
7272-7373-# Formats can be converted between losslessly
7474-$ postcards --output web,yaml postcard3.usdz
7575-postcard3: 12cm x 12cm (136 dpi)
7676-↪ Wrote web postcard file to postcard3.webp
7777-↪ Wrote metadata file to postcard3.yaml
7878-7979-$ postcards --output 3d.json postcard2.webp
8080-postcard2: 14.8cm x 10.5cm (136 dpi)
8181-↪ Wrote 3D postcard file to postcard2.usdz
8282-↪ Wrote metadata file to postcard3.json
8383-8484-# Whole directories can be processed at once
8585-$ postcards --output json *
8686-postcard1: 10.5cm x 14.8cm (136 dpi)
8787-↪ Wrote metadata file to postcard1.json
8888-postcard2: 14.8cm x 10.5cm (136 dpi)
8989-↪ Wrote metadata file to postcard2.json
9090-postcard3: 12cm x 12cm (136 dpi)
9191-↪ Wrote metadata file to postcard3.json
9292-postcard4: 17.7cm x 12.7cm (136 dpi)
9393-↪ Wrote metadata file to postcard4.json
9494-```
9595-9696-### Flags
9797-9898-| Flag | Example | Purpose | Default |
9999-|----------------|-------------|-------------------------------------------------------|---------------------------------------------------|
100100-| -f, --formats | -f web,json | Choose the output formats to create | Required |
101101-| -A, --archival | -A | Uses lossless compression & does not downscale images | Off; fits within 1536x1536px & compresses lossily |
102102-103103-## Formats
104104-105105-| Format | Filename | Purpose | Convertible? |
106106-|-----------|----------------------------|----------------------------------------------------------------------|--------------------------|
107107-| web | name.postcard.webp[^1] | A stacked front/back webp image with embedded XMP metadata | Yes, some metadata lost |
108108-| json,yaml | name-meta.{json,yaml} | A simple JSON/YAML file describing the metadata about a postcard | Yes, needs `sides` |
109109-| sides | name-{front,back}.webp[^1] | The separate front and back images of the postcard | Yes, needs `json`/`yaml` |
110110-| usd | name.usd, name-texture.png | A Universal Scene Description 3D model of the postcard (to scale) | Yes, no loss |
111111-| css | postcards.css | Outputs the (unchanging) CSS needed to display a postcard on the web | n/a |
112112-113113-[^1]: These file formats are always output in the WebP format, but any of JPEG, PNG, WebP can be imported with their usual extensions.