libpng处理png图片(一)
一:libpng库的编译
环境:windows10 + VS2013
需要下载:libpng, zlib两个库
下载地址:
libpng:http://libmng.com/pub/png/libpng.html
zlib:http://www.zlib.net/
注意事项:
libpng, zlib解压后放到同一目录,
打开ibpng目录下的projects\vstudio中的工程文件,编译运行
在输出目录(Debug或Realse)中得到输出文件libpng16.dll、libpng16.lib、zlib.lib
问题:
libpng, zlib版本问题导致编译时提示找不到zlib,修改配置文件中zlib信息即可
二,VS2013使用libpng,zlib库:
1. C/C++常规->附加包含目录中把包含png.h等头文件的目录加进来
2. 链接器->输入->附加依赖项中加zlib.lib;libpng.lib。
3.通用属性->VC++ 目录->库目录中把放着zlib.lib和libpng.lib的目录加进来。
三,png图片格式:
参数较多,其中重要信息:IHDR(文件头),IDAT(图像数据块),IEND(图像结束数据)
文件头里最重要的数据信息:
Width:图像宽度,以像素为单位
Height:图像高度,以像素为单位
ColorType:RGB格式或RGBA格式
图像数据块:
图片对应的像素点有多个参数,RGB或RGBA,
对某个像素操作需要有3个(RGB)或4个(RGBA)数据
详细png格式说明:
http://www.360doc.com/content/11/0428/12/1016783_112894280.shtml
四,VS下利用libpng的简单读写操作(代码稍加改动可执行):
写png图片:write_png.c
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <png.h> // This function actually writes out the PNG image file. The string 'title' is
// also written into the image file
int writeImage(char* filename, int width, int height, char* title); /*
fun: 根据宽,高,标题将每个像素的RGB值在指定路径生成png文件
return: int型,0表示正确,1表示出错
arg[0]: filename,生成的文件名字
arg[1]: width,图片宽
arg[2]: height,图片高
arg[3]: title,标题
*/
int writeImage(char* filename, int width, int height, char* title)
{
int code = ;
FILE *fp = NULL;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_bytep row = NULL; // Open file for writing (binary mode)
fp = fopen(filename, "wb");
if (fp == NULL) {
fprintf(stderr, "Could not open file %s for writing\n", filename);
code = ;
goto finalise;
} // 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 = ;
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 = ;
goto finalise;
} // Setup Exception handling
if (setjmp(png_jmpbuf(png_ptr))) {
fprintf(stderr, "Error during png creation\n");
code = ;
goto finalise;
} png_init_io(png_ptr, fp); // Write header (8 bit colour depth)
png_set_IHDR(png_ptr, info_ptr, width, height,
, PNG_COLOR_TYPE_RGB, 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, );
} png_write_info(png_ptr, info_ptr); // Allocate memory for one row (3 bytes per pixel - RGB)
row = (png_bytep)malloc( * width * sizeof(png_byte)); // Write image data
int x, y; for (y = ; y<height; y++) {
for (x = ; x<width; x++) {
if (x == || x == (width - ) || y == || y == (height - ))
{
row[x * + ] = 0x00;
row[x * + ] = 0x00;
row[x * + ] = 0x00;
}
else
{
row[x * + ] = 0x00;
row[x * + ] = 0x00;
row[x * + ] = 0xff;
}
}
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, -);
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
if (row != NULL) free(row); return code;
} int main(int argc, char *argv[])
{
// Make sure that the output filename argument has been provided
if (argc != ) {
fprintf(stderr, "Please specify output file\n");
return ;
} // Specify an output image size
int width = ;
int height = ; // Save the image to a PNG file
// The 'title' string is stored as part of the PNG file
printf("Saving PNG\n");
int result = writeImage(argv[], width, height, "This is my test image");
if (result)
{
printf("Saving err\n");
} //// Free up the memorty used to store the image
//free(buffer); return result;
}
生成的一张简单png图片,50*50边缘1像素黑框,中间蓝色:

读png图片:read_png.cpp
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>
#include <stdlib.h>
#include <string> #include <png.h>
#define PNG_BYTES_TO_CHECK 4 /*
fun: 读取文件名为filepath的png文件
return: png_bytep类型的buff,即数据域
arg[0]: filepath,文件名
arg[1]: width,图像宽度
arg[2]: height,图像高度
*/
png_bytep load_png_image(const char *filepath, int *width, int *height)
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_bytep* row_pointers;
char buf[PNG_BYTES_TO_CHECK];
int w, h, x, y, temp, color_type; fp = fopen(filepath, "rb");
if (fp == NULL) {
printf("load_png_image err:fp == NULL");
return ;
} png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, , , );
info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr));
/* 读取PNG_BYTES_TO_CHECK个字节的数据 */
temp = fread(buf, , PNG_BYTES_TO_CHECK, fp);
/* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */
if (temp < PNG_BYTES_TO_CHECK) {
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, );
printf("load_png_image err:读到的数据并没有PNG_BYTES_TO_CHECK个字节");
return ;
}
/* 检测数据是否为PNG的签名 */
temp = png_sig_cmp((png_bytep)buf, (png_size_t), PNG_BYTES_TO_CHECK);
/* 如果不是PNG的签名,则说明该文件不是PNG文件 */
if (temp != ) {
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, );
printf("load_png_image err:不是PNG的签名");
return ;
} /* 复位文件指针 */
rewind(fp);
/* 开始读文件 */
png_init_io(png_ptr, fp);
/* 读取PNG图片信息和像素数据 */
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, );
/* 获取图像的色彩类型 */
color_type = png_get_color_type(png_ptr, info_ptr); /* 获取图像的宽高 */
w = png_get_image_width(png_ptr, info_ptr);
h = png_get_image_height(png_ptr, info_ptr);
*width = w;
*height = h; /* 分配空间buff,保存像素数据 */
png_bytep buff = (png_bytep)malloc(h * w * * sizeof(png_byte));
memset(buff, , (h * w * * sizeof(png_byte))); /* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */
row_pointers = png_get_rows(png_ptr, info_ptr); /* 根据不同的色彩类型进行相应处理 */
switch (color_type) {
case PNG_COLOR_TYPE_RGB_ALPHA:
for (y = ; y<h; ++y)
{
for (x = ; x<w * ;)
{
///* 以下是RGBA数据,需要自己补充代码,保存RGBA数据 */
///* 目标内存 */ = row_pointers[y][x++]; // red
///* 目标内存 */ = row_pointers[y][x++]; // green
///* 目标内存 */ = row_pointers[y][x++]; // blue
///* 目标内存 */ = row_pointers[y][x++]; // alpha
printf("处理RGBA\n");
}
} break; case PNG_COLOR_TYPE_RGB:
for (y = ; y<h; y++)
{
for (x = ; x<w; x++)
{
buff[y*w + * x + ] = row_pointers[y][ * x + ];
buff[y*w + * x + ] = row_pointers[y][ * x + ];
buff[y*w + * x + ] = row_pointers[y][ * x + ];
printf("%x,%x,%x ", buff[y*w + * x + ], buff[y*w + * x + ], buff[y*w + * x + ]);
//printf("%x,%x,%x ", buff[y*w + 3 * x + 0], buff[y*w + 3 * x + 1], buff[y*w + 3 * x + 2]);
/*printf("处理RGB\n");*/
}
printf("\n");
}
printf("\n");
break;
/* 其它色彩类型的图像就不读了 */
default:
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, );
printf("default color_type:close\n");
return ;
}
png_destroy_read_struct(&png_ptr, &info_ptr, );
return buff;
} int main()
{
char *path = "F://1.png";
int width = ;
int height = ;
png_bytep buff = load_png_image(path, &width, &height);
if (!buff)
{
printf("load_png_image(filepath) erro");
}
printf("width:%d, height:%d\n", width, height); /*int i = 0, j = 0;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
printf("%x,%x,%x ", buff[i*width + 3 * j + 0], buff[i*width + 3 * j + 1], buff[i*width + 3 * j + 2]);
}
printf("\n");
}*/ system("pause"); return ;
}
读取6*6蓝底黑边框png图片数据域控制台效果:

libpng处理png图片(一)的更多相关文章
- libpng处理png图片(二)
一,实现效果:图片剪切, 图片拼接 ------------------切割后------------------> ...
- OpenGL使用libPng读取png图片
#include<stdarg.h> #include<png.h> #include<glut.h> #include<math.h> #includ ...
- 【转】 OpenGL使用libPng读取png图片
觉得自己越来越无耻了呢?原文:http://laoyin.blog.51cto.com/4885213/895554 我复制到windows下也可以正常跑出来. #include<stdarg. ...
- centos 6.5 + php5.5.31 fastcgi (fpm) 编译安装
yum intsall zlib zlib-devel //gzip 压缩和解压 yum install openssl openssl-devel yum install libxml2 libxm ...
- opencv中的子库
1 FLANN 近似最近邻库,NN就是nearest neighbor的缩写. 2 IlmImf Ilm是Industrial light & magic公司的缩写. Imf是image fo ...
- Android开源项目分类汇总-转载
太长了,还是转载吧...今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参 ...
- libpng Cximage图片处理
跨平台 开源 png图片处理 https://www.cnblogs.com/lidabo/p/6923426.html Cximage BIPro
- pngcrush caught libpng error: Not a PNG file..
今日真机测试遇到这样的奇葩问题: While reading XXX/XXX.png pngcrush caught libpng error: Not a PNG file.. 替换几次图片都没解决 ...
- [原创]cocos2dx加载网络图片&异步加载图片
[动机] 之前看到一款卡牌游戏,当你要看全屏高清卡牌的时候,游戏会单独从网络上下载,本地只存了非高清的,这样可以省点包大小,所以我萌生了实现一个读取网络图片的类. [联想] 之前浏览网页的时候经常看到 ...
随机推荐
- nginx反向代理与负载均衡
一:nginx反向代理与负载均衡配置思路与用法 1.nginx反向代理:就是你去相亲时,媒婆就是这里的代理,让媒婆带你去见姑娘 2.nginx负载均衡:就是有很多的媒婆经过商量给你选出最适合你的姑娘, ...
- HTML5本地图片裁剪并上传
最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小).这个功能的需求是:头像最初剪切为一个正方形.如果选择的图片小于规定 ...
- MyBatis快速入门(一)
一.MyBatis背景介绍 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的 ...
- PyQt通过resize改变窗体大小时ListWidget显示异常
前几天开始的pygame音乐播放器Doco,做的差不多了,上午做到了歌词显示和搜索页面.遇到bug,即通过resize改变ui大小时ListWidget显示异常 #目的: 增加一部分窗口用来显示歌词和 ...
- Struts2之i18N国际化
对于i18n其实没有太多内容,一般的公司用不到这些内容,除非是跨国公司,但即便是跨国公司也不一定会使用i18n来进行国际化处理,所以本篇内容仅供大家了解,不做深入的探讨,希望通过本篇内容,可以帮助大家 ...
- 老李分享:Web Services 组件 2
WSDL 是一种基于 XML 的语言,它用来对 web service 及其如何访问进行描述. WSDL 表示 web service 描述语言(Web Services Description La ...
- iOS 给UITextView加一个placeholder
苹果并没有为UITextView提供placeholder功能.我们可以通过两种办法实现. 方法一: 思路:设置默认显示的文字,颜色设置为灰色.代理方法监听textView点击. 缺点:如果点击到文字 ...
- 腾讯IVWEB团队:WebRTC 点对点直播
作者:villainthr 摘自:villainhr WebRTC 全称为:Web Real-Time Communication.它是为了解决 Web 端无法捕获音视频的能力,并且提供了 peer- ...
- [编织消息框架][JAVA核心技术]动态代理应用5-javassist
基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...
- Mybatis基础学习(三)—映射文件
一.输入映射 1.parameterType 指定输入参数的Java类,可以使用别名或者类的全限定名.它也可以接受基本数据类型.POJO对象.HashMap. (1)基本数据类型 (2 ...