Как использовать библиотеку libpng для преобразования растрового изображения RGBA в PNG и PNG обратно в растровое изображение RGBA

-7

Я пытаюсь использовать библиотеку libpng, и я сталкиваюсь с проблемой с ней.

Теперь я использую CLion и пытаюсь включить эту библиотеку libpng в свой проект. Проблема заключается скорее в настройке этой библиотеки, чтобы использовать ее в моем проекте, чем при использовании этой библиотеки. Я думаю, что я могу скопировать все файлы *.c, *.h из libpng в свой собственный проект в CLion, сделать из него статическую библиотеку liblibpng.a и просто связать с ней. Я даже скомпилировал liblibpng.a, но когда я пытаюсь его использовать, то есть простой, включая $ {path}/libpng-xxx/png.h, в файле png.h есть ошибки и предупреждения, такие как отсутствие определения png_uint_32. Хорошо, я могу ввести это как-то как unsigned int.

Я пытаюсь прочитать README.txt и другие руководства/документы, INSTALL.txt? Но есть много возможностей os, и я просто хочу включить функции png в свой проект. Почему необходимо установить эту библиотеку? Я хочу, чтобы мое приложение после создания в будущем было легко переносимым на другие компьютеры без необходимости установки сторонних библиотек.

Мой вопрос жарко, чтобы легко начать использовать эту библиотеку libpng и, возможно, также zlib в моем собственном проекте в CMake, я предпочитаю статическую библиотеку, я не хочу никакой конкретной установки и т.д.

Я думаю, что у меня есть проблема с этим объявлением, так как это вместо того, чтобы определять png_uint_32 просто выбросить ошибку! Это от pngconf.h

#if UINT_MAX > 4294967294
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294
typedef unsigned long int png_uint_32;
#else
# error "libpng requires an unsigned 32-bit (or more) type"
#endif

спросил(а) 2016-10-02T13:21:00+03:00 3 года, 11 месяцев назад
0
81

Короткий ответ, просто используйте lodepng. Это намного проще использовать, чем libpng, и он поставляется в одном источнике, поэтому вам не нужно путаться со связью и настройкой включенных путей.

Длительный ответ

/*
write an rgba image to a memory buffer in PNG format, without any fanciness.

Params: rgba - the rgba values
width - image width
height - image height
outsize - return for size of output buffer
Returns: pointer to allocated buffer holding png data
*/
void *makePNGBuffer(unsigned char *rgba, int width, int height, size_t *outsize)
{
int code = 0;
// FILE *fp;
png_structp png_ptr = 0;
png_infop info_ptr =0;
png_bytep row = 0;

struct mem_encode state = {0, 0};

*outsize = 0;

// Initialize write structure
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fprintf(stderr, "Could not allocate write struct\n");
code = 1;
goto finalise;
}

// Initialize info structure
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fprintf(stderr, "Could not allocate info struct\n");
code = 1;
goto finalise;
}

// Setup Exception handling
if (setjmp(png_jmpbuf(png_ptr))) {
fprintf(stderr, "Error during png creation\n");
code = 1;
goto finalise;
}

// png_init_io(png_ptr, fp);

/* if my_png_flush() is not needed, change the arg to NULL */
png_set_write_fn(png_ptr, &state, my_png_write_data, my_png_flush);

// Write header (8 bit colour depth)
png_set_IHDR(png_ptr, info_ptr, width, height,
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

// Set title
/*
if (title != NULL) {
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text(png_ptr, info_ptr, &title_text, 1);
}
*/

png_write_info(png_ptr, info_ptr);

// Allocate memory for one row (3 bytes per pixel - RGB)
row = (png_bytep) malloc(4 * width * sizeof(png_byte));

// Write image data
int x, y;
for (y=0 ; y<height ; y++) {
for (x=0 ; x<width ; x++) {
// setRGB(&(row[x*3]), buffer[y*width + x]);
row[x*4] = rgba[(y*width +x)*4];
row[x*4+1] = rgba[(y*width +x)*4+1];
row[x*4+2] = rgba[(y*width +x)*4+2];
row[x*4+3] = rgba[(y*width +x)*4+3];
}
png_write_row(png_ptr, row);
}

// End write
png_write_end(png_ptr, NULL);

finalise:
// if (fp != NULL) fclose(fp);
if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
if (row != NULL) free(row);

*outsize = state.size;
return state.buffer;

}

ответил(а) 2016-10-02T15:00:00+03:00 3 года, 11 месяцев назад
41

Попробуйте сделать эти большие целые числа в pngconf.h без знака, поставив "U" в конце:

if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32;
#else

Возможно, на вашей платформе 4294967294 не может быть представлено как целое число со знаком, поэтому первое сравнение не выполняется из-за неопределенности числа.

ответил(а) 2016-10-05T21:12:00+03:00 3 года, 11 месяцев назад
40

Какая ошибка?

ANSI-C (aka ISO C90) требует, чтобы ULONG_MAX имел значение, большее или равное 4294967295, поэтому, очевидно, сравнение с 4294967294 всегда преуспевает в компиляторе ANSI, и, очевидно, поскольку стандарт использует именно эту десятичную строку, компилятор, который имеет проблема с номером один меньше не является компилятором ANSI-C.

Джон Боулер

ответил(а) 2016-10-05T04:44:00+03:00 3 года, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема