LayerZip is a program independent way to store 2d image layers using zip deflate, png, and a json file. it intentionally avoids any proprietary features that only 1 or a few programs support for maximum interoperability.
this document written on is the latest LayerZip Specification Semantic version 0.0.1. this is self-published independently.
<ul> of links.
layerzip.json with content described in The Configuration JSON.
layerzip.json file and it must be in the root directory
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "LayerZip Configuration",
"type": "object",
"required": [
"specVersion",
"width",
"height",
"layers"
],
"properties": {
"specVersion": {
"type": "string",
"pattern": "^0\\.0\\.1$",
"description": "the specification version. MUST be matched against the specification for disambiguation. in this schema it MUST be {\"0.0.1\"}. SHOULD be matched to disambiguate specifics of a LayerZip spec",
"$comment": "in terms of regex it must be {\"^\\d+\\.\\d+\\.\\d+$\"}"
},
"width": {
"type": "integer",
"minimum": 1,
"description": "MUST be the Width of the canvas, in pixels."
},
"height": {
"type": "integer",
"minimum": 1,
"description": "MUST be the Height of the canvas, in pixels."
},
"layers": {
"type": "array",
"description": "MUST be an array of layers",
"items": {
"$ref": "#/definitions/layer"
}
}
},
"definitions": {
"layer": {
"type": "object",
"description": "a layer",
"required": [
"type",
"name",
"path"
],
"properties": {
"type": {
"type": "string",
"enum": [
"rasterlayer",
"vectorlayer",
"grouplayer"
],
"description": "MUST be one of {\"rasterlayer\"} if a png is associated, {\"vectorlayer\"} if a svg is associated, {\"grouplayer\"} if a directory is associated."
},
"name": {
"type": "string",
"description": "the layer's name as seen in the editor. SHOULD be matched exactly."
},
"path": {
"type": "string",
"description": "the layer's path. MUST be Normalized. the path MUST start from the {\"layerzip.json\"}."
},
"visible": {
"type": "boolean",
"description": "if omitted MUST default to {{true}}. if present MUST be a json boolean representing if its visible in the editor. must be the actual layer content even if the layer is set to be visible false.",
"default": true
},
"locked": {
"type": "boolean",
"description": "if omitted MUST default to {{false}}. if present MUST be a json boolean representing if its locked in the editor. if the editor doesnt support layer locking then put false.",
"default": false
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "if omitted MUST default to {{1}}. if present MUST be a json number representing its opacity.",
"default": 1
},
"layers": {
"type": "array",
"items": {
"$ref": "#/definitions/layer"
},
"description": "if omitted MUST default to an empty array. MUST only exist if the type is {\"grouplayer\"}."
},
"blendMode": {
"type": "string",
"enum": [
"normal",
"multiply",
"screen",
"overlay",
"color-dodge",
"color-burn",
"hard-light",
"soft-light",
"difference"
],
"default": "normal",
"description": "Blend mode following CSS / Porter-Duff naming conventions. If omitted or unknown, MUST fallback to 'normal'. Editors SHOULD support at least the first four values."
}
}
}
}
}
| Field Name | Type | Field Requirements | Required | Field Description |
|---|---|---|---|---|
specVersion | string | string MUST match /^0\.0\.1$/) json regxep | True | the specification version. MUST be matched against the specification for disambiguation. in this schema it MUST be 0.0.1. SHOULD be matched to disambiguate specifics of a LayerZip spec
|
width | integer | 1 <= N | True | MUST be the Width of the canvas, in pixels. |
height | integer | 1 <= N | True | MUST be the Height of the canvas, in pixels. |
layers | array | None | True | MUST be an array of layers |
| Field Name | Type | Field Requirements | Required | Field Description |
|---|---|---|---|---|
type | string | one of
| True | MUST be one of rasterlayer if a png is associated, vectorlayer if a svg is associated, grouplayer if a directory is associated.
|
name | string | None | True | the layer's name as seen in the editor. SHOULD be matched exactly. |
path | string | None | True | the layer's path. MUST be Normalized. the path MUST start from the layerzip.json.
|
visible | boolean | None | False | if omitted MUST default to true. if present MUST be a json boolean representing if its visible in the editor. must be the actual layer content even if the layer is set to be visible false.
|
locked | boolean | None | False | if omitted MUST default to false. if present MUST be a json boolean representing if its locked in the editor. if the editor doesnt support layer locking then put false.
|
opacity | number | 0 <= N <= 1 | False | if omitted MUST default to 1. if present MUST be a json number representing its opacity.
|
layers | array | None | False | if omitted MUST default to an empty array. MUST only exist if the type is grouplayer.
|
blendMode | string | one of
| False | Blend mode following CSS / Porter-Duff naming conventions. If omitted or unknown, MUST fallback to 'normal'. Editors SHOULD support at least the first four values. |
While the Full Path Sanitization is implementation-defined, implementations MUST make sure the path follows these rules.
\/:*?"<>|/ as the path separator.
..) or current
directory indicators (.).
The LayerZip file requires a specific folder structure. At the root level, all layers that are not in
groups MUST be placed directly in the root directory. Layers that belong to a group
MUST be placed in a subdirectory named for that group. Layer paths in layerzip.json MUST exactly
match their relative paths from the layerzip.json file, using / as the path separator.
Implementations SHOULD normalize paths (e.g., remove redundant ./ or ../ segments),
but the exact normalization method is implementation-defined. Nested groups are allowed. If a group is
referenced in layerzip.json, its directory MUST exist in the archive. The directory MAY be empty if
no layers are currently assigned to that group, and tools SHOULD preserve empty directories to maintain group
hierarchy.
Example folder structure:
/layerzip.json /background.png /foreground.png /characters/hero.png /characters/enemies/villain.png /props/ (empty group directory allowed)
Layers MUST be ordered by array index; layers with a higher index MUST be displayed in front of layers with lower indices.
Compliant software implementations MUST follow these rules when handling a LayerZip file:
layerzip.json file to
determine project structure.
width and height
specified in the JSON.
visible, locked, and
opacity values for each layer. If a layer is set to visible: false, the
software MUST still load the image data to ensure it is immediately available if toggled on by the user.
Implementations MUST handle errors gracefully to maintain user data integrity. If a required file is missing, the
application SHOULD NOT crash, but rather render the layer as empty and notify the user. If the layerzip.json
file is invalid or corrupted, the application MUST alert the user and refuse to load the project.
Sanitization of file paths is REQUIRED to prevent path traversal vulnerabilities.
other than that programs SHOULD attempt to do the following when a spec Violation Occurs:
..)
or current directory indicators (.).
..)
and current directory indicators (.) are technically spec violations.
please tell me how i did. it was my first time writing something like this. this is self-published independently.