Chinaunix首页 | 论坛 | 博客
  • 博客访问: 531459
  • 博文数量: 401
  • 博客积分: 244
  • 博客等级: 入伍新兵
  • 技术积分: 2215
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-04 10:02
文章分类

全部博文(401)

文章存档

2013年(37)

2012年(364)

分类:

2013-01-04 10:41:35

文件头数据块IHDR(header chunk) – 用于获取图片的宽度、高度、深度等基本信息!

IHDR

文件头数据块

否

否

第一块

域的名称

字节数

说明

Width

4 bytes

图像宽度,以像素为单位

Height

4 bytes

图像高度,以像素为单位

Bit depth

1 byte

图像深度: 
索引彩色图像:1,2,4或8 
灰度图像:1,2,4,8或16 
真彩色图像:8或16

ColorType

1 byte

颜色类型:
0
:灰度图像, 1,2,4,8或16 
2
:真彩色图像,8或16 
3
:索引彩色图像,1,2,4或8 
4
:带α通道数据的灰度图像,8或16 
6
:带α通道数据的真彩色图像,8或16

Compression method

1 byte

压缩方法(LZ77派生算法)

Filter method

1 byte

滤波器方法

Interlace method

1 byte

隔行扫描方法:
0
:非隔行扫描 
1
: Adam7(由Adam M. Costello开发的7遍隔行扫描方法)

针对以上信息,分析图片十六进制数据中对应信息(ASCII表 e表示扩展字符):

我将mypic.png图片在ubuntu下用hexdump –C > mypic.txt导入到了mypic.txt中,便于查看和分析!直接在windows下打开的话,很多都不正常显示。

粘出前5行:

00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|

00000010  00 00 00 80 00 00 00 80  08 06 00 00 00 c3 3e 61  |..............>a|

00000020  cb 00 00 20 00 49 44 41  54 78 9c ec bd 77 bc 64  |... .IDATx...w.d|

00000030  45 99 ff ff ae aa 73 3a  f7 cd f7 4e 60 66 18 18  |E.....s:...N`f..|

00000040  24 08 8a 92 4c 28 18 70  d5 45 01 23 66 d7 b0 e6  |$...L(.p.E.#f...|

00000050  65 17 31 ed ea ee ca ba  eb d7 35 eb ca ee cf c5  |e.1.......5.....|

00000060  35 20 2a 22 82 a8 08 82  02 92 04 19 82 64 66 98  |5 *".........df.|

 

PNG文件的标识

00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|

<对应>    e  P N G 回车 换行 替换 .                I  H D R

PNG文件的宽度(4 bytes)和高度(4 bytes) – 128 * 128(像素)

00000010  00 00 00 80 00 00 00 80  08 06 00 00 00 c3 3e 61  |..............>a|

                     128        128     2^16 = 32 06:带α通道数据的真彩色图像,8或16

00 c3 3e 61 CRC校验

 

后面的就是一些其他信息,我只需要获取宽度和高度等信息,所以其他的略过,分析都是类似的,如果需要改变颜色,可以试着往后分析,直接去改,这样省去了其他麻烦的修改方式!后面试着改变下颜色,所以分析下调色板:

00000030  45 99 ff ff ae aa 73 3a  f7 cd f7 4e 60 66 18 18  |E.....s:...N`f..|

00000040  24 08 8a 92 4c 28 18 70  d5 45 01 23 66 d7 b0 e6  |$...L(.p.E.#f...|

00000050  65 17 31 ed ea ee ca ba  eb d7 35 eb ca ee cf c5  |e.1.......5.....|

00000060  35 20 2a 22 82 a8 08 82  02 92 04 19 82 64 66 98  |5 *".........df.|

 

 

PNG文件格式中的数据块

数据块符号

数据块名称

多数据块

可选否

位置限制

IHDR

文件头数据块

否

否

第一块

cHRM

基色和白色点数据块

否

是

在PLTE和IDAT之前

gAMA

图像γ数据块

否

是

在PLTE和IDAT之前

sBIT

样本有效位数据块

否

是

在PLTE和IDAT之前

PLTE

调色板数据块

否

是

在IDAT之前

bKGD

背景颜色数据块

否

是

在PLTE之后IDAT之前

hIST

图像直方图数据块

否

是

在PLTE之后IDAT之前

tRNS

图像透明数据块

否

是

在PLTE之后IDAT之前

oFFs

(专用公共数据块)

否

是

在IDAT之前

pHYs

物理像素尺寸数据块

否

是

在IDAT之前

sCAL

(专用公共数据块)

否

是

在IDAT之前

IDAT

图像数据块

是

否

与其他IDAT连续

tIME

图像最后修改时间数据块

否

是

无限制

tEXt

文本信息数据块

是

是

无限制

zTXt

压缩文本数据块

是

是

无限制

fRAc

(专用公共数据块)

是

是

无限制

gIFg

(专用公共数据块)

是

是

无限制

gIFt

(专用公共数据块)

是

是

无限制

gIFx

(专用公共数据块)

是

是

无限制

IEND

图像结束数据

否

否

最后一个数据块

 

这样我只需要读取00000010开始的8个字节就可以获取图片宽度和高度了!

开始吧….

/// < png图片信息

typedef struct _PNGImg

{

    uint16_t wd;    /// < png图片的宽度  - png图片最大支持256,uint16_t足够了!

    uint16_t hg;    /// < png图片的高度 - png图片最大支持256,uint16_t足够了!

}PNGImg;

/**

 * @brief 获取png图片信息 (接口公司封装,和标准有差别)

 */

PNGImg * pngimggetInfo(const char * pImg)

{

    PNGImg * pPNGImg = NULL;

    File * pf = NULL;

   

    unsigned char wtmp[4]={'0'};   /// < 文件宽度

 unsigned char htmp[4]={'0'};   /// < 文件高度

  

    if (!pImg)                  /// < 参数为空,直接返回

        return NULL;

    if (!fexist(pImg))          /// < 文件不存在,直接返回

        return NULL;

   

    pf = fopen(pImg, OFM_READ); /// < 自定义的!ó "r"

    if (!pf)

        return NULL;

   

    pPNGImg = (PNGImg *)malloc(sizeof(PNGImg));

    if (!pPNGImg)

    {

        fclose(pf);

        return NULL;

    }

       

    fseek(pf,FST_START, 16L);   /// < 自定义的!ó SEEK_SET

    fread(pf, wtmp, 4);         /// < example 00000080

    fread(pf, htmp, 4);         /// < example 00000080           

    fclose(pf);

   

    pPNGImg->wd = ((int)(unsigned char)wtmp[2]) * 256 + (int)(unsigned char)wtmp[3];

    pPNGImg->hg = ((int)(unsigned char)htmp[2]) * 256 + (int)(unsigned char)htmp[3];

   

    return pPNGImg;

}

阅读(3228) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~