{"id":18647681,"url":"https://github.com/artcom/klear","last_synced_at":"2025-07-15T15:38:37.399Z","repository":{"id":141082273,"uuid":"10823130","full_name":"artcom/klear","owner":"artcom","description":"Create and manage Choreographies for lights and motors on the Manta Rhei and other kinetic installations","archived":false,"fork":false,"pushed_at":"2013-11-26T17:29:03.000Z","size":3616,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-17T19:37:55.851Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-20T15:36:16.000Z","updated_at":"2013-11-26T17:29:04.000Z","dependencies_parsed_at":"2023-03-13T10:39:18.533Z","dependency_job_id":null,"html_url":"https://github.com/artcom/klear","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/artcom/klear","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artcom%2Fklear","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artcom%2Fklear/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artcom%2Fklear/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artcom%2Fklear/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artcom","download_url":"https://codeload.github.com/artcom/klear/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artcom%2Fklear/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265443549,"owners_count":23766410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T06:27:26.062Z","updated_at":"2025-07-15T15:38:37.373Z","avatar_url":"https://github.com/artcom.png","language":"Ruby","readme":"# The klear File Format and Command Line Utility\n\nThe `klear` file format standardises our way to store animation data for motors\nand/or lights in installations. `klear` stands for: Kinetic Light Engine\nArchive. \n\nThis document describes the Kinetic Light Engine File Format which contains\nChoreographies and all data needed for playing it.  This repo also contains the\n*klear* ruby gem which provides library code and the `klear` command line\nutility to create and manage the choreographies. It was originally developed as\npart of the [Manta Rhei project][1] and is now continued for generic use.  \n\n*(background: The gem is the starting point for refactoring the Manta Rhei\ncode. The repo contains all code for handling the actual content while running\nactuall motors or driving the DMX lights is part of the kinetic-light-engine.)*\n\n[1]: http://www.artcom.de/en/projects/project/detail/manta-rhei/\n\n## The Data\n\nKinetic or Light installations have in common that a number of values are animated over time. For kinetic installation this can be the motor positions, for lights this usually is brightness, or can be RBG color, when 3 values are combined. The klear format uses PNG images to store this data. Each image is a two-dimensional grid, and animation than can be stored as sequence of images. For the images the PNG file format was choosen so that this data can be easily read and written on a variaty of platforms with available software. To store animation data as images also makes it possible to *preview* installation animations on a normal computer screen with a normal image viewer. (please see image format details further down). Which pixel in an image describes which axis or light is left up to the *player* software and not part of the klear format definition.\n\n## The File\n\nA `klear` file simply is a ZIP archive with a different filename extension. An archive format was choosen in order to keep related information being stored together in a single file. ZIP as a archiving (and compression) standard was choosen to make klear fileseasily managable on a lot of different platforms without the need for proprietary software. \n\n## Naming Convention\n\nFiles of this format should have the file extension `.kle` or `.klear`, e.g.\n\"simple-wave.klear\".\n\n## Layout and container Structure\n\nA .kle File contains multiple assets, incl. source PNGs, metatdata and a\nderived binary file containing frames in packed binary form. The Container\nFormat is ZIP so a .kle file is just a zip-file containing files and folders.\n\n**Directory Layout**\n\n+ *DIR* 'META-INF' (mandatory)\n    + 'kle.yml', YAML file containing meta-data describing aspects like\n      framerate \u0026 more\n    + 'MANIFEST.MF' containing meta-data about the klear file itself (e.g.\n      format version)\n+ *DIR* 'frames' (mandatory)\n    + Source PNGs files which were used to generate the kle\n+ *DIR* cache' (optional)\n    + 'frames.bin', binary file containing data derived from the PNGs during\n      creation\n    + further pre-processed data or application state for optimized restarts\n      might be stored here.\n+ *DIR* 'icon'\n    + 'normal.png', PNG file for a normal sized icon (150 x 110 px)\n\n## Workflow\n\nThe initial source of a klear file is a sequence of PNGs + metadata. Those are\nused to generate a .klear file, including the 'frames.bin'. The metadata is\nstored in 'META-INF/kle.yml'.\n\nIf a klear-file does not have a frames.bin in its cache directory it can be\nregenerated. This is also useful for future format changes together with the\nmanifest to detect if a frames.bin is deprecated and needs to be regenerated.\n\nThe source sequence of PNGs is stored in the klear-file as well. Having the source\nPNGs included with the archives allows for resampling of `frames.bin` and other\nmanipulations later on.\n\n## Mapping data to PNGs\n\nEach single PNG represents exactly one frame and is stored with 16-bit Gray per \nchannel. For visual convenience we can define the pixel scale, which means we can control how many pixels are actually stored per value. Otherwise a 100 (10 by 10) axis system would only be 10 by 10 pixel in size. By setting the pixel scale to 20, such images would be upscaled to 300 by 300 pixel which can be handliy reviewed on screen. Pixel scale absolutly now effect on the animation data itself (when using standard tools to scale or zoom imagage data care must be taken to avoid unwanted pixel value interpolation).\n\n**Example**\n\nFor the manta rhei installation we had 14 blades with 10 lights and one motor per blade. The natural mapping was to put this into 14 x 11 (=10 + 1) images where a column represents the state of a blade at a frame (a certain point in time). The number of columns represents the number of blades. By convention we use row 0 for the motor position on a blade and row 1 to 11 for the 10 lights on a blade. For better visual check the pixel scale is 10 x 10, making this a 140x110 pixel image per frame.\n\n![Waves_00129.png](spec/fixtures/kle_generate/Waves/Waves_00129.png)\n\n* We have 11 rows and 14 columns (blades)\n* bottom row describes the motor state\n* Upper rows describe the state of the lights from one direction to the other\n* The PNG is 140px by 110px in size.\n\n## PNG Sequence Order \n\nThe order of the sequence is determined by the **intuitiv** numerial order of the file names. This is done by extracting digits from the filenames and than sort them numerial. This is different than the directory listing order in some cases where the frame number is embedded in the filename or is not padded with a leading zero. When no frame numbe is present in the filenames the sorting is in normal alphabetical order.\n\n*Examples*\n\n* `A.png, B.png, X.png` is valid sequence of 3 PNGs\n* `Test_0001.png, Test_0002.png, Test_1000.png` is a valid sequence\n\nA sequence does not need to be consecutive (it can have gaps e.g.\n`01.png,10.png` is valid and the existence of e.g. 05.png is not enforced).\n\n*Sequence Order:* \n\n      ls -1 (shell order) | intuitive Animation Order\n    ----------------------+-------------------------------------\n      frame_1.png         | frame_1.png      \n      frame_10.png        | frame_2.png     \n      frame_100.png       | frame_10.png    \n      frame_12.png        | frame_12.png     \n      frame_2.png         | frame_100.png      \n\nThe number of columns and rows must be the same for all PNGs.\n\n## kle.yml\n\nContains information fields about how to use the frames:\n\n * Number of columns and rows (geometry)\n * Frames per second\n * recommended gamma value\n * pixel scale for the input PNGs\n * descriptor (optional)\n\nThe geometry is determined automatically by reading the first png in the png\nsequence and dividing width and height by 10 respectively. This relies on one\ntile in the png being 10x10px in size.\n\n*Example:*\n\u003cpre\u003e\n---\n description: calm_02\n geometry:\n   rows: 11\n   columns: 14\n fps: 25\n\u003c/pre\u003e\n\n## Klear file version 1.1 format update\n\n*Kle-Version: 1.1*\n\u003cpre\u003e\n pixel_scale:\n - 30\n - 30\n\u003c/pre\u003e\n\nIn version 1.1 the pixel_scale attribute is added which was fixed to 10px pixel before. The pixel scale defines the amout of pixels per axis, default value is 10px. This means a 10x10 pixel square in the input PNG stands for one axis. For easier visibility now pixel scale can be manually overwridden. For installations with few axises, for example 10 by 2, it might be reasonable to define pixel scale as 30. This would result in a PNG size of  300 by 60 pixel, which is much easier to review on the computer screen than a 10 by 2 pixel image.  \n\n\n## MANIFEST.MF\n\nThe manifest contains meta information about the file and file format itself:\n\n * `Manifest-Version` Version of the manifest itself\n * `Kle-Version` Version of the kle-file format (e.g. `1.0`)\n * `Created-By` Tool which created this file.\n\n*Example:*\n\n\u003cpre\u003e\nManifest-Version: 1.0\n\nKle-Version: 1.1\nCreated-By: bin/klear (0.1.5)\n\u003c/pre\u003e\n\n## frames.bin\n\nThe frames.bin binary file contains the extracted 16-bit values sampled from\neach tile of the PNGs. It contains all frames and each frame contains all\ncolumns and rows.\n\nEach 16-bit value is saved as unsigned 16 bit integer big endian (network byte\norder) and uses 2 bytes in frames.bin.\n\nA PNG with 11 rows and 14 columns uses `14 x 11 x 2 bytes = 308 bytes`.\n\nEach frame is encoded rows bottom to top and the columns from left to right.\n\nExample of a PNG with 3 rows \u0026 cols:\n\n      col 1   col 2   col 3\n    |-------|-------|-------|\n    | 27009 | 38885 | 47331 | \u003c- row 3\n    |-------|-------|-------|\n    | 51027 | 51233 | 49789 | \u003c- row 2\n    |-------|-------|-------|\n    | 47645 | 45039 | 41857 | \u003c- row 1\n    |-------|-------|-------|\n\nis written as a sequence of values like:\n\n    47645 45039 41857    51027 51233 49789    27009 38885 47331\n\n\nwhich results in a binary big endian (network) byte order sequence like:\n\n    0xBA1D 0xAFEF 0xA381    0xC753 0xC821 0xC27D    0x6981 0x97E5 0xB8E3\n\n## Command Line Usage\n\nFor ruby users this gem contains the klear command line utility to manage klear\nfiles. \n\n** Installation **\n\n    $ gem install klear\n\n**File info**\n\n    $ klear info choreo.kle\n\ndumps archive content info to stdout.\n \n**New File Generation**\n\n*Notice: file generation depends on jruby because of its usage of Java JAI*\n\nKlear files are zipped directory structures which are generated from a set of\nimages. The pixel values directly map to motor position and light intensity.\nOn top of that, the klear file contains some additional meta info and cache\ndate to speed up its loading at runtime. Generating a klear file from a images\nsequence in a directory goes like:\n\n    $ rvm jruby exec ./bin/klear.rb generate image_sequence_dir outfile.kle\n    \nand of course, more documentation needs to come.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartcom%2Fklear","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartcom%2Fklear","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartcom%2Fklear/lists"}