in reply to Hex color degrader

It struck me that the way you have implemented your degrade, if one of the rgb value is less than the value by which you are degrading $rgbarray[$rgblowcount] >= $degrade;, it is left untouched. This seems wrong to me.

Say you had the rgb value
#ff7fff
a bright purplish pink and you degrade it by 128 (0x80) then using your algorithm it becomes
#7f7f7f
a mid-grey.

Wouldn't it be better to degrade all of the triplet evenly until they reach zero thereby maintaining the relative proportions of the three colours as long as possible?

Using my example above,
#ff7fff
degraded by 128 becomes
#7f007f
a darker purple colour.

To that end, I offer...

#! perl -sw use strict; sub min{ $_[0]<$_[1] ? $_[0] : $_[1] } sub degrade{ my ($rgb, $degr) = (hex(shift), pop); $rgb -= min( $rgb&(0xff<<$_), $degr<<$_ ) for (0,8,16); sprintf '%06x', $rgb; } my $rgb = "FF9944"; printf 'Degrading %6s by %3d gives %6s%s', $rgb, $_, degrade( $rgb, $_ +), $/ for (0x01, 0x0f, 0x10, 0x44, 0x80, 0xcc, 0xee, 0xf0); __END__ C:\test>204824
Degrading FF9944 by    1 gives fe9843
Degrading FF9944 by   15 gives f08a35
Degrading FF9944 by   16 gives ef8934
Degrading FF9944 by   68 gives bb5500
Degrading FF9944 by 128 gives 7f1900
Degrading FF9944 by 204 gives 330000
Degrading FF9944 by 238 gives 110000
Degrading FF9944 by 240 gives 0f0000

Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!