Write jpeg with header comment – boost generic image library (gil)
I had to hack the living daylights out of something today, and although I am not proud of it, needs must where the devil drives!
I was using the boost generic image library (gil) for managing some camera images and using jpeg_write_view() for saving them as JPEGs. A requirement emerged to insert a comment into the header of the saved images, but the gil does not support this out of the box.
The gil uses libjpeg for writing its JPEGs and adding a comment in libjped is as easy as calling jpeg_write_marker(). The problem was that the gil buries libjpeg calls under a few classes so I had to copy and paste some of this in order to redefine a new writer which supports comments.
Anyway I have included the extra code inline below, it adds a new helper function called jpeg_write_view_comment()
Use this new function like this:
int quality = 70; jpeg_write_view_comment("image1.jpg", view, quality, "a comment damn it!!!");
Here is the extra code which I placed in a file called jpeg_writer_comment.h
#pragma once #include "boost/gil/extension/io/dynamic_io.hpp" using namespace boost; using namespace boost::gil; using namespace boost::gil::detail; class jpeg_writer_comment : public file_mgr { jpeg_compress_struct _cinfo; jpeg_error_mgr _jerr; void init() { _cinfo.err=jpeg_std_error(&_jerr); jpeg_create_compress(&_cinfo); jpeg_stdio_dest(&_cinfo,_fp.get()); } public: jpeg_writer_comment(FILE* file) : file_mgr(file) { init(); } jpeg_writer_comment(const char* filename) : file_mgr(filename, "wb") { init(); } ~jpeg_writer_comment() { jpeg_destroy_compress(&_cinfo); } templatevoid apply(const View& view,int quality=100, const char* comment = NULL) { _cinfo.image_width = (JDIMENSION)view.width(); _cinfo.image_height = (JDIMENSION)view.height(); _cinfo.input_components=num_channels ::value; _cinfo.in_color_space = jpeg_write_support_private ::type, typename color_space_type ::type>::color_type; jpeg_set_defaults(&_cinfo); jpeg_set_quality(&_cinfo, quality, TRUE); jpeg_start_compress(&_cinfo, TRUE); if (comment) { jpeg_write_marker(&_cinfo, JPEG_COM, (const JOCTET*)comment, strlen(comment)); } std::vector ::type> > > row(view.width()); JSAMPLE* row_address=(JSAMPLE*)&row.front(); for (int y=0;y void write_view(const any_image_view & runtime_view) { dynamic_io_fnobj op(this); apply_operation(runtime_view,op); } }; template inline void jpeg_write_view_comment(const char* filename,const View& view,int quality=100, const char* comment = NULL) { BOOST_STATIC_ASSERT(jpeg_write_support ::is_supported); jpeg_writer_comment m(filename); m.apply(view, quality, comment); }