DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Extensions To CImg

01.18.2007
| 4801 views |
  • submit to reddit
        Extensions to CImg, also for interoperability with Fl_Image


#include "CImg.h"
#include <Fl/Fl_Image.H>

using namespace cimg_library;

/* Generates a w*h*3 CImg<unsigned char> image from the given rgba data and background colour. */
CImg<unsigned char> cimg_from_rgba(unsigned char const* rgba,const unsigned int dimw,const unsigned int dimh, 
		const unsigned char back_r, const unsigned char back_g, const unsigned char back_b) {
	CImg<unsigned char> res(dimw,dimh,1,3);
	unsigned char *pR = res.ptr(0,0,0,0), *pG = res.ptr(0,0,0,1), *pB=res.ptr(0,0,0,2);
	const unsigned char *ptrs = rgba;
	for (unsigned int off=res.width*res.height; off>0; --off) {
		*(pR++) = (unsigned char)((ptrs[0] * ptrs[3] + back_r * (255 - ptrs[3])) >> 8);
		*(pG++) = (unsigned char)((ptrs[1] * ptrs[3] + back_g * (255 - ptrs[3])) >> 8);
		*(pB++) = (unsigned char)((ptrs[2] * ptrs[3] + back_b * (255 - ptrs[3])) >> 8);
		ptrs += 4;
	}
	return res;
}

/* Generates a w*h*3 CImg<unsigned char> image from the given rgb data. */
CImg<unsigned char> cimg_from_rgb(unsigned char const* rgb,const unsigned int dimw,const unsigned int dimh) {
	CImg<unsigned char> res(dimw,dimh,1,3);
	unsigned char *pR = res.ptr(0,0,0,0), *pG = res.ptr(0,0,0,1), *pB=res.ptr(0,0,0,2);
	const unsigned char *ptrs = rgb;
	for (unsigned int off=res.width*res.height; off>0; --off) {
		*(pR++) = (unsigned char)*(ptrs++);
		*(pG++) = (unsigned char)*(ptrs++);
		*(pB++) = (unsigned char)*(ptrs++);
	}
	return res;
}

/* Generates a FLTK RGB Image from the given CImg<unsigned char> image. */
Fl_RGB_Image* image_from_cimg(CImg<unsigned char> const & cimg) {
	const unsigned int wh = cimg.dimx() * cimg.dimy();
	unsigned char *buffer = new unsigned char[3*wh], *nbuffer=buffer;
	const unsigned char 
		*ptr1 = cimg.ptr(0,0,0,0),
		*ptr2 = cimg.dim>1?cimg.ptr(0,0,0,1):ptr1,
		*ptr3 = cimg.dim>2?cimg.ptr(0,0,0,2):ptr1;
	for (unsigned int k=0; k<wh; k++) {
		*(nbuffer++) = (unsigned char)(*(ptr1++));
		*(nbuffer++) = (unsigned char)(*(ptr2++));
		*(nbuffer++) = (unsigned char)(*(ptr3++));
	}
	return new Fl_RGB_Image(buffer, cimg.dimx(), cimg.dimy());
}

/* Returns a resized image to a maximum of the given dimensions, keeping its aspect ratio. */
template<typename T> CImg<T> get_resize_keep_aspect_ratio(CImg<T> const & cimg, const unsigned int w, const unsigned int h) {
	if (cimg.dimx() * h > cimg.dimy() * w) { // cimg.dimx() / cimg.dimy() > w / h
		return cimg.get_resize(w, cimg.dimy() * w / cimg.dimx(), -100, -100, 5);
	} else {
		return cimg.get_resize(cimg.dimx() * h / cimg.dimy(), h, -100, -100, 5);
	}
}

/* Returns a resized image to a maximum of the given dimensions, keeping its aspect ratio,
 * only if the dimensions given are smaller than the original dimensions. */
template<typename T> CImg<T> get_resize_if_smaller_keep_aspect_ratio(CImg<T> const & cimg, const unsigned int w, const unsigned int h) {
	if (w < cimg.dimx() || h < cimg.dimy())
		return get_resize_keep_aspect_ratio(cimg, w, h);
	else
		return CImg<T>(cimg);
}