Использование библиотеки libjpeg

Использование библиотеки libjpeg

Использование библиотеки libjpeg

Зачастую результатом выполнения CGI приложения является не HTML документ, а картинка. В этой статье рассматривается просто и несложный способ генерации JPEG изображения с помощью библиотеки libjpeg.

Подключим заголовочные файлы. Так как мы пишем на C++ (уж не могу я отказаться от простых удобств этого языка), а libjpeg написана на C, то используем конструкцию extern «C»

#include <stdio.h>
#include <stdlib.h>

extern "C"
{
#include <jpeglib.h>
}

Так как пишем мы CGI приложение, то первое что должна вывести наша программа — Content-Type. Кроме того определим высоту и ширину изображения и выделим для него память. Переменная quality будет задавать качество JPEG изображения (изменяется от 0 до 100).

Изображение будем хранить в формате RGB, то есть каждая точка будет описана тремя байтами: R — уровнем красного (от 0 до 255), G — уровнем зеленого (от 0 до 255) и B — уровнем синего (от 0 до 255). Именно для этого и используется умножение на 3.

void main(void) {
	printf("Content-Type: image/jpeg\n\n");

	int width=400;
	int height=400;
	int quality=75;
	char *scr=(char*)malloc(width*height*3);

Нарисуем что-нибудь незамысловатое.

	for (int i=0;i<width ;i++)
		for (int j=0;j<height;j++) {
			char *p=scr+j*width*3+i*3;
			*p=i+j;p++;
			*p=i-j;p++;
			*p=i*j;
			}

Инициализируем структуры jpeg_compress_struct и jpeg_error_mgr. Зададим выходной файл (stdout), зададим ширину, высоту и качество сжатия.

	/* Compress to JPEG */
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

	jpeg_stdio_dest(&cinfo, stdout);

	cinfo.image_width=width;
	cinfo.image_height=height;
	cinfo.input_components=3;
	cinfo.in_color_space=JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, true);
	jpeg_start_compress(&cinfo, TRUE);

Теперь построчно обработаем изображение с помощью функции jpeg_write_scanlines

    JSAMPROW row_pointer[1];
    int row_stride;
    row_stride = cinfo.image_width*3;

    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0]=(JSAMPLE *)(scr+cinfo.next_scanline*row_stride);
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    	}

И в завершении вызовем оставшиеся действия для обработки изображения (в самом простейшем случае ничего, ровным счетом, не произойдет) и освободим память.

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);

	free(scr);
	}

С помощью следующей строки вы сможете откомпилировать эту программу. Опции -I и -L не обязательный. Под Linux у меня работало и без них, а вот под FreeBSD пришлось указать.

gcc -o jpeg -I/usr/local/include -L/usr/local/lib main.cpp -ljpeg

При выполнении этой программы у вас должно получится следующее изображение:

Использование библиотеки libjpeg

Исходный код: main.cpp

#include <stdio.h>
#include <stdlib.h>

extern "C"
{
#include <jpeglib.h>
}



void main(void) {
	printf("Content-Type: image/jpeg\n\n");

	int width=400;
	int height=400;
	int quality=75;
	char *scr=(char*)malloc(width*height*3);

	for (int i=0;i<width;i++)
		for (int j=0;j<height;j++) {
			char *p=scr+j*width*3+i*3;
			*p=i+j;p++;
			*p=i-j;p++;
			*p=i*j;
			}

	/* Compress to JPEG */
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

	jpeg_stdio_dest(&cinfo, stdout);

	cinfo.image_width=width;
	cinfo.image_height=height;
	cinfo.input_components=3;
	cinfo.in_color_space=JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, true);
	jpeg_start_compress(&cinfo, TRUE);

    JSAMPROW row_pointer[1];
    int row_stride;

    row_stride = cinfo.image_width*3;

    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0]=(JSAMPLE *)(scr+cinfo.next_scanline*row_stride);
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    	}
	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);

	free(scr);
	}

Более подробно про использование библиотеки читайте в файлe src/libjpeg.doc ее дистрибутива.

Скачать библиотеку libjpeg

Комментарии