{"id":13806634,"url":"https://github.com/phenopolis/pluto","last_synced_at":"2025-10-06T02:40:57.591Z","repository":{"id":115680202,"uuid":"531057530","full_name":"phenopolis/pluto","owner":"phenopolis","description":"A fast and convenient image processing library","archived":false,"fork":false,"pushed_at":"2025-01-31T14:26:03.000Z","size":2388,"stargazers_count":68,"open_issues_count":9,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-20T02:06:44.717Z","etag":null,"topics":["crystal","crystal-lang","image-processing","jpeg","lossless","lossy","png","ppm","webp"],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phenopolis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-31T11:40:36.000Z","updated_at":"2025-01-31T14:26:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"a16cb5a2-d401-4d4f-a72c-6a2dc168fb58","html_url":"https://github.com/phenopolis/pluto","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/phenopolis/pluto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenopolis%2Fpluto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenopolis%2Fpluto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenopolis%2Fpluto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenopolis%2Fpluto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phenopolis","download_url":"https://codeload.github.com/phenopolis/pluto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenopolis%2Fpluto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278551493,"owners_count":26005386,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["crystal","crystal-lang","image-processing","jpeg","lossless","lossy","png","ppm","webp"],"created_at":"2024-08-04T01:01:14.112Z","updated_at":"2025-10-06T02:40:57.560Z","avatar_url":"https://github.com/phenopolis.png","language":"Crystal","funding_links":[],"categories":["Image processing"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource\n      media=\"(prefers-color-scheme: dark)\"\n      srcset=\"https://media.githubusercontent.com/media/phenopolis/pluto/media/logo-white.png\"\n    /\u003e\n    \u003cimg\n      alt=\"logo\"\n      src=\"https://media.githubusercontent.com/media/phenopolis/pluto/media/logo-black.png\"\n      width=\"720px\"\n    /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eA fast and convenient image processing library\u003c/p\u003e\n\n## Documentation\n\n- [Main](https://crystaldoc.info/github/phenopolis/pluto/main/index.html)\n- [Stable](https://crystaldoc.info/github/phenopolis/pluto/v1.0.1/index.html)\n\n## Currently supported\n\n- Image formats\n  - JPEG (through [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo))\n  - PNG (through [libspng](https://libspng.org/))\n  - PPM\n  - [StumpyCore](https://github.com/stumpycr/stumpy_core)\n  - WebP (through [libwebp](https://developers.google.com/speed/webp))\n    - WebP 1.3+ linking flags are used by default. If you have an older version installed, compile with the `-Dlegacy_webp` flag to skip the requirement for `libsharpyuv`.\n- Image operations\n  - Bilinear resize\n  - Box blur\n  - Brightness\n  - Channel swap\n  - Contrast\n  - Crop\n  - Gaussian blur\n  - Horizontal blur\n  - Lanczos resize\n  - Padding\n  - Rotation\n  - Vertical blur\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n   ```yaml\n   dependencies:\n     pluto:\n       github: phenopolis/pluto\n   ```\n\n2. Run `shards install`.\n\n## Usage\n\n### Basic\n\n```crystal\nrequire \"pluto\"\n\n# Formats requiring linkinkg a C library must be explicitly `require`d\nrequire \"pluto/format/jpeg\"\nrequire \"pluto/format/png\"\nrequire \"pluto/format/webp\"\n\nimage = File.open(\"lib/pluto_samples/desert.png\") do |file|\n  Pluto::ImageRGBA.from_png(file)\nend\n\nimage.contrast(-100)  # Creates a new object\nimage.contrast!(-100) # Modifies the existing object\n\nio = IO::Memory.new\nimage.to_jpeg(io)\nio.rewind\nFile.write(\"output.jpeg\", io)\n```\n\n### StumpyCore\n\nPluto can convert to and from [StumpyCore](https://github.com/stumpycr/stumpy_core) `Canvas` objects, so any format that Stumpy supports can be usable with Pluto as well.\n\n```crystal\nrequire \"pluto\"\nrequire \"stumpy_png\"\n\ncanvas = StumpyPNG.read(\"lib/pluto_samples/desert.png\") # =\u003e StumpyCore::Canvas\nimage = Pluto::ImageRGBA.from_stumpy(canvas)            # =\u003e Pluto::ImageRGBA\nimage.to_stumpy                                         # =\u003e StumpyCore::Canvas\n```\n\n\u003e [!note]\n\u003e Converting from a `StumpyCore::Canvas` created from a 16-bit image will result in a loss of information, since Pluto currently only supports 8 bit.\n\n### More\n\nSee the API or the [`spec/`](https://github.com/phenopolis/pluto/tree/main/spec) folder for more examples.\n\n## Benchmarks\n\nSee [`BENCHMARKS.md`](https://github.com/phenopolis/pluto/blob/main/BENCHMARKS.md).\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/phenopolis/pluto/fork\u003e).\n2. Create your feature branch (`git checkout -b my-new-feature`).\n3. Commit your changes (`git commit -am 'Add some feature'`).\n4. Push to the branch (`git push origin my-new-feature`).\n5. Create a new Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenopolis%2Fpluto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphenopolis%2Fpluto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenopolis%2Fpluto/lists"}