极简的 PNG 编码函数 svpng(),用来学习C语言,真的很爽

这个是在知乎上看到的大神写的文章,如果是学习C语言入门的,我觉得可以从这个入手,特别是对图像感兴趣的。

文章中提到的「我」,指的是「Milo Yip」大神。

1.    什么是png格式图片?

相对地,PNG(Portable Network Graphics)就是一个广为人知的图片格式。如果可以把影像直接储存成 PNG,不是更理想么?

然而,在 C/C++ 中写入 PNG 一般需要链接一些程序库,例如 PNG 的标准参考程序库是 libpng。它很强大,支持 PNG 所有功能,但对于初学者而言,配置、编译并学习如何使用这些程序库,可能已足够打消动手的念头。

可以简单一点么?

2.    svpng

为此,我在周末尝试写一个极简的 C 函数 Github miloyip/svpng(save PNG 的缩写),它仅能写入 24-bit RGB 或 32-bit RGBA、无压缩的 PNG。它只有一个 32 行代码的函数。

github地址:

https://github.com/miloyip/svpng

用法如下:

#include "svpng.inc"void test_rgb(void) {unsigned char rgb[256 * 256 * 3], *p = rgb;unsigned x, y;FILE *fp = fopen("rgb.png", "wb");for (y = 0; y < 256; y++)for (x = 0; x < 256; x++) {*p++ = (unsigned char)x;    /* R */*p++ = (unsigned char)y;    /* G */*p++ = 128;                 /* B */}svpng(fp, 256, 256, rgb, 0);fclose(fp);
}

就会输出这个 rgb.png 文件:

这个函数的声明很简单,缺省配置下是这样的:

/*!\brief 以 PNG 格式存储 RGB/RGBA 影像\param out 输出流(缺省使用 FILE*)。\param w 影像宽度。(<16383)\param h 影像高度。\param img 影像像素数据,内容为 24 位 RGB 或 32 位 ARGB 格式。\param alpha 影像是否含有 alpha 通道。
*/
void svpng(FILE* out, unsigned w, unsigned h, const unsigned char* img, int alpha);

相信这样的函数时使对初学者而言,也极易使用。也不需要另外生成程序库,只要复制到项目便可使用。

3.    代码实现

这里简单介绍实现要点,对此没兴趣的读者也可略过。

根据 Portable Network Graphics (PNG) Specification (Second Edition) 「www.w3.org」,PNG 文件由多个 chunk 组成。每个 chunk 的类型以 4 个字符表示。最基本的 PNG 文件内容是:

  • 8 字节 magic number:用于识别 PNG 格式

  • IHDR(Image Header) chunk:描述影像的维度、色彩深度、色彩格式、压缩类型等

  • IDAT(Image Data)chunk:存储影像的像素数据

  • IEND(Image End)chunk:PNG数据流结束

每个 chunk 的结构是:

  • chunk 内容长度(4 字节)

  • chunk 类型(4 字节)

  • chunk 内容

  • chunk 的 CRC(包括类型和内容)

PNG 里的数据是以大端(big endian)编码的,但在 IDAT 中,每个 block 的长度则以小端存储。另外,实现的难点之一,是要同时实现 CRC-32 及 Adler-32 校验和(checksum)的生成。

编码实现如下(文字版请移玉步至 svpng.inc):

为了减少代码大小,使用宏去避免加入多个函数。另外,为了简化实现,把每一行像素写成一个 block,这样可能会浪费一点空间,但对于这函数而言也不是问题。

4.     结语

本文介绍了一个极简的 C 函数 svpng,方便在 C/C++ 中把图像存储成 PNG 文件,并简介了当中的实现。希望读者能利用此函数,进入计算机图形学之门。

===

文中的 inc 而不是.h,是因为inc 是对方法的实现,而不是简单的声明。

unsigned char rgb[256 * 256 * 3] ,可能有的人不明白为什么数组要这样声明,一个像素点是通过{R,G,B}三色值表示的,所以后面有一个3,但是一张图片,是包含有长和宽的,也就是前面的256*256,就是这张图片的长和宽。实际上的图片是这样排列的 { R, G, B, R, G, B, ... } 的形式,从上至下,左至右。


#推荐阅读#

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32项目(六)—— 中文电子捡货标签

STM32项目&#xff08;六&#xff09;—— 中文电子捡货标签 宗旨&#xff1a;技术的分享是有限的&#xff0c;分享的精神是无限的。 传统物流行业仓储拣货采用纸单作业&#xff0c;拣货完成后再进行验货、出货&#xff0c;容易造成拣货错误、拣货速度与效率低、新员工培训时间…

如何把Linux工具里的“军刀”BusyBox移植到RT-Thread Smart?

RT-Thread Smart 系列连载序号内容1《当“树莓派”遇上RT-Thread Smart——应用编程入门》2《RT-Thread Smart和树莓派&#xff1a;wget & cURL网络客户端》3《如何把Linux工具里的“军刀”BusyBox移植到RT-Thread Smart&#xff1f;》4sdl图形类应用5dropbear及ssh server…

STM32项目(七) —— 智能仓库管理系统

智能仓库管理系统 随着经济的发展&#xff0c;对企业的生产经营要求提高&#xff0c;企业必须综合利用各种先进技术&#xff0c;在网络与信息技术的支持下&#xff0c;改进现在的生产经营模式和组织结构&#xff0c;增加利润。随着企业规模的扩大。高效方便的仓库管理系统&…

花三千块钱求推荐一个靠谱的C++工程师

直接说重点有个朋友想招一个C工程师&#xff0c;因为项目的原因&#xff0c;不可能现在招新人培养&#xff0c;想招到一个熟练C的工程师&#xff0c;所以想在公众号里面广而告之。如果是你推荐的人入职后&#xff0c;就可以获得三千奖励&#xff0c;如果是你本人入职&#xff0…

老外码农酒后吐槽,该说的不该说的全说了!!

上个月&#xff0c;一个有着10年码龄的程序猿喝高了&#xff0c;在社交网站Reddit上吐槽。然后被疯狂转发&#xff0c;点赞。可说是讲出了咱们很多码农的心声。咱们国内这边也有不少版本了。我们也凑凑热闹翻译一版。跟大家一块儿欣赏一下&#xff1a;今天是有点儿高了&#xf…

Intel官宣开发RISC-V处理器:明年首发7nm工艺

近日业界盛传&#xff0c;Intel计划以20亿美元收购RISC-V IP供应商SiFive——后者的产品已被80多家公司采纳&#xff0c;设计了200多种产品&#xff0c;出货量极大&#xff0c;广泛用于各种加速器。虽然双方对于收购都拒绝置评&#xff0c;但深入合作已经展开。Intel官方宣布&a…

SCCM2007 R2的部署前准备,SCCM系列之一

SCCM 2007 R2的部属前准备<?xml:namespace prefix o />System Center 是微软著名的管理平台软件&#xff0c;在实现Microsoft的MOF&ITIL的IT管理理念的过程中发挥了很重要的作用&#xff0c;System Center可以在MOF的每一个运维象限中都有对应的System Center产品协…

硬件基础 —— 电阻

硬件基础 —— 电阻1、电阻基本知识电阻&#xff1a;在电路中对电流有阻碍作用并且造成能量消耗的部分。主要物理特性是变电能为热能&#xff08;耗能元件&#xff09;&#xff0c;符号R&#xff08;单位&#xff1a;Ω&#xff09;。2、电阻的作用&#xff1a;分流、限流、分压…

史上最全的LED点灯程序,你都掌握了吗?

摘要&#xff1a;你点亮过多少板子的LED灯呢&#xff1f;有很多小伙伴留言说讲一下STM32、FPGA、Liunx他们之间有什么不同。不同点很多&#xff0c;口说无凭&#xff0c;今天就来点亮一下STM32、FPGA和Liunx板子的LED灯&#xff0c;大家大致看一下点灯流程和点灯环境以及点灯流…

B站硬核up主稚晖君:对于3年以上软件开发工程师,我有这些建议!

稚晖君&#xff0c;何许人也&#xff1f;本硕就读于电子科技大学华为AI架构师热爱硬件开发B站硬核UP主“栈溢出”工程师加入“华为天才少年计划”或许当你看到这一堆Title的时候并不觉得有什么特别&#xff0c;那么接下来看看他的一些作品。作品1&#xff1a;B站最强小电视这条…

同事说rar压缩有风险,让我用zip压缩文件

在现在最常见的压缩文件有zip、rar、7z三种&#xff0c;它们都有各自的优点和缺点。我们用一句话来概括一下&#xff1a;7z压缩率最高&#xff0c;RAR安全性高&#xff0c;ZIP使用范围广。文件压缩打包是最为常见的一种分享方式了&#xff0c;而众多的压缩格式中zip仍然是主流。…

JAVA实现概率计算(数字不同范围按照不同几率产生随机数)

程序中经常遇到随机送红包之类的情景&#xff0c;这个随机还得指定概率&#xff0c;比如10%的机率可以得到红包。那么java怎么实现一个简单的概率计算了&#xff0c;见如下例子&#xff1a; int randomInt RandomUtils.nextInt(1,101); if(randomInt < 10){ //100里面1个数…

AKI-H8串口通信

串口通信是一种通信接口简写SCI&#xff0c;它可是实现异步和同步两种传输模式。可以思考一下同步和异步的区别。 所谓同步就是接收方和发送方使用的是同一个时钟&#xff0c;步调一致的处理数据。典型的就是CPU和内存&#xff0c;通过总线存取数据。特点就是快&#xff0c;发送…

字节取消大小周,部分员工:心疼,每个月少拿 1W 块

如图&#xff0c;是脉脉最近的一个热帖&#xff0c;头条昨天全员发邮件取消了大小周&#xff0c;原本是一件好事&#xff0c;减轻大家的工作压力&#xff0c;努力向 workbalance 靠拢&#xff0c;可是看着风向好像不太对&#xff0c;我们继续看下 TOP 的几个回复。下面是反对头…

高通LCD的pwm背光驱动

发生异常的现象&#xff1a; msm8953 lcd在快速亮灭的情况下背光概率性休眠不灭&#xff1b;测量高通pwm&#xff0c;发现正常的时候pwm的管脚LCM_BL_PWM为低电平&#xff0c;失败的时候为高电平&#xff1b; 根据原理图&#xff1a; mpp是什么&#xff1f; mpp是基于电源pmic的…

为什么一个字节定义成8位?

今天给大家分享一个小小知识点&#xff0c;为什么一个字节定义成8位呢&#xff1f;一些人没有回答到点子上。这件事得追溯计算机历史&#xff0c;源于IBM360操作系统和图灵奖得主&#xff08;Fred&#xff09;Brooks Jr。布鲁克斯被问到“您认为自己最大的技术成就是什么&#…

硬件基础 —— 光耦

光耦1、工作原理以光为媒介传递电信号。对输入和输出信号有良好的隔离作用&#xff08;光耦隔离&#xff09;。光耦一般由三个部分组成&#xff1a;光的发射、光的接收和信号放大。输入的电信号驱动发光二极管&#xff0c;被光探测器接收而产生光电流&#xff0c;再经过进一步放…

红外感应自动出水水龙头的电路原理

红外感应自动出水的水龙头&#xff0c;生活中很常见&#xff1a;可以用以下的电路方案实现&#xff0c;供电采用USB的5V&#xff1a;只要手靠近“红外线靠近检测模块”&#xff0c;直流水泵就会开启供水&#xff1a;其中这种直流水泵长这样&#xff1a;当“红外线靠近检测模块”…

Linux面试最高频的5个基本问题

CPU利用率和CPU负载的区别是什么提到CPU利用率&#xff0c;就必须理解时间片。什么是CPU时间片&#xff1f;我们现在所使用的Windows、Linux、Mac OS都是“多任务操作系统”&#xff0c;就是说他们可以“同时”运行多个程序&#xff0c;比如一边打开Chrome浏览器浏览网页还能一…

用iptables实现G1手机cmwap代理上http网站[转]

2019独角兽企业重金招聘Python工程师标准>>> 折腾了几天&#xff0c;总算有点阶段性成果&#xff1a; 证实可以用iptables实现通过cmwap的代理上HTTP协议的网站。 首先&#xff0c;android系统的实现是有缺陷的。在接入apn中指定的proxy并不会被系统所用。好似只有浏…