gil boost : convert rgb8_image_t to rgba8_image_t

2.5k views Asked by At

I'm a little bit confusing about GIL syntax. I want to convert

rgb8_image_t

to

rgba8_image_t

and set alpha channel to 1. Is there any built-in function. If not how to do this manually?

1

There are 1 answers

0
timday On

You want to use boost::gil::copy_and_convert_pixels with a suitable matching color_convert specialisation in scope.

Here's a complete example:

#include <boost/gil/gil_all.hpp>
#include <cassert>

namespace boost { namespace gil {

    // Define a color conversion rule NB in the boost::gil namespace
    template <> void color_convert<rgb8_pixel_t,rgba8_pixel_t>(
      const rgb8_pixel_t& src,
      rgba8_pixel_t& dst
    ) {

      // Well we _could_ just write...

      // dst[0]=src[0];
      // dst[1]=src[1];
      // dst[2]=src[2];
      // dst[3]=255;

      // ...but that'd be too easy / not as generic as it could be
      // so let's go crazy...
      get_color(dst,red_t())=get_color(src,red_t());
      get_color(dst,green_t())=get_color(src,green_t());
      get_color(dst,blue_t())=get_color(src,blue_t());

      typedef color_element_type<rgba8_pixel_t,alpha_t>::type alpha_channel_t;
      get_color(dst,alpha_t())=channel_traits<alpha_channel_t>::max_value(); 
    }
  }
}

int main(int,char**) {

  // Create a 1x1 RGB image and set its pixel to a color
  boost::gil::rgb8_image_t a(1,1);
  boost::gil::view(a)(0,0)=boost::gil::rgb8_pixel_t(1,2,3);

  // Create a 1x1 RGBA
  boost::gil::rgba8_image_t b(1,1);

  // Copy AND CONVERT
  boost::gil::copy_and_convert_pixels(
    boost::gil::const_view(a),
    boost::gil::view(b)
  );

  // Check the alpha has been set as expected
  const boost::gil::rgba8_pixel_t p=boost::gil::const_view(b)(0,0);
  assert(p==boost::gil::rgba8_pixel_t(1,2,3,255));

  return 0;
}

Alternatively there are copy_and_convert_pixels overloads (see the docs) which accept an explicit color conversion functor, but for something as uncontroversial as making RGB images have an implicit max alpha on conversion there seems to be little reason not to define it where it will be picked up by default.