Skip to content

Commit

Permalink
add rgb_to_lab and lab_to_rgb
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Jan 11, 2023
1 parent 7872b06 commit 44a2f68
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
- no need to supply mstar for add_rgb_space
- can supply add_rgb_space-format hash-ref to the relevant functions
- add rgb_to_lab and lab_to_rgb

0.201 2022-02-14
- more accurate dependencies
Expand Down
72 changes: 66 additions & 6 deletions color_space.pd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pp_add_exported(
'rgb_to_xyz', 'xyz_to_rgb',
'xyz_to_lab', 'lab_to_xyz',
'rgb_to_lch', 'lch_to_rgb',
'rgb_to_lab', 'lab_to_rgb',
'add_rgb_space',
);

Expand Down Expand Up @@ -131,11 +132,11 @@ hash-ref in the same format.

=head1 CONVERSIONS

The full list of exported functions include rgb_to_cmyk, cmyk_to_rgb, rgb_to_hsl, hsl_to_rgb, rgb_to_hsv, hsv_to_rgb, rgb_to_xyz, xyz_to_rgb, xyY_to_xyz, xyz_to_lab, lab_to_xyz, lab_to_lch, lch_to_lab, rgb_to_lch, lch_to_rgb, lch_to_lab.
Some conversions, if not already included as functions, can be achieved
by chaining existing functions. For example, LCH to HSV conversion can
be achieved by chaining lch_to_rgb and rgb_to_hsv:

Some conversions, if not already included as functions, can be achieved by chaining existing functions. For example, RGB to Lab conversion can be achieved by chaining rgb_to_xyz and xyz_to_lab.

my $lab = xyz_to_lab( rgb_to_xyz( $rgb, 'sRGB' ), 'sRGB' );
my $hsv = rgb_to_hsv( lch_to_rgb( $lch, 'sRGB' ), 'sRGB' );

To generate a local diagram of what conversions are available between
formats, using GraphViz, you can use this script:
Expand All @@ -149,8 +150,8 @@ formats, using GraphViz, you can use this script:
# then:
perl scriptname >d.dot; dot -Tsvg d.dot >d.svg; display d.svg

(As of 0.202, this is everything to and from C<rgb> except C<lab>,
which is only to and from C<xyz> and C<lch>)
(As of 0.202, this is everything to and from C<rgb>, plus C<xyz> <->
C<lab> <-> C<lch>)

=cut

Expand Down Expand Up @@ -836,6 +837,65 @@ sub PDL::lch_to_rgb {
return xyz_to_rgb( $xyz, $spec );
}


=head2 rgb_to_lab

=for ref

Converts an RGB color triple to an LAB color triple.

The first dimension of the ndarrays holding the rgb values must be size 3, i.e. the dimensions must look like (3, m, n, ...).

=for bad

If C<rgb_to_lab> encounters a bad value in any of the R, G, or B values the output ndarray will be marked as bad and the associated L, A, and B values will all be marked as bad.

=for usage

Usage:

my $lab = rgb_to_lab( $rgb, 'sRGB' );
my $lab = rgb_to_lab( $rgb, \%rgb_spec );

=cut

*rgb_to_lab = \&PDL::rgb_to_lab;
sub PDL::rgb_to_lab {
my ($rgb, $space) = @_;
my $spec = get_space($space);
return xyz_to_lab( rgb_to_xyz( $rgb, $spec ), $spec );
}


=head2 lab_to_rgb

=for ref

Converts an LAB color triple to an RGB color triple.

The first dimension of the ndarrays holding the lab values must be size 3, i.e. the dimensions must look like (3, m, n, ...).

=for bad

If C<lab_to_rgb> encounters a bad value in any of the L, A, or B values the output ndarray will be marked as bad and the associated R, G, and B values will all be marked as bad.

=for usage

Usage:

my $rgb = lab_to_rgb( $lab, 'sRGB' );
my $rgb = lab_to_rgb( $lab, \%rgb_spec );

=cut

*lab_to_rgb = \&PDL::lab_to_rgb;
sub PDL::lab_to_rgb {
my ($lab, $space) = @_;
my $spec = get_space($space);
return xyz_to_rgb( lab_to_xyz( $lab, $spec ), $spec );
}


=head2 add_rgb_space

Supports adding custom RGB space definitions. The C<m> and C<white_point>
Expand Down
23 changes: 23 additions & 0 deletions t/color_space.t
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,29 @@ sub tapprox {
ok( tapprox( $a_rgb, $rgb), 'lch_to_rgb sRGB with bad value' ) or diag($a_rgb, $rgb);
}

# rgb_to_lab
{
my $rgb = pdl([25, 10, 243], [0,0,1]) / 255;
my $lab = pdl([31.5634666908367, 74.943543, -102.31763],
[ 0.0197916632671635, 0.13908209, -0.37848241]);

my $a_lab = rgb_to_lab($rgb, 'sRGB');
ok( tapprox( $a_lab, $lab ), 'rgb_to_lab sRGB' ) or diag($a_lab, $lab);

my $a_rgb = lab_to_rgb($lab, 'sRGB');
ok( tapprox( $a_rgb, $rgb ), 'lab_to_rgb sRGB' ) or diag($a_rgb, $rgb);

my $rgb_bad = $rgb->copy;
$rgb_bad->setbadat(1,1);
$a_lab = $rgb_bad->rgb_to_lab('sRGB');
ok( tapprox( $a_lab, $lab ), 'rgb_to_lab sRGB with bad value' ) or diag($a_lab, $lab);

my $lab_bad = $lab->copy;
$lab_bad->setbadat(1,1);
$a_rgb = $lab_bad->lab_to_rgb('sRGB');
ok( tapprox( $a_rgb, $rgb ), 'lab_to_rgb sRGB with bad value' ) or diag($a_rgb, $rgb);
}

# add_rgb_space
{
my %custom_space = (
Expand Down

0 comments on commit 44a2f68

Please sign in to comment.