日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 极简的 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

微信掃描二維碼,關注我的公眾號

總結

以上是生活随笔為你收集整理的极简的 PNG 编码函数 svpng(),用来学习C语言,真的很爽的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。