{"id":16115601,"url":"https://github.com/kornelski/rust-rgb","last_synced_at":"2025-05-15T02:05:55.132Z","repository":{"id":9267140,"uuid":"61443634","full_name":"kornelski/rust-rgb","owner":"kornelski","description":"struct RGB for sharing pixels between crates","archived":false,"fork":false,"pushed_at":"2024-12-02T11:51:38.000Z","size":482,"stargazers_count":104,"open_issues_count":7,"forks_count":19,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-05-14T00:24:03.339Z","etag":null,"topics":["pixel-layout","rgb-color","rust","rust-library"],"latest_commit_sha":null,"homepage":"https://lib.rs/rgb","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kornelski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-18T16:54:09.000Z","updated_at":"2025-05-05T13:15:40.000Z","dependencies_parsed_at":"2024-02-10T00:32:23.294Z","dependency_job_id":"1ed5d158-3e61-47eb-80f7-202db6e2d288","html_url":"https://github.com/kornelski/rust-rgb","commit_stats":{"total_commits":243,"total_committers":24,"mean_commits":10.125,"dds":"0.25514403292181065","last_synced_commit":"4a67b556e89a64b3e28d1b9421e5733b4010a24c"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kornelski%2Frust-rgb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kornelski%2Frust-rgb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kornelski%2Frust-rgb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kornelski%2Frust-rgb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kornelski","download_url":"https://codeload.github.com/kornelski/rust-rgb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254259370,"owners_count":22040819,"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":["pixel-layout","rgb-color","rust","rust-library"],"created_at":"2024-10-09T20:19:15.154Z","updated_at":"2025-05-15T02:05:55.116Z","avatar_url":"https://github.com/kornelski.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pixel types for [Rust](https://www.rust-lang.org) [![crate](https://img.shields.io/crates/v/rgb.svg)](https://lib.rs/crates/rgb)\n\nOperating on pixels as weakly-typed vectors of `u8` is error-prone and inconvenient. It's better to use vectors and slices of pixel structs, like `\u0026[Rgb\u003cu8\u003e]`.\n\nHowever, Rust is so strongly typed that _your_ `Rgb` struct is not compatible with _my_ `Rgb` struct. This crate provides common structs to share between crates.\n\n## Features\n\n * It's a shared type [used in many crates](https://lib.rs/crates/rgb/rev), which allows you to seamlessly and reliably share pixel data between them.\n\n * Compiles quickly and has low overhead. The dependencies are only for interoperability with the broader ecosystem, and are all optional.\n\n * Implements standard Rust traits, and has convenience methods for operating on all channels of the pixels. Saves you from having to copy-paste the same lines for `r`, `g`, and `b`.\n\n * It's unopinionated about color management, which lets it prepresent most RGB-related pixels without interfering. If you need more advanced conversions and non-RGB color spaces, use the [`palette` crate](https://lib.rs/crates/palette) instead.\n\n## Basic Usage\n\n```rust\nuse rgb::{Rgb, Rgba, Argb, Bgr, Bgra, Abgr, Grb}; // and more\nuse rgb::prelude::*; // traits with convenience methods\n\nlet rgb_pixel = Rgb { r: 0u8, g: 100, b: 255 };\nlet wider_pixel = rgb_pixel.map(u16::from);\n\nprintln!(\"{rgb_pixel}\"); // prints rgb(0, 100, 255)\nprintln!(\"{rgb_pixel:X}\"); // prints #0064FF\n\nassert_eq!(rgb_pixel.to_color_array(), [0, 100, 255]);\nassert_eq!(rgb_pixel.with_alpha(128), Rgba::new(0, 100, 255, 128));\n```\n\n### Conversions from/to other types\n\nWe defer to the `bytemuck` crate to have safe zero-cost conversions between types. See [`bytemuck::cast_slice()`][bslice] and [`cast_vec()`][bvec].\n\n[bslice]: https://docs.rs/bytemuck/latest/bytemuck/fn.cast_slice.html\n[bvec]: https://docs.rs/bytemuck/latest/bytemuck/allocation/fn.cast_vec.html\n\n```rust,ignore\nlet pixels: Vec\u003cu8\u003e = vec![0u8; 3 * size];\nlet rgb_pixels: Vec\u003cRgb\u003cu8\u003e\u003e = rgb::bytemuck::allocation::cast_vec(pixels);\n\nfor rgb_pixel in \u0026rgb_pixels {\n}\n```\n\nIf you'd like to work with 2D slices of pixels, see [the `imgvec` crate](https://lib.rs/crates/imgvec).\n\n# Stable and testing versions\n\nThe version 0.8 is stable, and we plan to support it for a long time. You can use it, and rely on it.\n\n```toml\n[dependencies]\nrgb = \"0.8.50\"\n```\n\nWe want to release a proper v1.0.0 eventually. We plan to have it backwards-compatible with crates using v0.8, except some deprecated cruft removed/fixed. We hope the migration will be seamless for most users. Please help us test it!\n\n```toml\n# This is required due to how version unification works in Cargo\n[patch.crates-io]\nrgb.git = \"https://github.com/kornelski/rust-rgb\"\n\n[dependencies]\nrgb = \"0.8.90\"\n```\n\n- Are the names of the traits and their methods good?\n- Are there any standard library traits you'd like implemented on the pixel types?\n- Is the split between `Pixel`, `HetPixel`, `HasAlpha` sensible?\n  (pixels support a different type for the alpha channel, and there's `Rgbw` without alpha).\n\n[Please open issues in the repo with the feedback](https://github.com/kornelski/rust-rgb/issues)\nor message [@kornel@mastodon.social](https://mastodon.social/@kornel).\n\n## Usage\n\n```rust\nuse rgb::{Rgb, Rgba, Argb, Bgr, Bgra, Abgr, Grb, Gray_v09 as Gray, GrayA};\n\nlet rgb = Rgb {r: 0, g: 0, b: 0};\nlet rbga = Rgba {r: 0, g: 0, b: 0, a: 0};\nlet argb = Argb {a: 0, r: 0, g: 0, b: 0};\n\nlet bgr = Bgr {b: 0, g: 0, r: 0};\nlet bgra = Bgra {b: 0, g: 0, r: 0, a: 0};\nlet abgr = Abgr {r: 0, g: 0, b: 0, a: 0};\n\nlet grb = Grb {g: 0, b: 0, r: 0};\n\nlet gray = Gray {v: 0};\nlet gray_a = GrayA {v: 0, a: 0};\n```\n\nIf you have a pixel type you would like to use that is not currently\nimplemented, please open an issue to request your pixel type.\n\nThe pixel types with an alpha component such as `Rgba` have two\ngeneric type parameters:\n\n```rust\nstruct Rgba\u003cT, A = T\u003e {\n    r: T,\n    g: T,\n    b: T,\n    a: A,\n}\n```\n\nThis makes them more flexible for more use-cases, for example if you\nneeded more precision for you color components than your alpha\ncomponent you could create an `Rgba\u003cf32, u8\u003e`. However, in most\nuse-cases the alpha component type will be the same as the color\ncomponent type.\n\nA pixel with separate types for the color and alpha\ncomponents is called a heterogeneous pixel (`HetPixel`), whereas a pixel with a\nsingle type for both color and alpha components is called a\nhomogeneous pixel (`Pixel`).\n\n## Pixel Traits\n\nAll functionality for the pixel types is implemented via traits. This\nmeans that none of the pixel types, like `Rgb\u003cu8\u003e`, have any inherent\nmethods. This makes it easy to choose which methods you'd like to be\nin scope at any given time unlike inherent methods which are always\nwithin scope.\n\nThis crate offers the following traits:\n\n### `HetPixel`\n\nThe most foundational pixel trait implemented by every pixel type.\n\n```rust\nuse rgb::{Rgba, HetPixel};\n\nlet mut rgba: Rgba\u003cu8\u003e = Rgba::try_from_colors_alpha([0, 0, 0], 0).unwrap();\n\n*rgba.each_color_mut()[2] = u8::MAX;\nassert_eq!(rgba.to_color_array(), [0, 0, 255]);\n\n*rgba.alpha_opt_mut().unwrap() = 50;\nassert_eq!(rgba.alpha_opt(), Some(50));\n\nlet rgba = rgba.map_colors(u16::from);\nlet rgba = rgba.map_colors_same(|c| c * 2);\nlet rgba = rgba.map_alpha(f32::from);\nlet rgba = rgba.map_alpha_same(|a| a * 2.0);\n\nassert_eq!(rgba, Rgba::\u003cu16, f32\u003e {r: 0, g: 0, b: 510, a: 100.0});\n```\n\n### Pixel\n\nA stricter form of `HetPixel` where the two component types, color and\nalpha, are the same.\n\n```rust\nuse rgb::{Rgba, Pixel};\n\nlet mut rgba: Rgba\u003cu8\u003e = Rgba::try_from_components([0, 0, 0, 0]).unwrap();\n\n*rgba.each_mut()[2] = u8::MAX;\nassert_eq!(rgba.to_array(), [0, 0, 255, 0]);\n\nlet rgba = rgba.map(u16::from);\nlet rgba = rgba.map_same(|c| c * 2);\n\nassert_eq!(rgba, Rgba::\u003cu16\u003e {r: 0, g: 0, b: 510, a: 0});\n```\n\n### `GainAlpha`\n\nA way to add alpha to a pixel type in various ways.\n\n```rust\nuse rgb::{Rgb, Rgba, GainAlpha};\n\nlet expected: Rgba\u003cu8\u003e = Rgba {r: 0, g: 0, b: 0, a: 255};\n\nassert_eq!(Rgb {r: 0, g: 0, b: 0}.with_default_alpha(255), expected);\nassert_eq!(Rgb {r: 0, g: 0, b: 0}.with_alpha(255), expected);\nassert_eq!(Rgba {r: 0, g: 0, b: 0, a: 0}.with_alpha(255), expected);\n```\n\n### `HasAlpha`\n\nA trait only implemented on pixels that have an alpha\ncomponent.\n\nDue to a naming conflict with several now-deprecated inherent\nfunctions with the same name (such as `Rgb::alpha()`) the\n`HasAlpha::alpha()` method requires fully qualified syntax for\ndisambiguation. The deprecated functions are due to be removed in a\nfuture release which will solve this issue.\n\n```rust\nuse rgb::{Rgba, HasAlpha};\n\nlet mut rgba: Rgba\u003cu8\u003e = Rgba {r: 0, g: 0, b: 0, a: 255};\n\n*rgba.alpha_mut() -= 50;\n\nassert_eq!(HasAlpha::alpha(\u0026rgba), 205);\n```\n\n## Crate Features\n\n- `num-traits`: Enables various\n  [`num_traits`](https://docs.rs/num-traits) traits impls for the\n  pixel types such as `CheckedAdd`.\n- `defmt-03` = Enables the `Format` trait impls from\n  [`defmt`](https://docs.rs/defmt) `v0.3` for the pixel types\n- `serde` = Enables `Serializable` and `Deserializable` trait impls\n  from [`serde`](https://docs.rs/serde) for the pixel types\n- `bytemuck` = Enables `Pod` and `Zeroable` trait impls from\n  [`bytemuck`](https://docs.rs/serde) for the pixel types\n\nThe following crate features are only kept for backwards compatibility, and will be removed in the next major version:\n\n```toml\n# These are no longer used\nargb = []\ngrb = []\nchecked_fns = []\nas-bytes = [\"bytemuck\"]\n```\n\n## Color-Space Agnostic\n\nThis crate is purposefully a basic lowest-common-denominator, and it does not dictate what color spaces the pixel types are supposed to use.\nFor example, `Gray\u003cu8\u003e` could be either linear lightness or gamma-corrected luma, however you wish to use it.\n_Correct_ color management is a complex problem, and this crate doesn't want to impose any specific solutions.\n\nIf you need strongly-typed color spaces, you can use newtypes as component types for `Rgb\u003cT\u003e` and `Rgba\u003cT, AlphaType\u003e`, e.g.:\n\n```rust\n# use rgb::Rgb;\nstruct LinearLight(u16);\ntype LinearRGB = Rgb\u003cLinearLight\u003e;\n```\n\n## Roadmap to 1.0\n\nThe plan is to provide easy migration to v1.0. There will be a\ntransitional v0.9 version released that will be mostly\nbackwards-compatible with 0.8, and forwards-compatible with 1.0.\n\nThe changes:\n\n- Types were renamed to follow Rust's naming convention: `RGBA` → `Rgba`.\n  Type aliases with an `8` or `16` suffix (`RGBA8`) were kept as-is.\n- The grayscale types have changed from being tuple structs with\n  `.0`/`.1` to structs with named fields `.v` (value) and `.a` (alpha).\n- `GrayAlpha` has been renamed to `GrayA`.\n- `bytemuck::Pod` (conversions from/to raw bytes) require color and alpha components to be the same type\n  (i.e. it works with `Rgba\u003cu8\u003e`, but not `Rgba\u003cNewtype, DifferentType\u003e`).\n- Most inherent methods were moved to a new `Pixel` trait.\n\n### Migrating away from deprecated items\n\nSome items in this crate have become deprecated in preparation for a\nfuture release which removes them. Here is a checklist of things you may need to do.\n\n1. Update to the latest version of 0.8, and fix all deprecation warnings.\n   - rename `.alpha()` to `.with_alpha()`\n   - rename `.map_c()` to `.map_colors()`\n1. Change field access on `GrayAlpha` from `.0` and `.1` to `.v` and `.a` where possible.\n1. Use the `bytemuck` crate for conversions from/to bytes instead of `ComponentBytes` trait. Disable the `as-bytes` feature if possible.\n1. Use the `num-traits` crate for `.checked_add()`, don't enable `checked_fns` feature.\n1. Don't enable `gbr` and `argb` features. All pixel types are enabled by default.\n1. `AsRef\u003c[T]\u003e` implementations have changed to `AsRef\u003c[T; N]\u003e`. In most cases `.as_ref()`/`.as_mut()` calls should coerce to a slice anyway.\n1. Instead of `pixel.as_slice()` use `pixel.as_ref()`.\n1. Stop using the `rgb::Gray`/`rgb::GrayAlpha` types and switch to `rgb::Gray_v09 as Gray`/`rgb::GrayA` instead respectively.\n1. In generic code operating on pixels, add `Copy + 'static` bounds to the pixel types and their components.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkornelski%2Frust-rgb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkornelski%2Frust-rgb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkornelski%2Frust-rgb/lists"}