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
随机推荐
- 配置Thymeleaf模板引擎
1).thymeleaf-starter: 关闭缓存 2).静态资源都放在static文件夹下就可以按照路径直接访问 3).页面放在templates下,直接访问 springboot ,访问项目的时 ...
- Asp.net mvc基础(八)Layout页面的使用
Layout页面相当于母版页. 使用步骤如下: 1.创建MVC5布局页 @RenderBody()渲染正文部分 @ViewBag.Title表示标题内容 也可以自己定义渲染的部分:比如在布局页中添加@ ...
- MySQL 中 `LIMIT 100000000, 10` 和 `LIMIT 10` 的执行速度是否相同?
在MySQL中,LIMIT 100000000, 10和LIMIT 10的执行速度通常不会相同.它们的差异在于如何处理数据的检索. LIMIT 10: LIMIT 10表示从查询结果中获取前10条记录 ...
- Java 原生异步编程与Spring 异步编程 详解
简介 Java 异步编程是现代高性能应用开发的核心技术之一,它允许程序在执行耗时操作(如网络请求.文件 IO)时不必阻塞主线程,从而提高系统吞吐量和响应性. 异步 vs 同步 同步:任务按顺序执行,后 ...
- 鸿蒙 NEXT (一)初识鸿蒙
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- RPC实战与核心原理之业务分组
业务分组:如何隔离流量 回顾 RPC 中常用的保护手段"熔断限流" 熔断是调用方为了避免在调用过程中,服务提供方出现问题的时候,自身资源被耗尽的一种保护行为: 而限流则是服务提供方 ...
- RPC的通信流程
核心原理:能否画张图解释下RPC的通信流程? RPC的全称是Remote Procedure Call,即远程过程调用.RPC帮助我们屏蔽网络编程细节,实现调用远程方法跟调用本地(同一个项目中的方法) ...
- Tomcat启动信息乱码
异常描述:大概看到这个鬼样子-- 打开tomcat解压后文件: conf -> logging.properties 右键,选择以记事本或其他方式打开(只要能修改文件内容的软件都OK) 找到 j ...
- 电脑上多个git账户并且为不同仓库设置不同的用户名
说明 生成多个公钥命令 我这里以Gitee和我公司内网Gitlab举例,打开git bash (右键,Git Bash Here) 首先生成Gitee的 依次执行以下命令 git config --g ...
- qt激光加工软件开发——介绍
20年毕业后,先是从事qt+c++开发,而后从事mfc开发,今年步入新的公司,着手开发一版新的激光设备加工软件 激光加工软件所具备的功能: 轴的控制:主要包括XYZ三个轴,品牌:ACS.固高.Gali ...