Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

G'day All,

I've been playing around with Term::ANSIColor recently. I found the named colours to be very limited. The rgbRGB format provides additional colours but the codes are not particularly intuitive. Then I found rNNNgNNNbNNN; at first, I thought I'd need a different terminal but it turns out that it works just fine on my xterm.

I'm quite familiar with the hex notation #rrggbb, but less so with the decimal equivalents; so I wrote myself a helper program: rgb_palette. I thought I'd share; but there are a few things you'd probably want to know up-front.

  • Obviously, you'll need a true color (aka direct-color) terminal.
  • Change the shebang line if it doesn't fit your setup.
  • Install IO::Prompter.
  • The code, as is, has "use v5.36;". You can downgrade this but, if you do, deal with the subroutine signatures (either turn off experimental warnings or rewrite the two short subroutines, e.g. "sub fg ($r, $g, $b) { ..." --> "sub fg { my ($r, $g, $b) = @_; ..."). Also, add in whatever pragmata you're no longer getting for free.
  • I use a black background. You may need to fiddle with some of the text colours if you use something else.
  • I initially had the hex values on each of the coloured swatches in either black or white. I found this distracting; change the commented code in fg() if you want to put it back that way. As it stands, the foreground and background colours are the same making the text invisible but the swatch colour more prominent. I just double-click on a swatch; middle-click to paste; then "Enter" to get the rNNNgNNNbNNN conversion.
  • I've aimed to get a lot of colours without needing a giant screen. You'll need 100 columns and scrolling will almost certainly be necessary. You can also type in your own hex codes if you want: the output shows a swatch of the input value as well as the rNNNgNNNbNNN code.

Alright, that's enough blathering, here's the code:

#!/usr/bin/env perl use v5.36; use IO::Prompter [ -style => 'bold blue', -echostyle => 'bold magenta', ]; use Term::ANSIColor 5.00; my @nums_under_255 = qw{0 26 51 77 102 127 153 179 204 230 243}; say ''; for my $r (@nums_under_255, 255) { for my $g (@nums_under_255, 255) { print ' '; for my $b (@nums_under_255) { print colored(text("r${r}g${g}b${b}"), join(' on_', fg($r, + $g, $b), "r${r}g${g}b${b}")); } say colored(text("r${r}g${g}b255"), join(' on_', fg($r, $g, 25 +5), "r${r}g${g}b255")); } } say ''; my $rgb; while (1) { $rgb = prompt 'Convert hex to decimal rgb (or just hit "Enter" to +quit): ', -return => ''; # Fix for MSWin -- see https://rt.cpan.org/Public/Bug/Display.html +?id=118255 $rgb =~ s/\R\z//; unless (length $rgb) { say ''; last; } if ($rgb =~ /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/) +{ my $ansi_rgb = sprintf 'r%dg%db%d', map hex, $1, $2, $3; print colored(' --> [', 'bold white'); print colored(' ' x 8, "$ansi_rgb on_$ansi_rgb"); print colored('] --> ', 'bold white'); say colored($ansi_rgb, 'bold cyan'); } else { say colored("\nERROR: '", 'r255g0b0 on_r51g51b51'), colored($rgb, 'r255g255b0 on_r51g51b51'), colored( "' is invalid. Six hexadecimal characters are expected +; such as in the table above.", 'r255g0b0 on_r51g51b51' ); } } sub fg ($r, $g, $b) { #return $r + 2 * $g + $b > 204 ? 'black' : 'white'; return "r${r}g${g}b${b}"; } sub text ($str) { return sprintf ' %02x%02x%02x ', $str =~ /^r(\d+)g(\d+)b(\d+)$/; }

Enjoy!

Updates: Some people encountered problems, so I've made changes.

  • Term::ANSIColor introduced support for 24-bit colour in v5.00 (see Changes). I wasn't aware of this. I've changed "use Term::ANSIColor;" to "use Term::ANSIColor 5.00;". Thanks ++pryrt for reporting this.
  • For MSWin users, there's a bug in IO::Prompter. Again, thanks ++pryrt for reporting this. As a workaround, I've added:
    # Fix for MSWin -- see https://rt.cpan.org/Public/Bug/Display.html +?id=118255 $rgb =~ s/\R\z//;
  • Also for MSWin users, there's been some discussion, in a number of responses, about whether the module Win32::Console::ANSI, or the registry setting VirtualTerminalLevel, is required for this code to work. Not being in a position to test this, I can't comment further.

— Ken


In reply to 'rgb_palette' - Term::ANSIColor Helper by kcott

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2024-04-23 21:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found