Function ansi_colours::ansi256_from_rgb
source · Expand description
Returns index of a colour in 256-colour ANSI palette approximating given sRGB colour.
Because the first 16 colours of the palette are not standardised and usually user-configurable, the function usually ignores them.
The first argument uses AsRGB
trait so that the function can be called in
multiple ways using different representations of RGB colours such as
0xRRGGBB
integer, (r, g, b)
tuple or [r, g, b]
array. Calling the
function is equivalent to calling AsRGB::to_ansi256
method.
Examples
assert_eq!( 16, ansi_colours::ansi256_from_rgb(0x000000));
assert_eq!( 16, ansi_colours::ansi256_from_rgb( ( 1, 1, 1)));
assert_eq!( 16, ansi_colours::ansi256_from_rgb( [ 0, 1, 2]));
assert_eq!( 67, ansi_colours::ansi256_from_rgb(&( 95, 135, 175)));
assert_eq!(231, ansi_colours::ansi256_from_rgb(&[255, 255, 255]));
let rgb = rgb::RGB8 { r: 175, g: 0, b: 215 };
assert_eq!(128, ansi_colours::ansi256_from_rgb(rgb));
let bgr = rgb::RGB8 { b: 215, g: 0, r: 175 };
assert_eq!(128, ansi_colours::ansi256_from_rgb(bgr));
let grey = rgb::alt::Gray::<u8>(128);
assert_eq!(244, ansi_colours::ansi256_from_rgb(grey));
Examples found in repository?
src/impls.rs (line 227)
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
fn approx_rgb(r: u8, g: u8, b: u8) -> Self {
Self::Fixed(ansi256_from_rgb((r, g, b)))
}
/// Converts the colour into 256-colour-compatible format.
///
/// If the colour represents an RGB colour, converts it into a `Fixed`
/// variant using [`ansi256_from_rgb`] function. Otherwise, returns the
/// colour unchanged.
///
/// This implementation is present only if `ansi_term` crate feature is
/// enabled.
///
/// # Examples
///
/// ```
/// use ansi_colours::ColourExt;
/// use ansi_term::Colour;
///
/// assert_eq!(Colour::Red, Colour::Red.to_256());
/// assert_eq!(Colour::Fixed( 11), Colour::Fixed(11).to_256());
/// assert_eq!(Colour::Fixed( 16), Colour::RGB( 0, 0, 0).to_256());
/// assert_eq!(Colour::Fixed( 16), Colour::RGB( 0, 1, 2).to_256());
/// assert_eq!(Colour::Fixed( 67), Colour::RGB( 95, 135, 175).to_256());
/// assert_eq!(Colour::Fixed(231), Colour::RGB(255, 255, 255).to_256());
/// ```
#[inline]
fn to_256(&self) -> Self {
if let Self::RGB(r, g, b) = self {
Self::Fixed(ansi256_from_rgb((*r, *g, *b)))
} else {
*self
}
}
/// Converts the colour into sRGB.
///
/// Named colours (`Black`, `Red` etc. through `White`) are treated like
/// `Fixed` colours with indexes 0 through 7. `Fixed` colours are converted
/// into sRGB using [`rgb_from_ansi256`] function. `RGB` colours are
/// returned unchanged.
///
/// This implementation is present only if `ansi_term` crate feature is
/// enabled.
///
/// # Examples
///
/// ```
/// use ansi_colours::ColourExt;
/// use ansi_term::Colour;
///
/// assert_eq!(( 0, 0, 0), Colour::Fixed( 16).to_rgb());
/// assert_eq!(( 95, 135, 175), Colour::Fixed( 67).to_rgb());
/// assert_eq!((255, 255, 255), Colour::Fixed(231).to_rgb());
/// assert_eq!((238, 238, 238), Colour::Fixed(255).to_rgb());
/// assert_eq!(( 42, 24, 0), Colour::RGB(42, 24, 0).to_rgb());
/// ```
#[inline]
fn to_rgb(&self) -> (u8, u8, u8) {
let idx = match self.clone() {
Self::Black => 0,
Self::Red => 1,
Self::Green => 2,
Self::Yellow => 3,
Self::Blue => 4,
Self::Purple => 5,
Self::Cyan => 6,
Self::White => 7,
Self::Fixed(idx) => idx,
Self::RGB(r, g, b) => return (r, g, b),
};
rgb_from_ansi256(idx)
}
}
#[cfg(feature = "termcolor")]
impl AsRGB for termcolor::Color {
/// Returns sRGB colour corresponding to escape code represented by
/// [`termcolor::Color`].
///
/// Behaves slightly differently depending on the variant of the enum.
/// - For named colour variants (`Black`, `Red` etc. up till `White`),
/// returns corresponding system colour with indexes going from 0 to 7.
/// - Similarly, for `Ansi256` variant returns colour corresponding to
/// specified index. See [`rgb_from_ansi256`](`rgb_from_ansi256`).
/// - Lastly, for `Rgb` variant converts it to 24-bit `0xRRGGBB`
/// representation.
///
/// This implementation is present only if `termcolor` crate feature is
/// enabled.
#[inline]
fn as_u32(&self) -> u32 {
match self.clone() {
Self::Black => ansi256::ANSI_COLOURS[0],
Self::Blue => ansi256::ANSI_COLOURS[4],
Self::Green => ansi256::ANSI_COLOURS[2],
Self::Red => ansi256::ANSI_COLOURS[1],
Self::Cyan => ansi256::ANSI_COLOURS[6],
Self::Magenta => ansi256::ANSI_COLOURS[5],
Self::Yellow => ansi256::ANSI_COLOURS[3],
Self::White => ansi256::ANSI_COLOURS[7],
Self::Ansi256(idx) => ansi256::ANSI_COLOURS[idx as usize],
Self::Rgb(r, g, b) => (r, g, b).as_u32(),
_ => unreachable!(),
}
}
/// Returns index of a colour in 256-colour ANSI palette approximating given
/// sRGB colour.
///
/// Behaves slightly differently depending on the variant of the enum.
/// - For named colour variants (`Black`, `Red` etc. up till `White`),
/// returns index going from 0 to 7.
/// - For `Ansi256` variant simply returns index encoded in the variant.
/// - Lastly, for `Rgb` variant, approximates the colour and returns index
/// of closest colour in 256-colour palette.
///
/// This implementation is present only if `termcolor` crate feature is
/// enabled.
///
/// # Examples
///
/// ```
/// use ansi_colours::AsRGB;
///
/// assert_eq!( 0, termcolor::Color::Black.to_ansi256());
/// assert_eq!( 7, termcolor::Color::White.to_ansi256());
/// assert_eq!( 42, termcolor::Color::Ansi256(42).to_ansi256());
/// assert_eq!( 16, termcolor::Color::Rgb( 0, 0, 0).to_ansi256());
/// assert_eq!( 16, termcolor::Color::Rgb( 1, 1, 1).to_ansi256());
/// assert_eq!( 16, termcolor::Color::Rgb( 0, 1, 2).to_ansi256());
/// assert_eq!( 67, termcolor::Color::Rgb( 95, 135, 175).to_ansi256());
/// assert_eq!(231, termcolor::Color::Rgb(255, 255, 255).to_ansi256());
/// ```
#[inline]
fn to_ansi256(&self) -> u8 {
match self.clone() {
Self::Black => 0,
Self::Blue => 4,
Self::Green => 2,
Self::Red => 1,
Self::Cyan => 6,
Self::Magenta => 5,
Self::Yellow => 3,
Self::White => 7,
Self::Ansi256(idx) => idx,
Self::Rgb(r, g, b) => (r, g, b).to_ansi256(),
_ => unreachable!(),
}
}
}
#[cfg(feature = "termcolor")]
impl super::ColourExt for termcolor::Color {
/// Constructs a `Ansi256` colour which approximates given sRGB colour.
///
/// This implementation is present only if `termcolor` crate feature is
/// enabled.
///
/// # Examples
///
/// ```
/// use ansi_colours::ColourExt;
/// use termcolor::Color;
///
/// assert_eq!(Color::Ansi256( 16), Color::approx_rgb( 0, 0, 0));
/// assert_eq!(Color::Ansi256( 16), Color::approx_rgb( 0, 1, 2));
/// assert_eq!(Color::Ansi256( 67), Color::approx_rgb( 95, 135, 175));
/// assert_eq!(Color::Ansi256(231), Color::approx_rgb(255, 255, 255));
/// ```
#[inline]
fn approx_rgb(r: u8, g: u8, b: u8) -> Self {
Self::Ansi256(ansi256_from_rgb((r, g, b)))
}
/// Converts the colour into 256-colour-compatible format.
///
/// If the colour represents an RGB colour, converts it into an `Ansi256`
/// variant using [`ansi256_from_rgb`] function. Otherwise, returns the
/// colour unchanged.
///
/// This implementation is present only if `termcolor` crate feature is
/// enabled.
///
/// # Examples
///
/// ```
/// use ansi_colours::ColourExt;
/// use termcolor::Color;
///
/// assert_eq!(Color::Red, Color::Red.to_256());
/// assert_eq!(Color::Ansi256( 11), Color::Ansi256(11).to_256());
/// assert_eq!(Color::Ansi256( 16), Color::Rgb( 0, 0, 0).to_256());
/// assert_eq!(Color::Ansi256( 16), Color::Rgb( 0, 1, 2).to_256());
/// assert_eq!(Color::Ansi256( 67), Color::Rgb( 95, 135, 175).to_256());
/// assert_eq!(Color::Ansi256(231), Color::Rgb(255, 255, 255).to_256());
/// ```
#[inline]
fn to_256(&self) -> Self {
if let Self::Rgb(r, g, b) = self {
Self::Ansi256(ansi256_from_rgb((*r, *g, *b)))
} else {
*self
}
}