PNG 文件简单解析 和 libpng的简单实用
PNG 文件格式
89 50 4E 47 0D 0A 1A 0A 表示PNG的数据格式
00 00 00 0D IHDR 文件头数据的长度
49 48 44 52 IHDR 表示
00 00 00 01 00 00 00 01 表示图像的宽高
08 色深 2^8 = 256 位的调色板颜色
02 颜色类型 索引图像 真彩色图像
00 压缩算法
00 滤波器方法
00 表示非间隔扫描
90 77 53 DE 表示CRC校验
00 00 00 04
67 41 4D 41 gAMA值 可能跟伽马数值相关 辅助数据块
00 00 B1 8F ??
00 00 00 00 49 45 4E 44 AE 42 60 82 IEND 结束位置
w3c 表示的是比较详细的但是这些东西。说实话 很难全面理解。
实用libpng的话比较容易读取矩阵数据。
个人烦了一个错误。导致进度极其缓慢。
因为刚开始,我的电脑是64位的win10 +ubuntu 然后现在ubuntu中安装了 libpng 1.6 可能是觉得不放心。我 ./configure [--pix...]这个路径没有加上
然后我安装了两此,结果就悲剧了。。。
有打算在windows 上面搞,可是 visual stdio 的加入 dll 目录啥的看起来好麻烦。。。
搞了好久在一个论坛上找到了勉强的解决方案下载 libpng1.5版本。
然后又报错。
从网上知道了,第三方的库 编译啥的。 转载自错误划重点
gm: error while loading shared libraries: libpng15.so.15: cannot open shared object file: No such file or directory
安装gm库产生问题
解决方案:
1) 如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令
ldconfig命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下, 搜索出可共享的动态链接库(格式如lib*.so*), 进而创建出动态装入程序(ld.so)所需的连接和缓存文件. 缓存文件默认为/etc/ld.so.cache, 此文件保存已排好序的动态链接库名字列表.
2) 如果共享库文件安装到了/usr/local/lib(很多开源的共享库都会安装到该目录下)或其它"非/lib或/usr/lib"目录下, 那么在执行ldconfig命令前, 还要把新共享库目录加入到共享库配置文件/etc/ld.so.conf中, 如下:
# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
# echo "/usr/local/lib" >> /etc/ld.so.conf
# ldconfig
然后问题就迎刃而解了。
工作中难免压力大,解决问题的能力可不能随着压力的增大而放弃。保持一个平常心。很重要哈。
记住编译的命令是 gcc xxx.c -lpng 或许后面还有一个什么
抄了一个PNG读取数组的代码,好像是抄的
#include "png.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "zlib.h"
#define PNG_BYTES_TO_CHECK 4
#define _POSIX_SOURCE 1
void read_png(char *file_name) /* We need to open the file */
{
png_structp png_ptr;
png_infop info_ptr;
int i;
png_bytep* row_pointers;
int sig_read = 0;
char buf[PNG_BYTES_TO_CHECK];
png_uint_32 width, height;
int bit_depth, interlace_type;
FILE *fp;
int w, h, x, y, temp, color_type;
int buffer[500000] = {0};
int count = 0;
int png_transforms;
if ((fp = fopen(file_name, "rb")) == NULL)
return ;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
/* 为这个结构体分配空间 存储这图像的信息*/
info_ptr = png_create_info_struct(png_ptr);
setjmp( png_jmpbuf(png_ptr) );
/* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */
temp = fread( buf, 1, PNG_BYTES_TO_CHECK, fp );
if( temp < PNG_BYTES_TO_CHECK ) {
fclose(fp);
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
printf("没有充足的字节\n");
return /* 返回值 */;
}
temp = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK );
if( temp != 0 ) {
fclose(fp);
printf("不匹配字符串\n");
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return /* 返回值 */;
}
/* 复位文件指针 */
rewind( fp );
/*如果我们已经读取了这些信息 跳过相应的函数*/
/* 开始读文件 */
png_init_io(png_ptr, fp);
/* 获取图像的色彩类型 */
png_read_png(png_ptr, info_ptr, png_transforms, NULL);
color_type = png_get_color_type( png_ptr, info_ptr );
/* 获取图像的宽高 */
//color_type = info_ptr->color_type;
w = png_get_image_width( png_ptr, info_ptr );
h = png_get_image_height( png_ptr, info_ptr );
/* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */
row_pointers = png_get_rows( png_ptr, info_ptr );
/* 根据不同的色彩类型进行相应处理 */
switch( color_type ) {
case PNG_COLOR_TYPE_RGB_ALPHA:
for( y=0; y<h; ++y ) {
for( x=0; x<w*4; ) {
/* 以下是RGBA数据,需要自己补充代码,保存RGBA数据 */
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // red
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // green
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // blue
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // alpha
}
}
break;
case PNG_COLOR_TYPE_RGB:
for( y=0; y<h; ++y ) {
for( x=0; x<w*3; ) {
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // red
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // green
/* 目标内存 */buffer[count++] = row_pointers[y][x++]; // blue
}
}
break;
/* 其它色彩类型的图像就不读了 */
default:
fclose(fp);
temp = PNG_COLOR_TYPE_RGB_ALPHA;
printf("其他格式不读了%d \n", color_type);
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return /* 返回值 */;
}
/* One of the following I/O initialization methods is REQUIRED */
for(i = 0; i < 200 ; i++)
{
printf("%d ",buffer[i]);
}
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return 0;
}
int main(int argc, char** argv)
{
FILE *fp;
int temp = 0;
char buf[PNG_BYTES_TO_CHECK];
/* 打开源头文件 */
if ((fp = fopen(argv[1], "rb")) == NULL)
return 0;
/* 读取标志位 如果不是png文件退出 */
if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK)
{
printf("Sorry,it is not the png file");
return 0;
}
else
{
// 非0 表示匹配
temp = (!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
printf("yes ,goog luck %d \n ", temp);
}
read_png(argv[1]);
//printf("%d",check_if_png("hei.png",fp));
return 0;
}
有很多博客介绍这些信息但是难免这些信息介绍的不全面。
如果知道如何把安装好的libpng库完全从计算机中删除掉的话,请留言。
[w3c关于PNG的介绍,最好用google翻译看一下](https://www.w3.org/TR/PNG/#4Concepts.Sourceimage)
[转载:错误划重点](http://www.cnblogs.com/sagech/p/5627084.html)
链接生成静态可执行文件
g++ test.cc -lpng16 -lz -L/usr/local/lib -static -o PNG_TO_H.static
PNG 文件简单解析 和 libpng的简单实用的更多相关文章
- Maven项目pom.xml文件简单解析
Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...
- 对 cloudwu 简单的 cstring 进行简单解析
题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...
- Skinned Mesh原理解析和一个最简单的实现示例
Skinned Mesh 原理解析和一个最简单的实现示例 作者:n5 Email: happyfirecn##yahoo.com.cn Blog: http://blog.csdn.net/n5 ...
- 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表 Items表记录了i ...
- tomcat原理解析(一):一个简单的实现
tomcat原理解析(一):一个简单的实现 https://blog.csdn.net/qiangcai/article/details/60583330 2017年03月07日 09:54:27 逆 ...
- node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例)
title: node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例) date: 2020-11-27 tags: node native sqlite3 前言 简单来 ...
- 参考MySQL Internals手册,使用Golang写一个简单解析binlog的程序
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. MySQL作为最流行的开源关系型数据库,有大量的拥趸.其生态已经相当完善,各项特性在圈内都有大量研究.每次新特性发布,都会 ...
- demo工程的清单文件及activity中api代码简单示例
第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...
- python argparse模块解析命令行选项简单使用
argparse模块的解析命令行选项简单使用 util.py #!/usr/bin/env python # coding=utf-8 import argparse parser = argpars ...
- 基于DOM的XSS注入漏洞简单解析
基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21
随机推荐
- cocos3 Shader的CCProgram模板详解
这段内容描述的是一个 着色器(Shader) 的基本结构模板,可能用于一种自定义的着色器语言或框架(例如基于某种图形渲染引擎或中间表示语言扩展的着色器定义方式).以下是逐部分解析其含义: 1. CCP ...
- react项目vite报错:UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??='
问题: vite报错:UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??=' 今天clone一个vite的项目,安装 ...
- 【记录】smartctl|Linux如何通过smartctl查看有没有坏的磁盘?以及使用时长、电源周期、故障记录等
smartctl是一个用于监测和分析硬盘健康状态的工具,可以用于检测是否存在坏的磁盘.以下是使用smartctl检查磁盘健康状态的步骤: 安装smartctl软件 在Linux系统中,smartc ...
- 智表ZCELL产品V2.0发版小感
不知不觉,智表从诞生以来已经两年多了,首先感谢各位用户的支持,没有大家的支持,智表这个产品估计早就已经终止了,正是大家的支持和鼓励,智表才一步一步走到了今天.智表最初是从一个简单不能再简单的table ...
- k8s之statefulset控制器
operator: statefulset:有状态副本集 特点 运行在: 1,稳定且唯一的网络标识符 2,稳定且持久的存储 3,有序,平滑地部署和扩展 4,有序,平滑地删除和终止 5,有序的滚动更新 ...
- Django实例(3)-用户连数据库登入系统
App01--->urls.py from django.contrib import adminfrom django.conf.urls import urlfrom app01 impor ...
- C# AggreateException
在 C# 中,AggregateException 是一种特殊类型的异常,它允许在多个异步任务中捕获并组合多个异常.当在一个异步任务中同时执行多个子任务时,如果其中任何一个子任务抛出了异常,那么父任务 ...
- VScode中的自定义模板
1.背景 在用bootstrap框架,写前端代码时,由于每个页面都有固定的模板格式,比如都包含CDN等,所以在每次写代码的时候,都要重复写这些,效率比较低下.幸运的是,VScode中可以编辑各个语言的 ...
- TEA密码与逆向工程
前置信息 TEA系列概述:TEA算法是一种分组密码算法,由剑桥大学计算机实验室的David Wheeler和Roger Needham于1994年发明.它使用64位的明文分组和128位的密钥进行加 ...
- centos安装certbot
一步一步来,官网的教程: yum install snapd systemctl enable --now snapd.socket ln -s /var/lib/snapd/snap /snap s ...