国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

libpng的png_read_info和png_read_image使用

2019-11-08 02:19:22
字體:
供稿:網(wǎng)友

常用接口

libpng庫解析圖片主要用的函數(shù)大致有: png_sig_cmp(sig, 0, 8); png_create_read_struct(png_get_libpng_ver(NULL), NULL, NULL, NULL); png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, trfile); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_rowbytes(png_ptr,info_ptr); png_read_image(png_ptr, row_pointers);

初始化PNG數(shù)據(jù)

加載png圖片

png_structp png_ptr;png_infop info_ptr;FILE * trfile;void Load(char * fileName){ trfile = fopen(name,"rb"); BYTE sig[9] = {0}; fread(sig, 1, 8, trfile); int result ; result = png_sig_cmp(sig, 0, 8); png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); esult = setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, trfile); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr);}

png_sig_cmp(sig, 0, 8): it will return 0 (false) if the bytes match the corresponding bytes of the PNG signature; 驗證PNG文件的正確性完整性; 如果你已經(jīng)使用png_sig_cmp函數(shù)來檢查了png數(shù)據(jù),需要調(diào)用png_set_sig_bytes函數(shù)來告訴libpng庫,這樣庫處理數(shù)據(jù)的時候?qū)^相應(yīng)的數(shù)據(jù)

png_set_sig_bytes(png_ptr, 8); Tell lib we have already handled the first “8” magic bytes. Handling more than 8 bytes from the beginning of the file is an error. 設(shè)置讀取PNG文件的指針偏移量,不能超過8位(用于配置png_sig_cmp的使用);

setjmp(png_jmpbuf(png_ptr)) When libpng encounters an error, it expects to longjmp back to your routine; 設(shè)置發(fā)生錯誤時返回錯誤時調(diào)用的位置; 用setjmp/longjmp函數(shù)來處理異常。libpng庫默認(rèn)集成這種機制來完成異常處理; 如果設(shè)置了用戶自定義的錯誤處理函數(shù),libpng將會調(diào)用用戶自定義錯誤處理函數(shù),而不會返回到這個設(shè)置了默認(rèn)返回點的調(diào)用點上;

輸出PNG文件的長寬位深度數(shù)據(jù)

經(jīng)過上面的Load后可以打印相關(guān)的png數(shù)據(jù),這里定義一個結(jié)構(gòu)體存放更清晰

typedef struct { int pixelDepth; int imageWidth; int imageHeight;}PngImageInfo;void GetImageInfo(PngImageInfo* pInfo){ pInfo->pixelDepth = info_ptr->pixel_depth; pInfo->imageWidth = info_ptr->width; pInfo->imageHeight = info_ptr->height;}

解碼位深度為24bit和32bit的PNG文件

下面開始解碼png數(shù)據(jù)到一個數(shù)組中,用于進行繪制到顯存下

unsigned long* GetPngData(int dstW, int dstH){ unsigned long pDst[dstW * dstH * 4]; // 解析后的數(shù)據(jù),24位和32位的圖每個像素占空間ARGB個1byte png_bytep row_pointers[dstH]; for (int row = 0; row < dstH; row++){ row_pointers[row] = NULL; } for (int row = 0; row < dstH; row++){ //png_get_rowbytes(png_ptr,info_ptr)==834==278*3(本例程使用的是24位深度的PNG圖片) row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr,info_ptr)); } png_read_image(png_ptr, row_pointers); if(info_ptr->pixel_depth == 24) { int pixelR,pixelG,pixelB; unsigned char * pSrc; int i, j; int top = 0; //畫布y軸上偏移量 int left = 0; //畫布x軸上偏移量 for(j=0;j<dstH;j++){ pSrc = row_pointers[top+j] + left * 3; for(i=0;i<dstW;i++){ pixelR = *pSrc++; pixelG = *pSrc++; pixelB = *pSrc++; pDst[i] = 0xFF000000 | (pixelR << 16) | (pixelG << 8) | pixelB; } pDst += dstW;// 加上圖片的橫向像素點(即縱向下移一個像素單位) } } for (int row = 0; row < info_ptr->height; row++){ png_free(png_ptr,row_pointers[row]); } return pDst; // 返回指針是不科學(xué)的 但是這里僅僅是舉例說明}

這里插播一下關(guān)于32位的位深度的PNG圖片的解析:

if(info_ptr->pixel_depth == 32){ unsigned long pixelR,pixelG,pixelB,pixelA; unsigned char * pSrc; int i, j; for(j=0;j<dstH;j++){ pSrc = row_pointers[top+j] + left * 4; for(i=0;i<dstW;i++) { pixelR = *pSrc++; pixelG = *pSrc++; pixelB = *pSrc++; pixelA = *pSrc++; pDst[i] = (pixelA<< 24) | (pixelR << 16) | (pixelG << 8) | pixelB; } pDst += dstW; }}

繪制解碼后的PNG文件數(shù)據(jù)

上面的Draw函數(shù)已經(jīng)獲取到解碼后的png數(shù)據(jù),接下來只需要把數(shù)據(jù)放入到內(nèi)存對應(yīng)的區(qū)域就能把圖片顯示出來了:

// 硬件地址unsigned long* GetDisplayMemoryAddr(){ int* h_hsPR = open("/dev/frame", O_RDWR, 0); unsigned long* pDst = (unsigned long*)mmap(0, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED,h_hspr, 0); return pDst;}// 圖片大小 278*182// 畫布大小(屏幕大小) 800*480void CopyPngDataToDisplayDriver(){ unsigned long*pDst = GetDisplayMemoryAddr(); unsigned long*pSrc = GetPngData(278, 182); for(int i=0; i<182; i++) { memcpy(pDst,pSrc,278 * 4); //pDst[dstW*dstH*4] pDst += 800; pSrc += 278; } ioctl(h_hspr,IOCTL_Y,NULL); ioctl(h_hspr,IOCTL_X,NULL);}

效果為: 這里寫圖片描述

本次例程使用的是交叉編譯到全志的開發(fā)板中進行測試 PNG圖片文件數(shù)據(jù):278*182,位深度24


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 孝感市| 洛阳市| 三明市| 甘泉县| 西乌| 株洲县| 昌都县| 万安县| 吴江市| 福建省| 潜江市| 航空| 三穗县| 稻城县| 噶尔县| 曲靖市| 丰县| 白河县| 泾阳县| 周宁县| 乐东| 永胜县| 伊宁市| 珲春市| 徐闻县| 江西省| 云南省| 南溪县| 巩义市| 将乐县| 安塞县| 永仁县| 德阳市| 榆树市| 乌鲁木齐县| 景德镇市| 同心县| 汉沽区| 汤原县| 桐城市| 安徽省|