PNG图片详解与加密解密方法

合集下载

像加密使用Photoshop对像进行加密和保护

像加密使用Photoshop对像进行加密和保护

像加密使用Photoshop对像进行加密和保护在信息时代,隐私和数据保护成为了越来越重要的问题。

为了保证个人或机构的隐私不被泄露,各种加密技术得到了广泛的应用。

而在图像领域,Photoshop作为一款广泛使用的图像处理工具,也可以用于对图像进行加密和保护。

本文将介绍如何使用Photoshop对图像进行加密,并提供一些保护图像隐私的建议。

一、加密图像的基本概念加密是指将明文信息通过某种加密算法转化为密文,只有掌握相应密钥的人可以将密文还原为明文。

在加密图像中,我们通常使用某些算法对图像进行像素级别或位级别的转换,从而将图像的内容进行隐藏。

二、使用Photoshop加密图像1. 密码保护在Photoshop中,我们可以为图像设置密码,这样只有输入正确的密码才能打开图像。

具体操作是,打开图像后,点击“文件”菜单,选择“文件信息”,在“描述”栏目中勾选“保护图像”,输入密码并确认即可。

2. 隐藏图层Photoshop中的图像是由多个图层组成的,我们可以选择隐藏某些图层,从而实现对图像内容的保护。

点击图层面板中的眼睛图标,即可隐藏或显示相应的图层。

3. 像素级别加密通过修改像素值,我们可以将图像的内容进行加密。

在Photoshop 中,可以使用“图像”菜单下的“调整”功能,对图像进行像素级别的修改。

例如,可以调整颜色通道、亮度对比度等属性,使图像的真实内容难以辨认。

三、保护图像隐私的建议除了使用加密技术,还有其他一些方法可以帮助保护图像的隐私。

以下是一些建议:1. 不要公开分享高分辨率的图像,尽量缩小图像尺寸和分辨率,以降低图像反向工程的难度。

2. 在社交媒体上分享图片时,最好使用水印工具,可以在图像上添加自己的名字或标识,避免他人盗用。

3. 对于重要的图像,可以考虑使用专业的加密软件进行加密,这些软件通常有更高级的加密算法和功能。

4. 定期备份图像文件,并将备份文件存储在安全的地方,以防止图像丢失或遭到破坏。

png隐写解题思路

png隐写解题思路

PNG隐写解题思路
PNG隐写是指在PNG图像文件中隐藏秘密信息的技术。

下面是一种解题思路:
1.检查文件格式:首先确认所给的图像文件确实是PNG格式的文件。

可以通过查看文件扩展名或使用图像处理软件来确认。

2.分析图像像素数据:PNG图像是由像素组成的。

使用图像处理库或工具,将图像解析为像素矩阵,并获得每个像素的RGB值。

3.检测隐藏信息:在PNG隐写中,隐藏信息通常会修改一些像素的RGB值来嵌入秘密信息。

通过分析像素矩阵,寻找可能的变化或异常。

4.提取隐藏信息:如果发现了可能的隐藏信息,可以根据隐藏信息的嵌入算法来提取出秘密信息。

这可能涉及到像素值的解码、解密或提取过程。

需要注意的是,PNG隐写技术有多种实现方法和工具,每种方法可能具有不同的嵌入和提取算法。

因此,解决PNG隐写问题时,了解所使用的隐写方法和相应的解码算法非常重要。

此外,可以使用专门的隐写分析工具或库来辅助隐写信息的检测和提取。

1/ 1。

图像的加密与解密

图像的加密与解密

图像的加密与解密图像加密与解密图像加密解密使用的是按位异或的运算,一真一假方为真,全真全假皆为假。

比方说,3和5进行按位异或,3的二进制为11,5的二进制为101,运算之后得到二进制110,换算成十进制也就是得到6,那么3、5、6这三个数字,任意两个进行按位异或运算都可以得出另一个。

import cv2import numpy as np#读取图像img = cv2.imread('./lena.jpg')#生成秘钥key = np.random.randint(0,256,img.shape,dtype=np.uint8)#加密secret = cv2.bitwise_xor(img,key)#解密truth = cv2.bitwise_xor(secret,key)#显示图像cv2.imshow('secret',secret)cv2.imshow('truth',truth)cv2.waitKey(0)数字水印嵌入与提取数字水印利用图像的位平面来实现,像素点最高为255,也就是8位二进制表示,每一位可以看成一个位面,高位代表的数字大,低位代表的数字小,整幅图像可以看成是由八个位平面堆叠而成,我们可以把水印图片嵌入到载体图片的最低层位平面。

import cv2import numpy as np#读取原始载体图像lena=cv2.imread("./lena.jpg")#读取水印图像watermark=cv2.imread("./watermark.png",0)#将水印大于0的像素置为1temp = watermark[:,:] > 0watermark[temp] = 1#读取G通道打算将水印嵌入本通道(想把水印藏到哪个通道都随意)g_channel = lena[:,:,1]#保留前7位末位置为0g_channel_1 = np.left_shift(np.right_shift(g_channel,1),1)#嵌入载体图像new_channel = cv2.bitwise_or(g_channel_1,watermark)lena[:,:,1] = new_channel#提取g通道channel = lena[:,:,1]#生成全1数组temp1 = np.ones(channel.shape,dtype=np.uint8)#按位与运算,提取水印water = cv2.bitwise_and(temp1,channel)#将1处理为255w= water[:,:] > 0water[w] = 255#显示嵌入水印的图像cv2.imshow('img',lena)#显示从图像中提取的水印cv2.imshow('water',water)cv2.waitKey()脸部打码与解码脸部打码与解码是使用像素点进行按位运算的综合应用import cv2import numpy as np#读取原始载体图像lena = cv2.imread("./lena.jpg")shape = lena[:,:,0].shape#指定打码区域mask = np.zeros(shape,dtype=np.uint8)mask[220:380,220:350] = 1#获取一个key,打码、解码所使用的密钥key = np.random.randint(0,256,size=shape,dtype=np.uint8)def encode(img):'''脸部打码:param img: 图像:return: 打码图'''key = globals()['key']mask = globals()['mask']# 使用密钥key加密原始图像lena 整幅图被加密xor_img = cv2.bitwise_xor(img, key)# 打码区域的像素置为255 占满八位全1 按位与运算使得打码区域保持原样其他区域全黑and_face = cv2.bitwise_and(xor_img, mask * 255)# 通过反色后按位与运算使脸部区域置为全0 其他区域保持原样no_face = cv2.bitwise_and(img, (1 - mask) * 255)# 两矩阵各像素相加得到脸部打码图像return and_face + no_facedef decode(img):'''脸部解码:param img: 图像:return: 解码图'''key = globals()['key']mask = globals()['mask']# 与秘钥按位异或运算解析出脸部打码区域xor_img = cv2.bitwise_xor(img, key)# 脸部区域保留其他区域置为全黑and_face = cv2.bitwise_and(xor_img, mask * 255)# 打码图的脸部区域置为全黑其他区域不变no_face = cv2.bitwise_and(img, (1 - mask) * 255)# 两矩阵各像素相加得到脸部解码图像return and_face + no_face#脸部打码b_channel = encode(lena[:,:,0])g_channel = encode(lena[:,:,1])r_channel = encode(lena[:,:,2])secret_img = cv2.merge([b_channel,g_channel,r_channel]) cv2.imshow('secret_img',secret_img)#脸部解码b_channel = decode(secret_img[:,:,0])g_channel = decode(secret_img[:,:,1])r_channel = decode(secret_img[:,:,2])true_img = cv2.merge([b_channel,g_channel,r_channel]) cv2.imshow('true_img',true_img)cv2.waitKey()cv2.destroyAllWindows()。

PNG图片详解与加密解密方法.pdf

PNG图片详解与加密解密方法.pdf

PNG图片详解与加密解密方法PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,所以该文件格式又被叫做PNG-8 128仿色。

PNG-24因为其图片容量过大,而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生,有时还会严重拖慢显示速度,故并不常用,CoCoMo认为这些异常和平台底层的图像解压不无关系。

不过该格式最大的优点是可以保存Alpha通道,同事也曾有过利用该图片格式实现Alpha 混合的先例,想来随着技术的发展,手机硬件平台的提升,Alpha混合一定会被广泛的应用,到那时该格式的最大优势才会真正发挥。

?PNG-8文件是目前广泛应用的PNG图像格式,其主要有六大块组成:?1.PNG文件标志,为固定的64个字节:0x89504e47 0x0d0a1a0a ?2.文件头数据块IHDR(header chunk) 3.调色板数据块PLTE(palette chunk) 4.sBIT,tRNS块?等。

5.图像数据块IDAT(image data chunk) 6.图像结束数据IEND(image trailer chunk),固定的96个字节:0x000000000x49454e44 0xae426082 ?这六大块按顺序排列,也就是说IDAT块永远是在PLTE块之后,期间也会有许多其他的区块用来描述信息,例如图像的最后修改时间是多少,图像的创建者是谁等…??数据块1-4:?除了PNG文件标志,其中四大数据块和文件尾都是由统一的数据块文件结构描述的:? Chunk Length: 4byte?Chunk Type: 4byte?Chunk Data: Chunk Length的长度?Chunk CRC: 4byte ?例如IHDR块的数据长度为13,即? Chunk Length = 13 ?Chunk Type ="IHDR"IHDR块:?用来描述图像的基本信息,其格式为:?图像宽: 4byte?图像高: 4byte?图像色深: 4byte?颜色类型: 1byte?压缩方法: 1byte?滤波方法: 1byte?扫描方法: 1bytePLTE块:?这个就是传说中放置调色盘数据的地方啦,其格式为:?循环?RED: 1byte?GREEN:1byte?BLUE: 1byte?END?循环长度嘛,不就是Chunk Length / 3的长度嘛,而且Chunk Length一定为3的倍数。

图像加密方案

图像加密方案

图像加密方案
1. 引言
图像加密是指将图像进行加密处理,使得未经授权的用户无法理解该图像的内容。

图像加密在信息安全中起着重要的作用,可以保护图像中的敏感信息,防止未经授权的传播和使用。

本文将介绍一种基于对称加密算法的图像加密方案,并详细讨论其实现细节。

2. 图像加密方案概述
本图像加密方案基于对称加密算法,使用相同的密钥对图像进行加密和解密。

主要包括以下步骤:
2.1 密钥生成
在图像加密方案中,首先需要生成一个密钥用于加密和解密操作。

可以使用随
机数生成算法生成一个指定长度的密钥。

2.2 图像加密
在图像加密过程中,首先将原始图像转换为二进制数据。

然后使用对称加密算
法对二进制数据进行加密。

加密后的二进制数据将被转换回图像格式,并保存为加密图像。

2.3 图像解密
图像解密的过程与图像加密相反。

首先将加密图像转换为二进制数据。

然后使
用相同的密钥,对二进制数据进行解密。

解密后的二进制数据将被转换回图像格式,并保存为解密后的图像。

3. 对称加密算法选择
在图像加密方案中,选择适合的对称加密算法是十分重要的。

常见的对称加密
算法包括DES、AES等。

需要根据图像的大小和加密速度要求来选择算法。

4. 图像加密方案实现步骤
4.1 读取原始图像
首先,使用相应的图像处理库,读取原始图像并将其保存为二进制数据。

```python import cv2
读取原始图像image = cv2.imread(。

Png图片格式使用技巧!

Png图片格式使用技巧!

Png图片格式使用技巧!图/文白树Png是图像文件存储格式,Png有多少种格式,有哪些特点,PC 端中常用的Png格式是哪些,手机端最合适的Png格式是什么呢?如果你对这些问题有疑问,那么很开心的告诉你,这里有你需要的答案。

PNG的格式和透明度png有3种不同深度的,格式:png8、png24、png32。

其中,在优化面板选择png8,可发现png8包括不透明、索引色透明、alpha透明3种格式。

PNG88位的png最多支持256(2的8次方)种颜色,8位的png其实8支持不透明、索引透明、alpha透明。

PNG24支持2的24次方种颜色,表现为不透明。

PNG32支持2的32次方种颜色,32位是我们最常使用的格式,它是在png在24位的png基础上增加了8位的透明信息,支持不同程度的半透效果。

其实PNG8的3种格式不透明、索引透明、alpha透明,正好把png的所有格式都归类好了:•『png 不透明』格式•『png 索引透明』格式•『png alpha透明』格式•『PNG 不透明』格式说到不透明,就像jpg格式一样,『png 不透明』只能为不透明,代表格式有:『png8 不透明』和『png24』,导出软件有:Photoshop、Fireworks。

不推荐使用『png 不透明』格式,建议用jpg图片来代替它。

可能会有同学会问为什么png24是不透明的,我使用photoshop 导出来的就是png24啊?Png24实际为不透明图片打开photoshop,任意打开一个带透明的psd文件,存储为web 所有格式(ctrl+shift+alt+s),如下面板所示:不勾选透明度单选框,图片的透明背景会被默认的白色填充导出来的png图片深度为24位,图片为不透明,表现跟jpg图片相似如果勾选了透明度(alpha通道),导出深度为32位的透明图片从photoshop存储为web所有格式面板中这样理解,png24深度其实为24位,再勾选上8位的alhpa通道,24+8=32,即『png32』= 『png24+alpha』,这也许是photoshop软件开发者不添加png32位格式的原因,下图为Photoshop存储为web所有格式界面的图片格式选择,并没有png32位的选项~『PNG 索引透明』格式说到索引颜色透明,我们可以了解下什么是索引颜色,『png 索引透明』代表格式有『png8 索引透明』导出软件有:Photoshop、Fireworks,它的特点总结如下:•挑选一副图片中最有代表性的若干种颜色(通常不超过256种)、只能为不透明或全透明、文件体积小、带有杂边锯齿、支持IE6如何使用Photoshop导出『png8 索引透明』使用Photoshop,存储为web所有格式,按照如下图片的红色边框配置,可导出png8索引透明。

png图片结构分析与加密解密原理

png图片结构分析与加密解密原理

png图片结构分析与加密解密原理PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,所以该文件格式又被叫做PNG-8 128仿色。

PNG-24因为其图片容量过大,而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生,有时还会严重拖慢显示速度,故并不常用,CoCoMo认为这些异常和平台底层的图像解压不无关系。

不过该格式最大的优点是可以保存Alpha通道,同事也曾有过利用该图片格式实现Alpha 混合的先例,想来随着技术的发展,手机硬件平台的提升,Alpha混合一定会被广泛的应用,到那时该格式的最大优势才会真正发挥。


8 bit PNGs use an indexed color palette like GIF. If you want variable transparency, use 32bit PNGs (24 bit color, 8 bit alpha). If you don't care about transparency, use 24 bit PNGs.PNG-8文件是目前广泛应用的PNG图像格式,其主要有六大块组成:
1.PNG文件标志,为固定的64个字节:0x89504e47 0x0d0a1a0a
2.文件头数据块IHDR(header chunk)3.调色板数据块PLTE(palette chunk)4.sBIT,tRNS块
等。

5.图像数据块IDAT(image data chunk)6.图像结束数据IEND(image trailer chunk),固定的96个字节:0x00000000 0x49454e44 0xae426082
这六大块按顺序排列,也就是说IDAT块永远是在PLTE块之后,期间也会有许多其他的区块用来描述信息,例如图像的最后修改时间是多少,图像的创建者是谁等,不过这些区块的信息对我们来说都是可有可无的描述信息,故压缩时一般先向这些区块开刀。

图片加密解决方案

图片加密解决方案

图片加密解决方案
我们的电脑中存着许多自己拍的旅游照片、写真照、甚至是“毁形象”的青涩照。

不想让别人看到,就需要做一些加密的措施。

在此介绍几种简单易用的图片加密方法。

一、图片隐藏。

右击图片文件,选择“属性”,然后在下方的属性选框中选择“隐藏”。

即可把图片进行隐藏。

解密:查看隐藏文件即可。

二、图片类型更改。

一般图片的扩展名会是JPG,PNG等,把它更改以后就无法打开。

如图(改成TXT格式后,打开之后就是乱码。


解密:改回图片原有扩展即可。

(上图为把扩展名改成TXT之后打开,文本文档显示乱码的情况。


三、做成压缩包文件。

把文件打包压缩,设置压缩密码,如果不知道密码就无法解压。

解密:要记住密码。

四、使用特定程序加密。

使用可对文件进行加密的程序进行加密,加密后在未被允许的电脑上就无法打开查看。

解密:在自己设备上无法输入密码。

如果文件在未授权设备上要进行授权验证。

科诺斯科专家提醒如利用密码加密时务必记住加密密码,否则会出现自己也无法查看自己密码的情况。

PNG图片格式详解

PNG图片格式详解

PNG图⽚格式详解2-2 PNG图⽚格式详解1. PNG格式⽂件简介PNG(Portable Network Graphics,便携式⽹络图形),是⼀种采⽤⽆损压缩算法的位图格式。

其设计⽬的是试图替代GIF和TIFF⽂件格式,同时增加⼀些GIF⽂件格式所不具备的特性。

⼀般应⽤于JAVA程序、⽹页或S60程序中,原因是它压缩⽐⾼,⽣成⽂件体积⼩。

2. PNG⽂件结构详解PNG图像格式⽂件由以下结构组成:⽂件头/⽂件署名域:⼀个8字节的PNG⽂件署名域(即⽂件头)数据块:按照特定结构组织的3个以上的数据块组成2.1 ⽂件署名域实际上就是PNG⽂件的⽂件头。

PNG⽤8字节的⽂件署名域来识别该⽂件是不是PNG⽂件。

⽂件头/⽂件署名域:89 50 4e 47 0d 0a 1a 0a2.2 数据块2.2.1 数据块结构:PNG⽂件中,每个数据块由4个部分组成,如下:名称字节数说明Length (长度)4字节指定数据块中数据域的长度,其长度不超过(231-1)字节Chunk Type Code (数据块类型码)4字节数据块类型码由ASCII字母(A-Z和a-z)组成Chunk Data (数据块数据)可变长度存储按照Chunk Type Code指定的数据CRC (循环冗余检测)4字节存储⽤来检测是否有错误的循环冗余码2.2.2 数据块类型:PNG定义了两种类型的数据块:⼀种是称为关键数据块(必需的数据块),另⼀种是辅助数据块(可选的数据块)。

关键数据块定义了4个标准数据块,每个PNG⽂件都必须包含它们,PNG读写软件也都必须要⽀持这些数据块。

1. 关键数据块:IHD:⽂件头数据块。

它包含有PNG⽂件中存储的图像数据的基本信息,并要作为第⼀个数据块出现在PNG数据流中,⽽且⼀个PNG数据流中只能有⼀个⽂件头数据块。

PLTE:调⾊板数据块。

对于索引图像来说,调⾊板信息是必须的,它包含有与索引彩⾊图像相关的彩⾊变换数据,⽽且要放在图像数据块IDAT之前。

PNG文件结构分析---Png解析

PNG文件结构分析---Png解析

PNG⽂件结构分析---Png解析为了实现更⾼级的应⽤,我们必须充分挖掘PNG的潜⼒。

PNG的⽂件结构根据PNG⽂件的定义来说,其⽂件头位置总是由位固定的字节来描述的:⼗进制数137 80 78 71 13 10 26 10⼗六进制数89 50 4E 47 0D 0A 1A 0A其中第⼀个字节0x89超出了ASCII字符的范围,这是为了避免某些软件将PNG⽂件当做⽂本⽂件来处理。

⽂件中剩余的部分由3个以上的PNG的数据块(Chunk)按照特定的顺序组成,因此,⼀个标准的PNG⽂件结构应该如下:PNG⽂件标志PNG数据块……PNG数据块PNG数据块(Chunk)PNG定义了两种类型的数据块,⼀种是称为关键数据块(critical chunk),这是标准的数据块,另⼀种叫做辅助数据块(ancillary chunks),这是可选的数据块。

关键数据块定义了4个标准数据块,每个PNG⽂件都必须包含它们,PNG读写软件也都必须要⽀持这些数据块。

虽然PNG ⽂件规范没有要求PNG编译码器对可选数据块进⾏编码和译码,但规范提倡⽀持可选数据块。

下表就是PNG中数据块的类别,其中,关键数据块部分我们使⽤深⾊背景加以区分。

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图像结束数据否否最后⼀个数据块为了简单起见,我们假设在我们使⽤的PNG⽂件中,这4个数据块按以上先后顺序进⾏存储,并且都只出现⼀次。

解析PNG图像文件

解析PNG图像文件

PNG图像文件介绍PNG图像文件格式PNG是可携式网络图像(portable network graphics)的英文缩写。

PNG是从网络上开始发展的,目的是替代GIF和JPG格式,PNG图像文件格式也是当今游戏中常用的图像资源文件格式了。

PNG图像文件支持的图像颜色非常丰富,存储灰度图时可使用16位色深表示,存储真彩色图像时色深更可达到48位之多。

PNG图像文件介绍与BMP格式相比,PNG格式稍微复杂些。

PNG图像支持从0~255级次的多层透明色,使用无损压缩的zlib压缩算法压缩图像数据。

通常使用zlib压缩过的图像文件大小比BMP使用的RLE压缩的效果好,BMP的RLE压缩算法只支持压缩8位以下的图像,对于16位以上的真彩色图像不支持图像压缩,PNG使用的zlib压缩算法支持任何色深的图像数据压缩,压缩后的图像数据可以完整还原,相比之下JPG需要牺牲图像质量使用有损压缩来获得大的压缩率。

最后有一点需要注意,PNG图像格式使用Big-Endian顺序存储数据。

PNG图像文件存储结构(1)PNG文件存储结构的格式可以在/TR/REC-png.htm上找到定义。

BMP文件总体上由两部分组成,分别是PNG文件标志和数据块(chunks),如表5-8所示。

其中数据块分为两类:关键数据块(critical chunk)和辅助数据块(ancillary chunks)。

表5-8 PNG文件的组成结构PNG文件标志数据块(chunks)1.PNG文件标志PNG文件标志由8字节数据组成:89 50 4E 47 0D 0A 1A 0Ah,其中50 4E 47对应的ASCII值是"PNG"。

2.数据块(chunks)紧跟在PNG文件标志后面的数据是数据块(chunks),数据块(chunks)分为两类:关键数据块(critical chunks)和辅助数据块(ancillary chunks)。

图像加密解密算法

图像加密解密算法

中北大学信息商务学院课程设计说明书学生姓名:学号:系别:电子信息工程专业:电子信息工程题目:专业综合实践之多维信息处理部分:图像加密解密算法研究指导教师:赵英亮徐美芳职称: 副教授2016 年 1 月 8 日中北大学信息商务学院课程设计任务书15/16 学年第一学期系别:电子信息工程专业:电子信息工程课程设计题目:专业综合实践之多维信息处理部分:图像加密解密算法研究起迄日期:2015年12月28 日~2016年1月8日课程设计地点:机房指导教师:赵英亮徐美芳系主任:王浩全下达任务书日期: 2015 年12月27 日设计说明书应包括以下主要内容:(1)封面:课程设计题目、班级、姓名、指导教师、时间(2)设计任务书(3)目录(4)设计方案简介(5)设计条件及主要参数表(6)设计主要参数计算(7)设计结果(8)设计评述,设计者对本设计的评述及通过设计的收获体会(9)参考文献目录1 引言 (1)2设计目的 (2)3 设计方案简介 (2)3.1基于像素点置乱算法的图像加密技术 (3)3.2基于行列乱序算法的图像加密技术 (3)3.3基于色彩饱和度混乱算法的图像加密技术 (3)4 设计条件及主要参数表 (3)4.1像素点置乱 (3)4.2行列乱序 (3)4.3色彩饱和度混乱 (3)5设计主要参数计算 (5)6设计结果 (5)7 设计的收获体会 (7)8 参考文献 (7)1 引言随着20世纪90年代internet的迅速发展,多媒体技术的逐渐成熟和电子商务的兴起,网上多媒体信息量急剧膨胀,使得多媒体信息的安全问题变的越来越重要,多媒体信息安全成为学术界和工业界共同关注的新的研究方向。

数字图像是目前最流行的多媒体形式之一,在政治、经济、国防、教育等方面均有广泛应用。

Matlab里的imread函数可用于读取图片文件中的数据。

读进去的数据为一个三层的矩阵,矩阵的行或列表示图像每一个像素点的位置。

矩阵的第一层、第二层、第三层分别代表红、绿、蓝三种像素(RGB色域)。

png图片结构分析与加密解密原理

png图片结构分析与加密解密原理

png图片结构分析与加密解密原理PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,所以该文件格式又被叫做PNG-8 128仿色。

PNG-24因为其图片容量过大,而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生,有时还会严重拖慢显示速度,故并不常用,CoCoMo认为这些异常和平台底层的图像解压不无关系。

不过该格式最大的优点是可以保存Alpha通道,同事也曾有过利用该图片格式实现Alpha 混合的先例,想来随着技术的发展,手机硬件平台的提升,Alpha混合一定会被广泛的应用,到那时该格式的最大优势才会真正发挥。


8 bit PNGs use an indexed color palette like GIF. If you want variable transparency, use 32bit PNGs (24 bit color, 8 bit alpha). If you don't care about transparency, use 24 bit PNGs.PNG-8文件是目前广泛应用的PNG图像格式,其主要有六大块组成:
1.PNG文件标志,为固定的64个字节:0x89504e47 0x0d0a1a0a
2.文件头数据块IHDR(header chunk)3.调色板数据块PLTE(palette chunk)4.sBIT,tRNS块
等。

5.图像数据块IDAT(image data chunk)6.图像结束数据IEND(image trailer chunk),固定的96个字节:0x00000000 0x49454e44 0xae426082
这六大块按顺序排列,也就是说IDAT块永远是在PLTE块之后,期间也会有许多其他的区块用来描述信息,例如图像的最后修改时间是多少,图像的创建者是谁等,不过这些区块的信息对我们来说都是可有可无的描述信息,故压缩时一般先向这些区块开刀。

一种PNG图像的解码方法、装置及系统[发明专利]

一种PNG图像的解码方法、装置及系统[发明专利]

专利名称:一种PNG图像的解码方法、装置及系统专利类型:发明专利
发明人:郭振华
申请号:CN201710362964.4
申请日:20170522
公开号:CN107105266A
公开日:
20170829
专利内容由知识产权出版社提供
摘要:本发明实施例公开了一种PNG图像的解码方法,主机端CPU利用C语言通过对PNG图像的文件格式进行解析获取PNG图像的原始数据;然后调用OpenCL语言将所述原始数据以写缓存的方式写至FPGA板卡;FPGA板卡接收到主机端的解码指令后,采用OpenCL语言,根据预设的解码算法对原始数据进行解码,并对解码后的数据进行解压缩;最后主机端CPU调用OpenCL语言从通过FPGA 板卡中,以读缓存的方式读取解压缩后的数据,从而获取解码后的PNG图像。

提高了图像解码的速率以及吞吐率性能,有利于提高开发效率。

此外,本发明实施例还提供了相应的实现装置及系统,所述装置及系统具有相应的优点。

申请人:郑州云海信息技术有限公司
地址:450018 河南省郑州市郑东新区心怡路278号16层1601室
国籍:CN
代理机构:北京集佳知识产权代理有限公司
代理人:罗满
更多信息请下载全文后查看。

png图片详解与加密解密方法

png图片详解与加密解密方法

png图片详解与加密解密方法PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,所以该文件格式又被叫做PNG-8 128仿色。

PNG-24因为其图片容量过大,而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生,有时还会严重拖慢显示速度,故并不常用,CoCoMo认为这些异常和平台底层的图像解压不无关系。

不过该格式最大的优点是可以保存Alpha通道,同事也曾有过利用该图片格式实现Alpha 混合的先例,想来随着技术的发展,手机硬件平台的提升,Alpha混合一定会被广泛的应用,到那时该格式的最大优势才会真正发挥。


PNG-8文件是目前广泛应用的PNG图像格式,其主要有六大块组成:
1.PNG文件标志,为固定的64个字节:0x89504e47 0x0d0a1a0a 2.文件头数据块IHDR(header chunk) 3.调色板数据块PLTE(palette chunk) 4.sBIT,tRNS块
等。

5.图像数据块IDAT(image data chunk) 6.图像结束数据IEND(image trailer chunk),固定的96个字节:0x00000000 0x49454e44 0xae426082 这六大块按顺序排列,也就是说IDAT块永远是在PLTE块之后,期间也会有许多其他的区块用来描述信息,例如图像的最后修改时间是多少,图像的创建者是谁等… 数据块1-4:
除了PNG文件标志,其中四大数据块和文件尾都是由统一的数据块文件结构描述的:
Chunk Length: 4byte
Chunk Type: 4byte
Chunk Data: Chunk Length的长度
Chunk CRC: 4byte 例如IHDR块的数据长度为13,即 Chunk Length = 13 Chunk Type ="IHDR"IHDR块:
用来描述图像的基本信息,其格式为:
图像宽:4byte
图像高:4byte
图像色深:4byte
颜色类型:1byte
压缩方法:1byte
滤波方法:1byte
扫描方法:1bytePLTE块:
这个就是传说中放置调色盘数据的地方啦,其格式为:
循环
RED:1byte
GREEN:1byte
BLUE:1byte
END
循环长度嘛,不就是Chunk Length / 3的长度嘛,而且Chunk Length一定为3的倍数。

PNG图片数据解析

PNG图片数据解析

PNG图⽚数据解析PNG是⼀种⾮常流⾏的图⽚格式,它不仅⽀持透明效果,⽽且图⽚数据经过了压缩处理,所以⼴泛⽤于web等应⽤。

PNG的⽂件格式: PNG⽂件中的数据,总是以⼀个固定的8个字节开头: 除此之外,PNG的其他数据都是以数据块的⽅式组织,它们被分为标准数据块和辅助数据块,其中的辅助数据块是可选的。

关键数据块包含我们必须的图⽚信息,我们之后要重点解析的也是关键数据块。

每种数据块的结构: Length:该数据块的中Chunk Data的长度; Chunk Type Code:数据类型,就是指上⾯提到的IHDR,IEND等; Chunk Data:数据区域,如果是IDAT,就表⽰存储的还未解压的图⽚数据; CRC:循环冗余效验码;具体实现:(实现中没有处理png数据中变形的情况,部分头中的宏定义来⾃libpng,实例不具备实⽤性,仅作参考)头⽂件:1 #ifndef __PNG__2#define __PNG__34 #include <stdio.h>5 #include <stdlib.h>6 #include <math.h>7 #include "zlib/zlib.h"89/**10 * 类型标志11*/12#define PNG_FLAG_HEX "89504E470D0A1A0A"1314/**15 * 数据块类型16*/17#define DATA_CHUNK_TYPE_IHDR "IHDR"18#define DATA_CHUNK_TYPE_IDAT "IDAT"19#define DATA_CHUNK_TYPE_IEND "IEND"20#define DATA_CHUNK_TYPE_tEXt "tEXt"21#define DATA_CHUNK_TYPE_iTXt "iTXt"2223/**24 * 过滤⽅式25*/26#define DATA_FILTER_TYPE_DEFAULT 027#define DATA_FILTER_TYPE_ADD_ROW 128#define DATA_FILTER_TYPE_ADD_UP 229#define DATA_FILTER_TYPE_AVERGE 330#define DATA_FILTER_TYPE_PAETH 43132/* color type masks */33#define PNG_COLOR_MASK_PALETTE 134#define PNG_COLOR_MASK_COLOR 235#define PNG_COLOR_MASK_ALPHA 43637/* color types. Note that not all combinations are legal */38#define PNG_COLOR_TYPE_GRAY 039#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)40#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)41#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)42#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)4344#define RGB_USE_ALPHA(vr, vg, vb, va) \45 (unsigned)(((unsigned)((unsigned char)(vr) * ((unsigned char)(va) + 1)) >> 8) | \46 ((unsigned)((unsigned char)(vg) * ((unsigned char)(va) + 1) >> 8) << 8) | \47 ((unsigned)((unsigned char)(vb) * ((unsigned char)(va) + 1) >> 8) << 16) | \48 ((unsigned)(unsigned char)(va) << 24))4950/**51 * ⼀次解压图⽚数据的限制52*/53#define DECOMPRESSION_MAX_BYTES 81925455/**56 * 数据块信息57*/58 typedef struct _DataChunkHeader59 {60// 数据长度61 unsigned char length[4];62// 数据类型63 unsigned char type[4];64 } DataChunkHeader;6566/**67 * IHDR数据68*/69 typedef struct _IDHRData70 {71 unsigned char width[4];72 unsigned char height[4];73 unsigned char bitDepth[1];74 unsigned char colorType[1];75 unsigned char compressionMethod[1];76 unsigned char filterMethod[1];77 unsigned char interlaceMethod[1];78 } IDHRData;7980/**81 * PNG图⽚类82*/83class PNG84 {85public:86 PNG();87 PNG(const char* filePath);8889 ~PNG();9091int getWindth();92int getHeight();9394/**95 * 获取图⽚宽度96*/97 unsigned char* getImageData();9899private:100int m_width;101int m_height;102103 unsigned char m_bitDepth;104 unsigned char m_colorType;105 unsigned char m_compressionMethod;106 unsigned char m_filterMethod;107 unsigned char m_interlaceMethod;108 unsigned char m_chanels;109110 unsigned char* m_imageData;111112/**113 * 从⽂件加载图⽚数据114*/115bool loadImageDataFromFile(const char* filePath);116117/**118 * 解析数值119*/120int parseNumber(const unsigned char* data, int len);121122/**123 * 解压数据124*/125int decompressData(z_stream* zStream, unsigned char* data, int dataLen, int leftLen, FILE *pFile); 126127/**128 * ⽣成图⽚数据129*/130void generateImageData(unsigned char* data, unsigned long dataLen);131132/**133 * 默认的过滤⽅式134*/135void defaultFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);136137/**138 * 当前⾏相加的过滤⽅式139*/140void addCurrentRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes); 141142/**143 * 前⼀⾏相加的过滤⽅式144*/145void addUpRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes); 146147/**148 * 平均的过滤⽅式149*/150void avergeFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);151152/**153 * paeth的过滤⽅式154*/155void paethFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);156157/**158 * 解析IHDR数据159*/160void parseIHDRData(DataChunkHeader& dataChunkHeader, FILE* pFile);161162/**163 * 解析IDAT数据164*/165void parseIDATData(DataChunkHeader& dataChunkHeader, FILE* pFile);166167/**168 * 解析IEND数据169*/170void parseIENDData(DataChunkHeader& dataChunkHeader, FILE *pFile);171172/**173 * 解析其他数据174*/175void parseCommonData(DataChunkHeader& dataChunkHeader, FILE *pFile);176 };177178#endifcpp⽂件:1 #include "png.h"2 #include "utils/cUtil.h"3 #include <stdlib.h>45 #include <windows.h>67/**8 * 默认构造函数9*/10 PNG::PNG()11 {12this->m_width = 0;13this->m_height = 0;1415this->m_imageData = 0;16 }1718/**19 * 构造函数20 * @param filePath 图⽚路径21*/22 PNG::PNG(const char *filePath)23 {24this->m_width = 0;25this->m_height = 0;2627this->loadImageDataFromFile(filePath);28 }2930/**31 * 析构函数32*/33 PNG::~PNG()34 {353738/**39 * 从⽂件加载图⽚数据40*/41bool PNG::loadImageDataFromFile(const char* filePath)42 {43 FILE* pFile = fopen(filePath, "rb");44if (!pFile)45return false;4647// 解析PNG标志48char flag[8];49char hexFlag[17];50 fread(flag, 1, 8, pFile);51 toHexStr(flag, 8, hexFlag);52if (strcmp(hexFlag, PNG_FLAG_HEX) != 0)53return false;5455// 解析图⽚数据56 DataChunkHeader dataChunkHeader;57char dataChunkHeaderType[5];58do {59 fread(&dataChunkHeader, 1, sizeof(DataChunkHeader), pFile);6061 memcpy(dataChunkHeaderType, dataChunkHeader.type, 4);62 dataChunkHeaderType[4] = '\0';6364// IHDR65if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IHDR) == 0 ) {66this->parseIHDRData(dataChunkHeader, pFile);67 }68// IDAT69else if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IDAT) == 0 ) { 70this->parseIDATData(dataChunkHeader, pFile);71 }72// IEND73else if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IEND) == 0 ) { 74this->parseIENDData(dataChunkHeader, pFile);75 }76// 其他数据77else {78this->parseCommonData(dataChunkHeader, pFile);79 }80 } while( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IEND) != 0 );8182int i = 1;8384return true;85 }8687/**88 * 解析数值89*/90int PNG::parseNumber(const unsigned char* data, int len)91 {92char localNum[4];9394bool isLittleEndian = checkEndian();95for (int i = 0; i<4; i++) {96char ch;9798if (isLittleEndian) {99if (i <= len-1)100 ch = data[len - 1 - i];101else102 ch = '\0';103 }104else {105if (i <= len-1)106 ch = data[i];107else108 ch = '\0';109 }110 localNum[i] = ch;111 }112113int num;114 memcpy(&num, localNum, 4);115return num;116 }117118/**119 * 解析IHDR数据121void PNG::parseIHDRData(DataChunkHeader& dataChunkHeader, FILE* pFile)122 {123int dataLen = this->parseNumber(dataChunkHeader.length, 4);124125 IDHRData idhrData;126char crc[4];127128 fread(&idhrData, 1, sizeof(IDHRData), pFile);129 fread(crc, 1, 4, pFile);130131this->m_width = this->parseNumber(idhrData.width, 4);132this->m_height = this->parseNumber(idhrData.height, 4);133this->m_bitDepth = this->parseNumber(idhrData.bitDepth, 1);134this->m_colorType = this->parseNumber(idhrData.colorType, 1);135this->m_compressionMethod = this->parseNumber(pressionMethod, 1);136this->m_filterMethod = this->parseNumber(idhrData.filterMethod, 1);137this->m_interlaceMethod = this->parseNumber(idhrData.interlaceMethod, 1);138this->m_chanels = 0;139140switch (this->m_colorType) {141case PNG_COLOR_TYPE_GRAY:142case PNG_COLOR_TYPE_PALETTE:143this->m_chanels = 1;144break;145case PNG_COLOR_TYPE_RGB:146this->m_chanels = 3;147break;148case PNG_COLOR_TYPE_GRAY_ALPHA:149this->m_chanels = 2;150break;151case PNG_COLOR_TYPE_RGB_ALPHA:152this->m_chanels = 4;153break;154default:155this->m_chanels = 0;156break;157 }158 }159160/**161 * 解压数据162*/163int PNG::decompressData(z_stream* zStream, unsigned char* data, int dataLen, int leftLen, FILE *pFile) 164 {165int result = 0;166167int leftBytesCount = leftLen;168int avail_out = -1;169do {170if (zStream->avail_in == 0) {171if (avail_out == 0)172break;173else {174if (leftBytesCount == 0) {175 DataChunkHeader dataChunkHeader;176 fread(&dataChunkHeader, 1, sizeof(DataChunkHeader), pFile);177178int newDataLen = this->parseNumber(dataChunkHeader.length, 4);179 unsigned char* newData = new unsigned char[dataLen + newDataLen];180char crc[4];181182 fread(newData + dataLen, 1, newDataLen, pFile);183 fread(crc, 1, 4, pFile);184 memcpy(newData, data, dataLen);185186 delete data;187 data = newData;188189 zStream->next_in = newData + dataLen;190 zStream->avail_in = newDataLen;191192 dataLen = dataLen + newDataLen;193194return this->decompressData(zStream, data, dataLen, 0, pFile);195 }196 }197198// 导出数据是否超过限制199if (leftBytesCount > DECOMPRESSION_MAX_BYTES)200 zStream->avail_in = DECOMPRESSION_MAX_BYTES;201else202 zStream->avail_in = leftBytesCount;203204 leftBytesCount -= zStream->avail_in;205 }206207if (avail_out > 0)208 zStream->avail_out = avail_out;209else210 zStream->avail_out = m_width * 4 + 1;211212 result = inflate(zStream, Z_NO_FLUSH);213if (result != Z_OK)214break;215216 avail_out = zStream->avail_out;217 } while (zStream->avail_in >= 0);218219return result;220 }221222/**223 * ⽣成图⽚数据224*/225void PNG::generateImageData(unsigned char* data, unsigned long dataLen) 226 {227// ⾏字节数228int rowBytes = this->m_chanels * this->m_width;229230// 初始化图⽚数据231this->m_imageData = new unsigned char[rowBytes * this->m_height];232233 unsigned char* pImageData = this->m_imageData;234 unsigned char* pRowData = data;235236for (int rowIndex = 0; rowIndex < this->m_height; rowIndex++) {237// 过滤类型238 unsigned char filterType = pRowData[0];239240 pRowData += 1;241242switch (filterType) {243// 不需要过滤处理244case DATA_FILTER_TYPE_DEFAULT:245this->defaultFilterType(pImageData, pRowData, rowBytes);246break;247// 当前⾏相加248case DATA_FILTER_TYPE_ADD_ROW:249this->addCurrentRowFilterType(pImageData, pRowData, rowBytes); 250break;251// 和前⼀⾏相加252case DATA_FILTER_TYPE_ADD_UP:253this->addUpRowFilterType(pImageData, pRowData, rowBytes); 254break;255// 求平均256case DATA_FILTER_TYPE_AVERGE:257this->avergeFilterType(pImageData, pRowData, rowBytes);258break;259// Paeth260case DATA_FILTER_TYPE_PAETH:261this->paethFilterType(pImageData, pRowData, rowBytes);262break;263// 类型错误264default:265break;266 }267268 pImageData += rowBytes;269 pRowData += rowBytes;270271char text[100];272 sprintf(text, "filter type:%d, rowIndex:%d \n", filterType, rowIndex);273 OutputDebugString(text);274 }275276int channel = rowBytes / this->m_width;277if (channel == 4) {278 unsigned int *tmp = (unsigned int *)this->m_imageData;279280for (unsigned short i = 0; i < this->m_height; i++) {281for (unsigned int j = 0; j < rowBytes; j+=4) {282 unsigned int offset = i * rowBytes + j;283284 *tmp++ = RGB_USE_ALPHA(285this->m_imageData[offset],286this->m_imageData[offset+1],287this->m_imageData[offset+2],288this->m_imageData[offset+3]289 );290 }291 }292 }293 }294295/**296 * 默认的过滤⽅式297*/298void PNG::defaultFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)299 {300for (int i = 0; i < rowBytes; i++) {301 *pImageData++ = *pRowData++;302 }303 }304305/**306 * 当前⾏相加的过滤⽅式307*/308void PNG::addCurrentRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes) 309 {310for (int i = 0; i < rowBytes; i++) {311if (i == 0) {312 memcpy(pImageData, pRowData, 4);313 i += 3;314 pImageData += 4;315 pRowData += 4;316 }317else {318 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-4)) & 0xFF);319 }320 }321 }322323/**324 * 前⼀⾏相加的过滤⽅式325*/326void PNG::addUpRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes) 327 {328for (int i = 0; i < rowBytes; i++) {329 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-rowBytes)) & 0xFF);330 }331 }332333/**334 * 平均的过滤⽅式335*/336void PNG::avergeFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)337 {338for (int i = 0; i < rowBytes; i++) {339int averge = 0;340341if (i <= 3) {342 averge = ((int)*(pImageData-rowBytes)) / 2;343344 *pImageData++ = (unsigned char)((averge + (int)*(pRowData++)) & 0xFF);345 }346else {347 averge = (((int)*(pImageData-4)) + ((int)*(pImageData-rowBytes))) / 2;348349 *pImageData++ = (unsigned char)((averge + (int)*(pRowData++)) & 0xFF);350 }351 }352 }353354/**355 * paeth的过滤⽅式356*/357int Paeth(int a, int b, int c)358 {359int p = a + b - c;360int pa = abs(p - a);361int pb = abs(p - b);362int pc = abs(p - c);363364int Paeth;365if(pa <= pb && pa <= pc)366 Paeth = a;367else if (pb <= pc)368 Paeth = b;369else370 Paeth = c;371return Paeth ;372 }373void PNG::paethFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)374 {375for (int i = 0; i < rowBytes; i++) {376if (i <= 3) {377 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-rowBytes)) & 0xFF); 378 }379else {380 unsigned char left = *(pImageData - 4);381 unsigned char up = *(pImageData - rowBytes);382 unsigned char leftUp = *(pImageData - rowBytes - 4);383384int value = Paeth((int)left, (int)up, (int)leftUp);385386 *pImageData++ = (unsigned char)(((int)*(pRowData++) + value) & 0xFF);387 }388 }389 }390391/**392 * 解析IDAT数据393*/394void PNG::parseIDATData(DataChunkHeader& dataChunkHeader, FILE* pFile)395 {396// 解压后的图⽚数据397 unsigned char* imageData = new unsigned char[m_width * m_height * 4];398399int dataLen = this->parseNumber(dataChunkHeader.length, 4);400// 解压前的图⽚数据401 unsigned char* data = new unsigned char[dataLen];402char crc[4];403// 提取数据404 fread(data, 1, dataLen, pFile);405 fread(crc, 1, 4, pFile);406407// 存放临时的解压数据408 unsigned long decompressDataLen = m_width * m_height * 4 + m_height;409 unsigned char* decompressData = new unsigned char[decompressDataLen];410411 z_stream* zStream = new z_stream();412 zStream->next_in = data;413 zStream->next_out = decompressData;414415 inflateInit(zStream);416417// 解压数据418this->decompressData(zStream, data, dataLen, dataLen, pFile);419// ⽣成图⽚数据420this->generateImageData(decompressData, decompressDataLen);421422/*423 int result = 0;424 // 开始解压数据425 int leftBytesCount = dataLen;426 int avail_out = -1;427 do {428 if (zStream->avail_in == 0) {429 if (avail_out == 0)430 break;431 else {432 if (leftBytesCount == 0) {433434 }435 }436437 // 导出数据是否超过限制438 if (leftBytesCount > DECOMPRESSION_MAX_BYTES)439 zStream->avail_in = DECOMPRESSION_MAX_BYTES;440 else441 zStream->avail_in = leftBytesCount;442443 leftBytesCount = dataLen - zStream->avail_in;444 }445446 if (avail_out > 0)447 zStream->avail_out = avail_out;448 else449 zStream->avail_out = m_width * 4 + 1;450451 result = inflate(zStream, Z_NO_FLUSH);452 if (result != Z_OK)453 break;454455 avail_out = zStream->avail_out;456 } while (zStream->avail_in >= 0);457 // 数据解压是否成功458 if (result == Z_STREAM_END) {459 int i = 1;460 }461*/462 }463464/**465 * 解析IEND数据466*/467void PNG::parseIENDData(DataChunkHeader& dataChunkHeader, FILE *pFile)468 {469char crc[4];470 fread(crc, 1, 4, pFile);471 }472473/**474 * 解析其他数据475*/476void PNG::parseCommonData(DataChunkHeader& dataChunkHeader, FILE *pFile)477 {478int dataLen = this->parseNumber(dataChunkHeader.length, 4);479 fseek(pFile, dataLen + 4, SEEK_CUR);480 }481482/**483 * 获取图⽚宽度484*/485 unsigned char* PNG::getImageData()486 {487return this->m_imageData;488 }489490/**491 * 获取图⽚宽度492*/493int PNG::getWindth()494 {495return this->m_width;496 }497498/**499 * 获取图⽚⾼度500*/501int PNG::getHeight()502 {503return this->m_height;504 }如果需要绘制图⽚,可以使⽤opengl库参考代码:1 glViewport(0, 0, winWidth, winHeight);23 glMatrixMode(GL_PROJECTION);4 glLoadIdentity();5 glOrtho(0.0f, winWidth - 1.0, 0.0, winHeight - 1.0, -10.0, 10.0);67 glMatrixMode(GL_MODELVIEW);8 glLoadIdentity();910 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1112 glEnable(GL_TEXTURE_2D);1314int width = png->getWindth();15int height = png->getHeight();16 unsigned char* data = png->getImageData();1718 GLuint name1;19 glGenTextures(1, &name1);20 glBindTexture(GL_TEXTURE_2D, name1);21 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);22 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);23 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);24 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);25 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,GL_RGBA, GL_UNSIGNED_BYTE, data);26 glBegin(GL_POLYGON);27 glTexCoord2f(1, 1);28 glVertex3d(800, 800, 2);29 glTexCoord2f(0, 1);30 glVertex3d(0, 800, 2);31 glTexCoord2f(0, 0);32 glVertex3d(0, 0, 2);33 glTexCoord2f(1, 0);34 glVertex3d(800, 0, 2);35 glEnd();。

图像处理技术的图像加密与数字水印技巧分享

图像处理技术的图像加密与数字水印技巧分享

图像处理技术的图像加密与数字水印技巧分享图像加密和数字水印是图像处理技术中重要的领域,在保护图像隐私和版权方面具有重要的应用。

本文将分享图像加密和数字水印的一些常见技巧和方法。

图像加密是一种保护图像内容安全的技术,主要目的是通过对图像进行加密处理,使得未经授权的人无法获得图像的具体内容。

图像加密的方法有很多种,其中较为常见和有效的方法包括对称加密和非对称加密。

对称加密是指加密和解密所使用的密钥是相同的,常见的对称加密算法有DES、AES等。

这些算法通过对图像的每个像素进行位运算或混合运算,使得图像的像素值发生改变,从而达到加密的效果。

对称加密算法的优点是加密解密速度快,但缺点是密钥的传输需要保证安全。

非对称加密是指加密和解密使用的密钥是不同的,常见的非对称加密算法有RSA、DSA等。

这些算法使用两个密钥,公钥用于加密,私钥用于解密。

图像加密过程中,使用公钥对图像进行加密,只有拥有私钥的人才能解密。

非对称加密算法的优点是密钥安全性高,但缺点是加密解密速度较慢。

数字水印是指在图像中嵌入一些特定的信息,以证明图像的所有权和完整性。

数字水印可以分为可见水印和不可见水印两种。

可见水印是在图像的可见部分嵌入特定的信息,例如作者的名字或标志。

可见水印可以通过调整嵌入信息的透明度和位置,使得水印与图像融为一体,从而保护图像的版权。

可见水印的优点是易于嵌入和提取,但缺点是有可能影响图像的视觉感受。

不可见水印是在图像的不可见部分嵌入特定的信息,例如版权信息和访问控制信息。

不可见水印的嵌入过程需要考虑到对图像视觉质量的影响,并且需要保证嵌入信息的不可逆性和鲁棒性。

不可见水印的优点是不影响图像的视觉感受,但缺点是提取水印的过程相对较复杂。

除了加密和水印技术外,还可以通过图像压缩和加密的结合来提高图像的安全性。

基于压缩的加密技术将图像分为不同的区块,然后对每个区块进行压缩和加密,从而达到更好的保护图像的目的。

总之,图像加密和数字水印技术在图像处理领域中具有重要的应用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PNG图片详解与加密解密方法
PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,所以该文件格式又被叫做PNG-8 128仿色。

PNG-24因为其图片容量过大,而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生,有时还会严重拖慢显示速度,故并不常用,CoCoMo 认为这些异常和平台底层的图像解压不无关系。

不过该格式最大的优点是可以保存Alpha
通道,同事也曾有过利用该图片格式实现Alpha 混合的先例,想来随着技术的发展,手机硬件平台的提升,Alpha混合一定会被广泛的应用,到那时该格式的最大优势才会真正发挥。


PNG-8文件是目前广泛应用的PNG图像格式,其主要有六大块组成:
1.PNG文件标志,为固定的64个字节:0x89504e47 0x0d0a1a0a 2.文件头数据块IHDR(header chunk) 3.调色板数据块PLTE(palette chunk) 4.sBIT,tRNS块
等。

5.图像数据块IDAT(image data chunk) 6.图像结束数据IEND(image trailer chunk),固定的96个字节:0x00000000 0x49454e44
0xae426082 这六大块按顺序排列,也就是说IDAT块永远是在PLTE块之后,期间也会有许多其他的区块用来描述信息,例如图像的最后修改时间是多少,图像的创建者是谁等… 数据块1-4:

除了PNG文件标志,其中四大数据块和文件尾都是由统一的数据块文件结构描述的:
Chunk Length: 4byte

Chunk Type: 4byte

Chunk Data: Chunk Length的长度

Chunk CRC: 4byte 例如IHDR块的数据长度为13,即
Chunk Length = 13
Chunk Type ="IHDR"
IHDR块:

用来描述图像的基本信息,其格式为:

图像宽:4byte

图像高:4byte

图像色深:4byte

颜色类型:1byte

压缩方法:1byte

滤波方法:1byte

扫描方法:1byte
PLTE块:
这个就是传说中放置调色盘数据的地方啦,其格式为:

循环

RED:1byte

GREEN:1byte

BLUE:1byte

END

循环长度嘛,不就是Chunk Length / 3的长度嘛,而且Chunk Length一定为3的倍数。

tRNS块:
这个块时有时无,主要是看你是否使用了透明色。

该区块的格式为:

循环

if(对应调色盘颜色非透明)

0xFF:1byte

else

0x00:1byte

END

循环长度为调色盘的颜色数,相当于调色盘颜色表的一个对应表,标识该颜色是否透明,0xFF不透明,0x00透明。

故如果用UltraEdit查看PNG文件的二进制编码,如果看到一大片FF,一般就是tRNS区块啦,因为一个PNG文件一般只有一个透明色。



IDAT块:

这个就是存放图像数据的地方啦,这里要注意的是一个PNG文件可能有多个IDAT区块,而其他三大区块只可能有一个。


IDAT 区块是经过压缩的,所以数据不可读,压缩算法一般为LZ77滑动窗口算法,如果硬要看里面的数据的话,用zlib库也可以看
IEND块:

该区块虽然也按照数据块的结构,但Chunk Data是没有的,所以是固定的96个字节:
0x00000000
0x49454e44
0xae426082
IEND数据块的长度总是0(00 00 00 00,除非人为加入信息),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82。

PNG图像压缩:
了解了PNG的文件结构,压缩就有的放矢了。

压缩有6个级别,可以根据需要选择。

Level1:读取PNG文件,将除六大块之外的所有区块都过滤掉
Level2:文件头是固定的0x89504e47 0x0d0a1a0a,文件尾是固定的0x00000000 0x49454e44 0xae426082,去掉!
Level3:每个区块的Chunk Type我们是否需要呢?很明显,我们自己写的压缩格式自己应该清楚是按照什么样的顺序,去掉!
Level4:每个区块的Chunk Length我们是否需要呢?
IHDR块:定长13个字节,明显不需要,去掉。

PLTE块:最多128个颜色,为撒要用4byte来记录区块长度而不是用1byte来记录颜色数呢?
tRNS块:既然有颜色数,tRNS又是调色盘颜色表的对应表,既数量与颜色数相同,为什么还需要呢?
IDAT块:我想这个是唯一需要4byte来记录长度的区块。

Level5:每个区块的Chunk CRC 是否需要呢?
因为计算CRC需要一些时间,但对于字节较少的区块一般可以忽略不计,所以对于这个问题还是由程序员自己决定吧。

对于CRC的计算可以参看CoCoMo的另一篇Blog“PNG文件的CRC码计算”
Level6:每个区块我们是否要原封不动的保存期数据呢?
IHDR块:除了宽、高、色深是需要的,后面那4byte的信息是固定的0x03000000 PLTE块:为撒要用3byte来表示RGB而不是2byte的565格式?压缩方法可以参看CoCoMo的另一篇Blog“关于PNG图像压缩的一点感悟” tRNS块:我想tRNS块是冗余最多的区块了吧,大段大段的0xFF明显没有必要,一般的PNG文件只有一个透明色,为撒要用对应表的方法而不是一个索引来记录到底哪个是透明色呢?由于颜色数最多128,所以只需1byte就可以代替tRNS那么多0xFF啦。

PNG图像加解密:
很多人都担心自己辛苦创作的漂亮的美术图片很easy就被别人拿到了,究其原因是由于
PNG文件格式是固定的,稍微了解的人用UltraEdit很容易就能找到IHDR,PLTE等标识了。

CoCoMo就经常看GameLoft的图像文件,一般是2byte的Length,然后紧接着图片数据,都放在一个文件里,直接拷贝2进制然后粘贴到一个新文件里就是一幅图。

后来的加密技术会把PNG分块,例如前100个字节一块,紧接着1K一块,最后剩余字节一块,然后把块顺序打乱,用2byte来记录总长度,1byte记录顺序,但是这并没有从根本上消除IHDR,IEND 这些显眼的定位标识,好像在对破解者说:嘿,看,我就在这里!
现在了解了之前的压缩和解压技术,这个问题也就迎刃而解了,因为Chunk Length,Chunk Type和Chunk CRC这些东西都消失了,甚至连数据块本身的数据都修改了,我可以按照ImageWidth、ImageHeight、ImageDepth的顺序写数据,也可以倒过来写。

我想再牛的PNG 分析器也是无能为力的吧,唯一可以定位的就只有IDAT区块了,不过就算得到该区块的数据,也应该是一张黑白图。

相关文档
最新文档