我正在尋找一種方法來解碼一些PNG文件,我聽說過libpng,但我不明白這是如何工作的。它是否將png文件轉換爲ARGB8888格式的字節數組或其他內容?如何解碼一個PNG圖像爲原始字節?
3
A
回答
1
Runnable的例子
這種讀取和現有PNG,修改它,並寫入修改後的版本到磁盤。
修改部分在原始字節上完成。
用法:
./a.out [<old-png> [<new-png>]]
old-png
默認爲a.png
new-png
默認爲b.png
測試在Ubuntu 15.10,51年2月1日了libpng,編譯:
gcc main.c -lpng
改編自:https://gist.github.com/niw/5963798
#include <stdlib.h>
#include <stdio.h>
#include <png.h>
unsigned int width;
unsigned int height;
png_bytep *row_pointers;
static void read_png_file(char *filename) {
FILE *fp = fopen(filename, "rb");
png_byte bit_depth;
png_byte color_type;
unsigned int y;
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_read_info(png, info);
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
color_type = png_get_color_type(png, info);
bit_depth = png_get_bit_depth(png, info);
/* Read any color_type into 8bit depth, RGBA format. */
/* See http://www.libpng.org/pub/png/libpng-manual.txt */
if (bit_depth == 16)
png_set_strip_16(png);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
/* PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth. */
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png);
if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
/* These color_type don't have an alpha channel then fill it with 0xff. */
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
}
png_read_image(png, row_pointers);
fclose(fp);
}
static void write_png_file(char *filename) {
unsigned int y;
FILE *fp = fopen(filename, "wb");
if (!fp) abort();
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_set_IHDR(
png,
info,
width,
height,
8,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT
);
png_write_info(png, info);
/* To remove the alpha channel for PNG_COLOR_TYPE_RGB format, */
/* Use png_set_filler(). */
/*png_set_filler(png, 0, PNG_FILLER_AFTER);*/
png_write_image(png, row_pointers);
png_write_end(png, NULL);
for (y = 0; y < height; y++) {
free(row_pointers[y]);
}
free(row_pointers);
fclose(fp);
}
static void process_png(void) {
for (unsigned int y = 0; y < height; y++) {
png_bytep row = row_pointers[y];
for (unsigned int x = 0; x < width; x++) {
png_bytep px = &(row[x * 4]);
/*printf("%4d, %4d = RGBA(%3d, %3d, %3d, %3d)\n", x, y, px[0], px[1], px[2], px[3]);*/
png_byte old[4 * sizeof(png_byte)];
memcpy(old, px, sizeof(old));
px[0] = 255 - old[0];
px[1] = 255 - old[1];
px[2] = 255 - old[2];
}
}
}
int main(int argc, char *argv[]) {
char *in;
char *out;
if (argc > 1) {
in = argv[1];
} else {
in = "a.png";
}
if (argc > 2) {
out = argv[2];
} else {
out = "b.png";
}
read_png_file(in);
process_png();
write_png_file(out);
return EXIT_SUCCESS;
}
2
您可能最好在尋找一個專門的image library,它會爲您解碼圖像並將其返回到可識別的結構中。如果您想要對圖像進行實際操作(保存,顯示等),它也可以作爲一個更好的平臺。
相關問題
- 1. 如何將原始圖像數據保存到PNG圖像?
- 2. 如何使用python將原始圖像轉換爲png
- 3. 如何將原始圖像轉換爲Python中的PNG?
- 4. 如何創建只有一個字節的PNG圖像
- 5. 如何解碼從Assimp到CGImage的原始PNG數據?
- 6. 將tfrecords中的原始字節解碼爲tf.feature_column.numeric_column功能
- 7. 如何從一個字節數組中顯示一個表示一個.png文件的字節的圖像
- 8. 如何使用ReportLab從原始字節中繪製圖像?
- 9. 如何用KineticJS將另一個PNG圖像掩蓋PNG圖像?
- 10. 如何從原始Bayer圖像數據(字節數組)獲取位圖圖像?
- 11. 我將如何將PNG圖像轉換爲字節數組?
- 12. 如何解碼unicode原始文字爲可讀的字符串?
- 13. 我如何查看'原始'PNG圖像數據
- 14. 在Python中將原始圖像轉換爲PNG
- 15. C函數將原始圖像轉換爲png
- 16. 將原始像素數據轉換爲PNG或繪製原始像素數據
- 17. 使用DatatypeConverter解碼字節到原始字符串
- 18. SDL從原始圖像數據字符串中繪製PNG圖像
- 19. 如何從一個base64 PNG圖像
- 20. 如何在解碼原始字節數組後更改特定的字段值?
- 21. 爲什麼調整大小的PNG圖像比原始圖像大得多?
- 22. PNG文件格式和圖像字節?
- 23. 如何在UIImageView中像原始圖像一樣顯示圖像?
- 24. 如何使用GWT將PNG圖像數據作爲解碼字節數組獲取?
- 25. 如何解析圖像字節[]數組
- 26. 解密後的圖像與原始圖像不一樣
- 27. 如何將png圖像字符串數據轉換爲png?
- 28. 使用Magick ++解碼PNG圖像
- 29. Android將圖像解碼爲位圖中的字節數組
- 30. 解碼原始URL
有上的libpng和它的使用相當廣泛的手冊頁。有關在線版本,請參閱:http://www.manpagez.com/man/3/libpng/。 – 2009-09-01 15:20:10