技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 259|回复: 1
收起左侧

【VB.NET】解析恋活人物卡PNG文件

[复制链接]

52

主题

153

帖子

8265

积分

用户组: 超级版主

OS与VM研究学者

UID
1043
精华
30
威望
404 点
宅币
6460 个
贡献
694 次
宅之契约
0 份
在线时间
1551 小时
注册时间
2015-8-15
发表于 2022-3-20 14:40:16 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x

前言

不知道有没有玩过恋活人发现,人物卡是一个PNG图片文件,而这个图片文件里虽然表面上是证件照,但它还包含了人物照以及捏脸数据。
写本文的目的就是解释恋活的PNG文件是什么样的。

PNG文件结构

PNG的文件结构算是简单的,就两个部分:PNG签名(Signature)和PNG块(Chunks)。

PNG签名长度为8个字节。

Public Const PngSignature As Long = &HA1A0A0D474E5089

第一个字节是0x89,最高位是置位的以防止被当做文本文件打开
第2-4字节对应字母是PNG。
第5-6字节是CRLF换行。
第7字节是EOF。
第8字节是LF换行。

每个PNG块按顺序分四部分:块大小,块类型,块数据,块CRC。
除了块数据之外,每个成员均为4字节。
PNG文件不讲究文件对齐,所有数据均紧凑排列。
块大小和块CRC字段均为大端序,因此在x86的电脑上要逆字节序使用。
块类型为4字节字符串。
第一个字符的大小写决定它是否是重要的块。若为大写,则该块是重要的块。
第二个字符的大小写决定它是否是标准的块。若为小写,则该快是私有定义的块。
第三个字符按照PNG标准,必须是大写。
第四个字符的大小写决定它是否与重要的块相关。若为大写,则当有重要的块被修改时,该块不能被直接复制使用。

通常而言,一个PNG文件里必然会有IHDRIDATIEND三个块。其中IHDR必须是第一个块,IEND必须是最后一个块。

IHDR块

IHDR块表示PNG文件头,只有13个字节,定义如下:

Public Structure PngChunkIHdr
    Dim Width As Integer
    Dim Height As Integer
    Dim BitDepth As Byte
    Dim ColorType As Byte
    Dim CompressionMethod As Byte
    Dim FilterMethod As Byte
    Dim InterlaceMethod As Byte
End Structure

其中Width表示图片横向的像素单位长度,Height表示图片纵向的像素单位长度,ColorType表示像素类型。
注意WidthHeight也都是大端序的。
像素类型的值的各类定义为:

Public Enum PngPixelFormat
    Grayscale = 0
    TrueColorRGB = 2
    IndexedPalette = 3
    GrayscaleAlpha = 4
    RGBA = 6
End Enum

IEND块

IEND块表示PNG文件尾,没有块数据。遍历块到此时应当结束遍历。

IDAT块

IDAT块表示图片数据。一个PNG文件里可以有好几个IDAT块来表示一个图片。
PNG使用DEFLATE无损压缩算法,因此IDAT块里的数据必须解压后再用。
.NET的DeflateStream似乎不能解压PNG的IDAT块,且由于PictureBox控件能显示PNG文件,我没必要舍本逐末地自行把PNG解析成位图后再显示出来。

恋活的PNG文件

我最初的猜想是恋活的PNG文件里塞了一个私有的块,而经过解析后验证,并没有什么私有的块,它是在IEND块之后追加内容的。
根据多次测试,人物照应该在IEND块的34字节之后。它的结构同样是个PNG文件。
中间的34字节应该是恋活的签名(可以看见KoiKatuCharaS字样)。
而在人物照的IEND块之后的就是具体的捏脸数据了。本文不作深入解析了。

程序源码

本文采用Visual Basic 2010进行WinForm开发,在GitHub上开源

评分

参与人数 1威望 +10 宅币 +30 贡献 +10 收起 理由
0xAA55 + 10 + 30 + 10 屌!

查看全部评分

flowers for Broken spirits - a woman turned into stake will hold the world in the basin of fire.
回复

使用道具 举报

1093

主题

2645

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
238
威望
506 点
宅币
21997 个
贡献
45977 次
宅之契约
0 份
在线时间
2110 小时
注册时间
2014-1-26
发表于 2022-4-6 03:22:56 | 显示全部楼层
竟然在PNG里加自己的块。

另外如果能修改这些PNG的话,就可以给它汉化一波。

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2022-5-21 17:19 , Processed in 0.038530 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表