A tool for archiving & converting scans of postcards, and information about them.

Better format docs

+109 -119
+19
docs/formats/component.md
··· 1 + # Postcard components 2 + 3 + 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. 4 + 5 + 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: 6 + 7 + | Side files | `{name}` | Web file | 8 + |---------------------------------------------------------|-------------|--------------------------| 9 + | `mine-front.jpg`<br>`mine-back.png`<br>`mine-meta.yaml` | `postcard` | `mine.postcard.webp` | 10 + | `a-pc-front.png`<br>`a-pc-back.png`<br>`a-pc-meta.json` | `a-pc` | `a-pc.postcard.webp` | 11 + | `one-sided-only.jpg`<br>`one-sided-meta.yaml` | `one-sided` | `one-sided.postcard.jpg` | 12 + 13 + ## Notes 14 + 15 + - 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. 16 + - The front & back can be in any supported image format, but their _physical dimensions_ must be close to each other 17 + - Hyphens can be used in the `{name}` part, so long as the suffix is present (eg. `-front`) 18 + - 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). 19 + - 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
··· 1 1 # CSS 2 2 3 - 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. 3 + 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. 4 4 5 5 The 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. 6 + 7 + ## Example 8 + 9 + The following three output formats will create an HTML file that uses the CSS file to show the postcard in a visually appealing way. 10 + 11 + ```sh 12 + $ postcards -f css,html,web pyramids-front.jpg 13 + ⚙︎ Converting 1 postcard into 3 different formats… 14 + pyramids-front.jpg (Component files) → (CSS) postcards.css 15 + pyramids-front.jpg (Component files) → (HTML) pyramids.html 16 + pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg 17 + ```
+16 -2
docs/formats/html.md
··· 1 1 # HTML 2 2 3 - 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. 3 + 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. 4 + 5 + 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. 6 + 7 + 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. 4 8 5 - 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. 9 + ## Example 10 + 11 + 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. 12 + 13 + ```sh 14 + $ postcards -f html,css,web pyramids-front.jpg 15 + ⚙︎ Converting 1 postcard into 3 different formats… 16 + pyramids-front.jpg (Component files) → (HTML) pyramids.html 17 + pyramids-front.jpg (Component files) → (CSS) postcards.css 18 + pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg 19 + ```
+1 -1
docs/formats/metadata.md docs/formats/yaml.md
··· 1 - # Postcard metadata 1 + # Postcard metadata (YAML) 2 2 3 3 The 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
··· 1 - # Postcard sides 2 - 3 - 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. 4 - 5 - 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: 6 - 7 - | Side files | `{name}` | Web file | 8 - |---------------------------------------------------------------------|-------------|------------------| 9 - | `postcard-front.jpg`<br>`postcard-back.png`<br>`postcard-meta.yaml` | `postcard` | `postcard.webp` | 10 - | `a-pc-front.png`<br>`a-pc-back.png`<br>`a-pc-meta.json` | `a-pc` | `a-pc.webp` | 11 - | `one-sided-only.jpg`<br>`one-sided-meta.yaml` | `one-sided` | `one-sided.webp` | 12 - 13 - Notes: 14 - - The front & back can be in any supported image format, but their _physical dimensions_ must be relatively similar to each other 15 - - Hyphens can be used in the `{name}` part, so long as the suffix is present (eg. `-front`) 16 - - 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). 17 - - Metadata can be provided in JSON or YAML format, as desired 18 - - A metadata file must be present, and meet the minimum requirements as defined in the [metadata definition](./metadata.md)
+12
docs/formats/usd.md
··· 1 + # Universal Scene Description 3D format 2 + 3 + The component parts of a [USDZ file](usdz.md). 4 + 5 + ## Example 6 + 7 + ```sh 8 + $ postcards -f usd pyramids-front.jpg 9 + ⚙︎ Converting 1 postcard into 1 different format… 10 + pyramids-front.jpg (Component files) → (USD 3D model) pyramids.postcard.usd 11 + pyramids-front.jpg (Component files) → (USD 3D model) pyramids.postcard-texture.jpg 12 + ```
+11 -3
docs/formats/usdz.md
··· 1 - # USDZ format 1 + # Universal Scene Description (zip) format 2 2 3 - 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`. 3 + [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. 4 4 5 5 For postcards with only one side stored in the file the produced model will (by default) have the same image on both sides. 6 6 7 - 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. 7 + 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. 8 8 9 9 ## Requirements 10 10 11 11 USDZ 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. 12 + 13 + ## Example 14 + 15 + ```sh 16 + $ postcards -f usdz pyramids-front.jpg 17 + ⚙︎ Converting 1 postcard into 1 different format… 18 + pyramids-front.jpg (Component files) → (USDZ 3D model) pyramids.postcard.usdz 19 + ```
+19
docs/formats/web.md
··· 1 + # Web postcard format 2 + 3 + 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. 4 + 5 + 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. 6 + 7 + 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. 8 + 9 + ## Example 10 + 11 + 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. 12 + 13 + ```sh 14 + $ postcards -f web,css,html pyramids-front.jpg 15 + ⚙︎ Converting 1 postcard into 3 different formats… 16 + pyramids-front.jpg (Component files) → (Web) pyramids.postcard.jpg 17 + pyramids-front.jpg (Component files) → (CSS) postcards.css 18 + pyramids-front.jpg (Component files) → (HTML) pyramids.html 19 + ```
+16 -6
docs/formats/xmp.md
··· 1 1 # XMP Metadata 2 2 3 - 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` 3 + 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. 4 + 5 + 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. 6 + 7 + ## Structure 4 8 5 9 The 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: 6 10 11 + 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. 12 + 7 13 | XMP field | Schema | Postcard metadata | Use | 8 14 |-----------------------------|----------------|-----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------| 9 - | ImageWidth | TIFF | (from source images) | The pixel width of the combined image | 15 + | ImageWidth | TIFF | (from source images) | The pixel width of the combined image. | 10 16 | ImageLength | TIFF | (from source images) | The pixel height of the combined image | 11 17 | XResolution | TIFF | (from source images) | The cm width of the combined image (always the width of the front of the postcard) | 12 18 | YResolution | TIFF | (from source images) | The cm height of the combined image (always twice the height of the front of the postcard) | ··· 18 24 | GPSLongitude | Exif | location.longitude | The longitude of that location | 19 25 | AltTextAccessibility | IPTC4 XMP Core | front.description, back.transcription | Generated text suitable to be used as alt text for the postcard | 20 26 | 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 | 21 - | ImageRegionName | IPTC4 XMP Ext | - | A generic description of why an area of the postcard which has been masked as "secret" | 27 + | ImageRegionName | IPTC4 XMP Ext | - | Always "Private information" for secrets | 22 28 | ImageRegionBoundaryVertices | IPTC4 XMP Ext | front.secrets, back.secrets | The (normalized) x, y positions of the edges of the secret region | 23 - | ImageRegionBoundaryUnit | IPTC4 XMP Ext | - | Always "relative" (the vertex values are normalized to the width and height of the image) | 29 + | ImageRegionBoundaryUnit | IPTC4 XMP Ext | - | Always "relative" (the vertex values are normalized to the width and height of the **image**, not the side) | 24 30 | 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** | 25 31 | Sender | Postcard | sender | The name (and possibly URL) of the sender of the postcard | 26 32 | Recipient | Postcard | recipient | The name (and possibly URL) of the recipient of the postcard | 27 - | Context | Postcard | context.description | Any context provided about the postcard | 33 + | 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. | 28 34 | ContextAuthor | Postcard | context.author | The name (and possibly URL) of the author of the context | 29 - | - | - | locale | This metadata field is used to pick a suitable language for any fields above that are localised | 35 + | ThicknessMM | Postcard | physical.thickness_mm | The thickness of the postcard, if different to the standard 0.4mm | 36 + | DescriptionFront | Postcard | front.description | An alt-text style description of the front of the postcard | 37 + | DescriptionBack | Postcard | back.description | An alt-text style description of the back of the postcard | 38 + | TranscriptionFront | Postcard | front.transcription | The JSON blob representing the transcription of the front of the postcard (with annotations) | 39 + | TranscriptionBack | Postcard | back.transcription | The JSON blob representing the transcription of the back of the postcard (with annotations) |
+2 -88
docs/use-cases.md
··· 2 2 3 3 When I'm archiving images of a postcard 4 4 I want to store the front, back, and context/metadata (physical size, how it flips) together 5 - So that the component parts aren't accidentally lost/separated. 5 + So that I don't accidentally lose/separate the different parts. 6 6 7 7 I want to be able to mark areas as private and tastefully hide the information within them 8 8 So that I can hide my address when sharing or displaying. ··· 21 21 So that I get around to actually displaying it. 22 22 23 23 I want to be able to convert my postcard into a 3D format (eg. USDZ) 24 - So that the physicality of the postcard is preserved. 24 + So that I can preserve the physicality of the postcard. 25 25 26 26 I want to be able to extract metadata in easy to process formats (eg. JSON, YAML) 27 27 So that I can create static sites that show off the metadata as well as the front/back. 28 - 29 - ## Command line tool 30 - 31 - Example uses: 32 - 33 - ```bash 34 - $ postcards --help 35 - Usage: postcards [--output list,of,formats] [flags] postcard1-front.jpg [postcard2.yaml] 36 - 37 - $ tree 38 - . 39 - ├── postcard1-front.jpg 40 - ├── postcard1-back.jpg 41 - ├── postcard2.webp 42 - ├── postcard3.usdz 43 - ├── postcard4-only.png 44 - └── postcard4-meta.yaml 45 - 46 - # To build a postcard from scratch put a 'postcard1-front.{jpg,png,web}' and 47 - # a matching 'postcard1-back.{web,png,jpg}' in the same directory together and 48 - # request a metadata format (json or yaml) to have a template created for you 49 - $ postcards --output yaml postcard1-front.png 50 - postcard1: skipped, as metadata is missing 51 - ↪ Wrote new metadata file to postcard1-meta.yaml 52 - ℹ Edit this text file with information about your postcard 53 - 54 - $ tree 55 - . 56 - ├── postcard1-front.jpg 57 - ├── postcard1-back.jpg 58 - ├── postcard1-meta.yaml 59 - ├── postcard2.webp 60 - ├── postcard3.usdz 61 - ├── postcard4-only.png 62 - └── postcard4-meta.yaml 63 - 64 - # Create combined 'web' postcards from constituent parts, and display easily on the web 65 - $ postcards --output web,json,css postcard1-front.jpg 66 - postcard1: 10cm x 15cm (136 dpi) 67 - ↪ Wrote web postcard file to postcard1.webp 68 - ↪ Wrote metadata file to postcard1.json 69 - ↪ Wrote standard postcard CSS file to postcards.css 70 - ℹ This CSS expects your postcard HTML to be an image wrapped in a postcard div: 71 - <div class="postcard"><img src="your-postcard.webp" /></div> 72 - 73 - # Formats can be converted between losslessly 74 - $ postcards --output web,yaml postcard3.usdz 75 - postcard3: 12cm x 12cm (136 dpi) 76 - ↪ Wrote web postcard file to postcard3.webp 77 - ↪ Wrote metadata file to postcard3.yaml 78 - 79 - $ postcards --output 3d.json postcard2.webp 80 - postcard2: 14.8cm x 10.5cm (136 dpi) 81 - ↪ Wrote 3D postcard file to postcard2.usdz 82 - ↪ Wrote metadata file to postcard3.json 83 - 84 - # Whole directories can be processed at once 85 - $ postcards --output json * 86 - postcard1: 10.5cm x 14.8cm (136 dpi) 87 - ↪ Wrote metadata file to postcard1.json 88 - postcard2: 14.8cm x 10.5cm (136 dpi) 89 - ↪ Wrote metadata file to postcard2.json 90 - postcard3: 12cm x 12cm (136 dpi) 91 - ↪ Wrote metadata file to postcard3.json 92 - postcard4: 17.7cm x 12.7cm (136 dpi) 93 - ↪ Wrote metadata file to postcard4.json 94 - ``` 95 - 96 - ### Flags 97 - 98 - | Flag | Example | Purpose | Default | 99 - |----------------|-------------|-------------------------------------------------------|---------------------------------------------------| 100 - | -f, --formats | -f web,json | Choose the output formats to create | Required | 101 - | -A, --archival | -A | Uses lossless compression & does not downscale images | Off; fits within 1536x1536px & compresses lossily | 102 - 103 - ## Formats 104 - 105 - | Format | Filename | Purpose | Convertible? | 106 - |-----------|----------------------------|----------------------------------------------------------------------|--------------------------| 107 - | web | name.postcard.webp[^1] | A stacked front/back webp image with embedded XMP metadata | Yes, some metadata lost | 108 - | json,yaml | name-meta.{json,yaml} | A simple JSON/YAML file describing the metadata about a postcard | Yes, needs `sides` | 109 - | sides | name-{front,back}.webp[^1] | The separate front and back images of the postcard | Yes, needs `json`/`yaml` | 110 - | usd | name.usd, name-texture.png | A Universal Scene Description 3D model of the postcard (to scale) | Yes, no loss | 111 - | css | postcards.css | Outputs the (unchanging) CSS needed to display a postcard on the web | n/a | 112 - 113 - [^1]: These file formats are always output in the WebP format, but any of JPEG, PNG, WebP can be imported with their usual extensions.