1

Since boost::gil does not support gray8_view_t writing for the BMP format, I want to convert gray8_view_t to rgb8_view_t. Here is what I've tried so far.

auto rgb_view = boost::gil::planar_rgb_view(width, height, pixels, pixels, pixels, width);

pixels contains the raw pixels from the gray8_view_t object, so I let r=g=b=pixels. But boost::gil::write_view(ofstream, rgb_view, boost::gil::bmp_tag()) gives me an empty image. Any idea?

Update: By using sehe's example code http://coliru.stacked-crooked.com/a/daa0735f774b727f, I was able to get the color conversation to compile with color_converted_view<gil::rgb8_view_t>. But it does not compile when I use boost::gil::write_view to create an image file from the return value of color_converted_view<gil::rgb8_view_t>. My guess is I will have to create an actual rgb8_image_t object from the return value. How can I convert the return value of color_converted_view<gil::rgb8_view_t> to an actual rgb8_image_t object? Thank you!

#include <boost/gil.hpp>
#include <fstream>
namespace gil = boost::gil;

int main()
{
        std::ifstream in("gray8_image_t_sample.jpg", std::ios::binary);
        gil::gray8_image_t img;
        gil::read_image(in, img, gil::jpeg_tag());
        gil::gray8_view_t gv = gil::view(img);
        std::ofstream ofs1("test_image.png", std::ios::out | std::ios_base::binary);
        gil::write_view(ofs1, gv, gil::png_tag()); // This works

        auto rgbv = gil::color_converted_view<gil::rgb8_view_t>(gv);
        std::ofstream ofs2("test_image.bmp", std::ios::out | std::ios_base::binary);
        gil::write_view(ofs2, rgbv, gil::bmp_tag()); // this does not compile
} 

One of the error messages I'm getting

\boost\gil\color_base_algorithm.hpp(170,76): error G1A4676F8: no member named 'layout_t' in 'boost::gil::image<boost::gil::pixel<unsigned char, boost::gil::layout<boost::mp11::mp_list<boost::gil::red_t, boost::gil::green_t, boost::gil::blue_t>, boost::mp11::mp_list<std::integral_constant<int, 0>, std::integral_constant<int, 1>, std::integral_constant<int, 2>>>>, false, std::allocator<unsigned char>>' [clang-diagnostic-error]

Here is the gray8_image_t file I'm using

BunRieuCua
  • 53
  • 4
  • What have you tried? What's wrong with http://coliru.stacked-crooked.com/a/daa0735f774b727f? – sehe Nov 20 '21 at 16:43
  • Actually, I use `gil::any_image_view image_view;` to store the image data. I have tried `auto rgbv = gil::color_converted_view(image_view);`. But gil::color_converted_view does not compile when the argument has an any_image_view type. How can I convert any_image_view to gray8_view_t? I've tried boost::get(image_view) but it does not work – BunRieuCua Nov 21 '21 at 17:42
  • Here is the error I'm getting `boost\gil\extension\dynamic_image\image_view_factory.hpp(160,28): error GB4E3CEB1: excess elements in struct initializer [clang-diagnostic-error] return result_type{color_converted_view(src, _cc)};` – BunRieuCua Nov 21 '21 at 17:52
  • Using any_image_view is adding complexity that you probably don't need. This page details how to use it with GIL algorithms: [To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling `apply_operation(runtime_view, algorithm_fn)`;](http://boostorg.github.io/gil/doc/html/reference/classboost_1_1gil_1_1any__image__view.html#:~:text=To%20perform%20an%20algorithm%20on%20any_image_view%2C%20put%20the%20algorithm%20in%20a%20function%20object%20and%20invoke%20it%20by%20calling%20apply_operation(runtime_view%2C%20algorithm_fn)) – sehe Nov 21 '21 at 20:48
  • From your example code, `gil::rgb8_image_t rgbi(rgbv.width(), rgbv.height());` does not create a rgb8 image with the raw pixel data. How can I actually create a rgb8_image_t object that has the raw pixmap from the return value of `color_converted_view(gv)`? Thanks for your help! I'm very new to C++ and Boost::gil – BunRieuCua Nov 22 '21 at 02:04
  • Oh yeah that last line was just a left-over. Are you saying you got the color conversion to work then? Perhaps it is time to update your question with the actual code and precisely what you are stuck on. – sehe Nov 22 '21 at 02:51
  • Because of the complexity of `any_image_view`, I decided to use rgb8_view_t as the only image view type to store image data and use `color_converted_view` whenever I need to convert gray8_view_t to rgb8_view_t. I've updated my question. Thanks for your quick response. – BunRieuCua Nov 22 '21 at 13:16

1 Answers1

1

Okay the remaining problem was merely a misspecified template argument, color_converted_view expects a destination pixel type:

#include <boost/gil.hpp>
#include <boost/gil/extension/io/bmp.hpp>
#include <boost/gil/extension/io/jpeg.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <fstream>
namespace gil = boost::gil;

int main()
{
    std::ifstream in("gray8_image_t_sample.jpg", std::ios::binary);
    gil::gray8_image_t img;
    gil::read_image(in, img, gil::jpeg_tag());
    gil::gray8_view_t gv = gil::view(img);
    gil::write_view("input.png", gv, gil::png_tag());

    auto rgbv = gil::color_converted_view<gil::rgb8_pixel_t>(gv);
    gil::write_view("output.png", rgbv, gil::png_tag());
    gil::write_view("output.bmp", rgbv, gil::bmp_tag());
}

With the resuling files:

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Cheers. Welcome to stackoverflow. Don't forget to vote and accept (https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – sehe Nov 22 '21 at 23:15