文章目录

  • 一、png相关概念
    • png---一种无损压缩算法的位图格式
    • png和bmp、jpeg图片比较
    • libpng---一款C语言编写的读写PNG文件的跨平台的库
  • 二、png文件格式---文件标签+特定格式数据块
    • 2.1 PNG文件标签,8字节---用于识别png文件
    • 2.2 PNG关键块critical chunk介绍
      • 2.2.1 文件头数据块IHDR(header chunk)
      • 2.2.2 调色板数据块PLTE(palette chunk)
      • 2.2.3 图像数据块IDAT(image data chunk)
      • 2.2.4 图像结束数据IEND(image trailer chunk)
  • 三、libpng使用基础
    • 3.1 libpng库 的下载编译安装
    • 3.2 libpng库的解码图片示例
  • 参考

一、png相关概念

png—一种无损压缩算法的位图格式

PNG:Portable Network Graphics,是一种支持无损压缩(使用从LZ77派生的无损数据压缩算法)的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。PNG的开发目标是改善并取代GIF作为适合网络传输的格式而不需专利许可,所以被广泛应用于互联网及其他方面上。

png和bmp、jpeg图片比较

bmp常见是非压缩的,它size最大但是显示简单,主要是最后用作本地存储 和 显示阶段-无需解压, 传输都会选择png和jpeg。jpeg图片的优势是压缩比例大,它由于存在转换到yuv域并进行下采样420,通过有损压缩算法 能得到比png更高的压缩效率,常见的大图都会选择jpeg而非png。png相对jpeg它的优势是包含alpha通道(可以做半透明效果,而jpeg是不存在的alpha通道),并且常用无损压缩,常见用在一些精细小图标,或者必须带上aplha透明度的图片的使用场景。

libpng—一款C语言编写的读写PNG文件的跨平台的库

libpng是一款C语言编写的读写PNG文件的跨平台的库,libpng 可作为 ANSI C (C89) 源代码使用,并且需要zlib 1.0.4 或更高版本提供压缩算法支持。

二、png文件格式—文件标签+特定格式数据块

PNG图像格式文件由一个8字节的PNG文件标签file signature按特定结构组织的3个以上的后续数据块chunk组成
1、文件标签file signature为一组固定8字节文件署名,用于识别png文件。
2、数据块chunk分为 :1、关键块critical chunk,是文件必须包含的关键块,读取软件也必须支持解析;2、辅助块ancillary chunks,允许软件忽略它不认识的附加块,允许PNG格式在扩展时仍能保持与旧版本兼容。每个数据块都由下面所示的的4个域组成:

CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中。

我们选择如下图片做举例:

2.1 PNG文件标签,8字节—用于识别png文件

PNG文件包括8字节文件署名(89 50 4E 47 0D 0A 1A 0A,十六进制),用来识别PNG格式

2.2 PNG关键块critical chunk介绍

关键块critical chunk*中有4个标准数据块:
文件头数据块IHDR(header chunk):包含有图像基本信息,作为第一个数据块出现并只出现一次。
调色板数据块PLTE(palette chunk):必须放在图像数据块之前。
图像数据块IDAT(image data chunk):存储实际图像数据。PNG数据允许包含多个连续的图像数据块。
图像结束数据IEND(image trailer chunk):放在文件尾部,表示PNG数据流结束。

2.2.1 文件头数据块IHDR(header chunk)

IHDR含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG文件中只能有一个文件头数据块。文件头数据块由13字节组成,它的格式如下表所示


8~ 11字节:0xd表示IHDR长度13字节,12~ 15字节:就是ASCII码的IHDR字符表示块类型;紧接着13个字节为IHDR的内容:0x27b 宽度635,0x19b 高度 411,0x8 色深度 8bit,0x6 颜色类型,带alpha通道的真彩,0x0 压缩算法LZ77派生算法,0x0 滤波器方法,0x0 非隔行扫描;剩下的是CRC校验码;

2.2.2 调色板数据块PLTE(palette chunk)

PLTE包含有与索引彩色图像((indexed-color image))相关的彩色变换数据,它仅与索引彩色图像有关,而且要放在图像数据块(image data chunk)之前。真彩色的PNG数据流也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。(类似bmp也有相同的调色板机制)

调色板实际是一个彩色索引查找表,它的表项数目可以是1~256中的一个数,每个表项有3字节,因此调色板数据块所包含的最大字节数为768。

2.2.3 图像数据块IDAT(image data chunk)

它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。

2.2.4 图像结束数据IEND(image trailer chunk)

它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。内容为 00 00 00 00 49 45 4E 44 AE 42 60 82

三、libpng使用基础

3.1 libpng库 的下载编译安装

1、下载libpng源码:https://sourceforge.net/projects/libpng/files/,这里我下载的最新libpng-1.6.37版本。
2、阅读INSTALL文件进行编译

# prefix=path是可添加的附加参数,表示指定编译结果安装的目录
./configure --prefix=/home/study/libpng/libpng_build
make check
make install

3、编译后查看编译出内容:其中最关键的是静态库libpng16.a和动态库libpng16.so,还有输出的文档

├── bin
│   ├── // 略
├── include
│   ├── libpng16
│   │   ├── pngconf.h
│   │   ├── png.h
│   │   └── pnglibconf.h
│   ├── pngconf.h -> libpng16/pngconf.h
│   ├── png.h -> libpng16/png.h
│   └── pnglibconf.h -> libpng16/pnglibconf.h
├── lib
│   ├── libpng16.a
│   ├── // 略
│   ├── libpng.so -> libpng16.so
└── share└── man

3.2 libpng库的解码图片示例

接下来通过libpng库写一个png的解析程序,用来解析一张png图片,代码可以参考源码目录的example.c举例。
libpng的整体用法和libjpeg的设计非常类似,都是先注册一个异常跳转的调用函数方便调用库失败异常通知和处理,然后设置输入流可以来源文件或者内存,再调用解析头函数,然后可以查看到png文件各种属性,接下来根据需要有选择的进行一些输出属性设置(比如位宽控制,是否丢弃alpha通道,是否做缩放,格式转化 如把灰度数据转化为RGB存储数据,数据排序调整,滤波设置),然后申请内存,调用读取接口把png的数据读出。

#include <png.h>
#include "stdio.h"
#include "stdlib.h"
#include <string.h>int main(int argc, char *argv[]) {if (argc < 2) {printf("please intput like: ./a.out xxx.png\n");return -1;}// 打开输入文件FILE *infile = fopen(argv[1], "rb");if (infile == NULL) {printf("intput file %s open failed!\n", argv[1]);return -1;}// 创建输出文件FILE *outfile = fopen("./output.bit", "w+");if (outfile == NULL) {printf("out file open failed!\n");return -1;}png_structp png_ptr = NULL;png_infop info_ptr = NULL;png_uint_32 width, height;int bit_depth, colortype, interlace_type;// 创建libpng库依赖的解码示例上下文png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);if (png_ptr == NULL) {printf("png_create_read_struct failed!\n");return -1;}info_ptr = png_create_info_struct(png_ptr);if (info_ptr == NULL) {printf("png_create_info_struct failed!\n");return -1;}if (setjmp(png_jmpbuf(png_ptr))) {printf("setjmp failed!\n");     return -1;}// 设置输入流png_init_io(png_ptr, infile);// 读取png文件头png_read_info(png_ptr, info_ptr);// 获取png文件解析信息png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &colortype, &interlace_type, NULL, NULL);// 根据获取文件信息做输出属性调整,得打ARGB8888的输出格式if(colortype == PNG_COLOR_TYPE_PALETTE)png_set_palette_to_rgb(png_ptr);// 要求转换索引颜色到RGBif(colortype == PNG_COLOR_TYPE_GRAY && bit_depth < 8)png_set_expand_gray_1_2_4_to_8(png_ptr);// 低于8bit深度强制8bitif(bit_depth == 16)png_set_strip_16(png_ptr); // 16bit深度要求强制8bitif(png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS))png_set_tRNS_to_alpha(png_ptr); // 扩展RGB数据的alpha通道到ARGB数据类型if(colortype == PNG_COLOR_TYPE_GRAY || colortype == PNG_COLOR_TYPE_GRAY_ALPHA)png_set_gray_to_rgb(png_ptr); //灰度必须转换成RGB// 申请读取sizeint size = width * height * 4; // 输出类型为argb8888每个像素4字节char *outbuf = malloc(size);if (outbuf == NULL) {printf("malloc failed!\n");       return -1;}png_bytep *row_pointers = (png_bytep *)malloc(height * sizeof(char *)); // 申请行指针数组用于读取if (row_pointers == NULL) {printf("malloc failed!\n");    return -1;}int row;for (row = 0; row < height; row++)row_pointers[row] = outbuf + row * width * 4;// 读取数据,这里使用一次读取完成的方式png_read_image(png_ptr, row_pointers);png_read_end(png_ptr, info_ptr);// 读取的数据写到输出文件fwrite(outbuf, size, 1, outfile);// 销毁解码示例上下文png_destroy_read_struct(&png_ptr, &info_ptr, NULL);// 关闭全部文件free(outbuf);fclose(infile);fclose(outfile);return 0;
}

编译执行:

gcc sample_png2.c -lpng
./a.out ./test.png

解析出来的工具用裸数据 ARGB格式查看output.bit如下,说明解析ok:

参考

维基百科png介绍:https://chi.jinzhao.wiki/wiki/PNG
libpng官网:http://www.libpng.org/pub/png/libpng.html
libpng源码:https://sourceforge.net/projects/libpng/files/
https://www.w3.org/TR/PNG/#4Concepts.Sourceimage
https://dev.gameres.com/Program/Visual/Other/PNGFormat.htm
https://blog.csdn.net/hherima/article/details/45847043

图形图像基础 之 png介绍相关推荐

  1. 图形图像基础 之 jpeg介绍

    一.[概念]jpeg相关概念简介 jpeg-一种影像有损压缩标准方法 后缀jpg/jpeg JPEG(Joint Photographic Experts Group 联合图像专家小组)是一种针对照片 ...

  2. 图形图像基础 之 bmp介绍

    文章目录 一.bmp相关概念 位图Bitmap 与 矢量图Vector---用点表示 还是 用公式表示 bmp(Bitmap-File)---一种非压缩图形文件位图格式,后缀bmp 二.bmp文件格式 ...

  3. 4.图形图像素材编辑

    4.图形图像素材编辑 图形.图像是人类视觉所感受到的一种具象化的信息,是多媒体信息的主要类型,也是信息传递最基本.最常见的方式.它可以形象.生动和直观地表达大量的信息,具有文字和声音无可比拟的优点.图 ...

  4. OpenCV图形图像击中击不中HITMISS变换处理基础知识

    ☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 博文传送门: 老猿关于HTM变换的博文目录请见: https://blog.csdn.ne ...

  5. 图形和图像计算机基础知识,计算机图形图像基础

    <计算机图形图像基础>是2011-03-01浙江大学出版社出版的图书,作者是程辉,田少煦.[1] 书    名 计算机图形图像基础 作    者 程辉,田少煦ISBN 9787308083 ...

  6. 一个C#函数学完C#图形图像编程基础

    老师说C#主要用于 1.winform开发 2.网络 3.驱动 在图形图像处理上用的比较少,不过书里有图形图像编程这一章节,为了系统的学完C#编程基础,以及为了能够更熟悉C#的特性,再加上今天晚上闲的 ...

  7. 一步一步学Silverlight 2系列(31):图形图像综合实例—实现水中倒影效果

    Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ir ...

  8. c 语言 数据库 pdf下载,Visual C/C++ 编程精选集锦 数据库及图形图像分册 PDF扫描版[38MB]...

    Visual C/C++ 编程精选集锦 数据库及图形图像分册 内容简介: Visual C/C++作为功能强大的可视化应用程序开发工具,是计算机界公认的优秀应用开发工具.Microsoft的基本类库M ...

  9. 视频教程-图形图像-无中生有Photoshop CS6背景素材技法ps教程 [超多案例]-其他

    图形图像-无中生有Photoshop CS6背景素材技法ps教程 [超多案例] 全栈工程师,曾担任多家互联网公司技术总监.运营经理,在技术与运营方面积累了大量实战经验,同时也是清华大学出版社特约作家, ...

最新文章

  1. 团队计划(5.25)
  2. oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT
  3. Jquery中使用select2插件实现ajax实时请求数据
  4. 东莞.NET俱乐部线下技术沙龙-活动报名
  5. 脚本错误和安全警报怎么解决_适用于应用程序错误的AWS警报
  6. 前端学习(2215):认识react(2)
  7. 小鹏全新中大型SUV谍照曝光,智能驾驶+纯电SUV+睡眠舱?期待值拉满
  8. 交接文档怎么写_如何最快速的交接工作
  9. Java学习之数据类型的转换
  10. uniapp手写地图搜索选取功能
  11. 年假计算器在线_死亡计算器 和 年龄计算器
  12. JSP脚本元素(声明 %! 表达式 %= 脚本 %)
  13. 模块化机房建设指导书_模块化机房建设方案
  14. 皮皮虾无水印解析源码实战
  15. 小蚁智能摄像机无法连接服务器,小米摄像头连接不上
  16. 设计心理学中的映射交互设计概念|优漫动游
  17. js获取内网ip地址,操作系统,浏览器版本等信息
  18. 2020中国网络安全年会论文发布 知道创宇ZoomEye引领全球网空测绘
  19. 中职计算机专业英语ppt,中职计算机英语教学方法论文
  20. 12306极速全自动抢票

热门文章

  1. Java枚举深入理解以及HttpStatus类的使用
  2. git代码从A库某分支迁到B库某分支(亲测有效)
  3. 计算机网络技术中,分组交换技术在计算机网络技术中的作用及特点是什么?
  4. 鼠标指针在微信界面消失怎么办?
  5. Rational Rose 2003下载与破解安装
  6. 问题解决:“nginx: [emerg] unknown directive “ “ in /etc/nginx/conf.d/XXX.conf:122”
  7. python贴吧数据可视化软件_Python数据可视化工具之Pyecharts初体验
  8. OCR(脱机手写汉字识别与印刷汉字识别)
  9. 点集拓扑学习(一)拓扑空间
  10. JavaEE的RESTful标准技术JAX-RS,jersey-client客户端使用介绍【享学Java】