码迷,mamicode.com
首页 > 其他好文 > 详细

日式冒险游戏《巫女小镜大冒险》PIC 图片转 BMP 图片

时间:2015-12-20 19:31:08      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:

-----------------------------------------------------------------------------

!!警告!!

游戏资源所有权,归游戏开发商所有

以下转换算法与代码,仅供学习交流使用,请勿用于非法或商业用途

由此引起的一切后果,与博主(我)无关

-----------------------------------------------------------------------------

这游戏的资源本身没有被打包,直接就可以看到所有的资源文件,唯独有一种后缀名为 PIC 的图片经过特殊处理,其余都是游戏数值数据文件,音频文件直接就可以用,所以这次针对 PIC 文件做分析;

废话不多说,PIC 文件与 BMP 文件有着几乎一模一样的文件头,用下面结构体可以直接一次性读取 PIC 文件信息:

 1 struct PIC_INFO {
 2     char sig[ 4 ]; // ‘PIC ‘
 3     char u1[ 14 ]; // all 00
 4     int image_width;
 5     int image_height;
 6     short u2; // 1
 7     short bit_per_pixel; // 24
 8     int u3; // 00 00 00 00
 9     int u4; // 00 00 00 00
10     int u5; // 12 0B 00 00
11     int u6; // 12 0B 00 00
12     int u7; // 00 00 00 00
13     int u8; // 00 00 00 00
14 };

还是老规矩,以 u 开头的数据成员依旧没有摸清楚具体用途,虽然基本上已经确认与 BMP 的 BITMAPINFOHEADER 有着一一对应的意义;

文件开头是 4 个字节的签名,该值永远为 ‘PIC ‘,随后是图片的宽度和高度,以及每像素占多少个字节(也就是色深 bit per pixel ),然后根据色深来确认是否包含调色板数据,8 位色深的 PIC 包含一个大小为 RGBQUAD 乘以 256 个字节的调色板数据,24 位色深 PIC 不包含调色板数据,随后就是像素自身的颜色数值;

下面代码直接将一个 PIC 图片转换成一张 BMP 图片:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <Windows.h>
 4 
 5 #pragma pack( push, 2 )
 6 struct PIC_INFO {
 7     char sig[ 4 ]; // ‘PIC ‘
 8     char u1[ 14 ]; // all 00
 9     int image_width;
10     int image_height;
11     short u2; // 1
12     short bit_per_pixel; // 24
13     int u3; // 00 00 00 00
14     int u4; // 00 00 00 00
15     int u5; // 12 0B 00 00
16     int u6; // 12 0B 00 00
17     int u7; // 00 00 00 00
18     int u8; // 00 00 00 00
19 };
20 #pragma pack( pop )
21 
22 const char * buildBMPFileNameFromPicFileName( const char * _pic_name ){
23     static char file_name[ 256 ] = { 0 };
24     memset( file_name, 0, sizeof( file_name ) );
25     unsigned int len = strlen( _pic_name );
26     strcpy_s( file_name, sizeof( file_name ), _pic_name );
27     for( unsigned int i = len; i >= 0; -- i ){
28         if( . == file_name[ i ] ){
29             file_name[ i ] = \0;
30             strcat_s( file_name, sizeof( file_name ), ".bmp" );
31             break;
32         }
33     }
34     return ( const char * ) file_name;
35 }
36 
37 void convertPICtoBMP( const char * _pic_name ){
38     FILE * pic_file = nullptr;
39     FILE * bmp_file = nullptr;
40     char bmp_file_name[ 256 ] = { 0 };
41     BITMAPFILEHEADER bfh = { 0 };
42     BITMAPINFOHEADER bih = { 0 };
43     DWORD pixel_data_size = 0;
44     BYTE * pixel_data_ptr = nullptr;
45     RGBQUAD palette[ 256 ] = { 0 };
46 
47     // read PIC info
48     PIC_INFO info = { 0 };
49     fopen_s( & pic_file, _pic_name, "rb" );
50     fread( & info, 1, sizeof( PIC_INFO ), pic_file );
51     printf( "[ %4d x %4d ] bpp %2d %s \n",
52         info.image_width,
53         info.image_height,
54         info.bit_per_pixel,
55         _pic_name );
56     if( 8 == info.bit_per_pixel ){
57         fread( palette, 1, sizeof( palette ), pic_file );
58     }
59 
60     // read PIC pixel data
61     pixel_data_size = ( info.image_height * info.image_width * info.bit_per_pixel / 8 );
62     pixel_data_ptr = new BYTE[ pixel_data_size ];
63     fread( pixel_data_ptr, 1, pixel_data_size, pic_file );
64 
65     // build BMP file
66     strcpy_s( bmp_file_name, sizeof( bmp_file_name ),
67         buildBMPFileNameFromPicFileName( _pic_name ) );
68     fopen_s( & bmp_file, bmp_file_name, "wb" );
69 
70     bfh.bfSize = sizeof( bfh );
71     bfh.bfOffBits = sizeof( bfh ) + sizeof( bih );
72     bfh.bfType = 0x4D42;
73 
74     bih.biSize = sizeof( bih );
75     bih.biBitCount = info.bit_per_pixel;
76     bih.biCompression = BI_RGB;
77     bih.biPlanes = 1;
78     bih.biWidth = info.image_width;
79     bih.biHeight = info.image_height;
80 
81     fwrite( & bfh, 1, sizeof( bfh ), bmp_file );
82     fwrite( & bih, 1, sizeof( bih ), bmp_file );
83 
84     // write pixel data to BMP file
85     if( 8 == info.bit_per_pixel ){
86         fwrite( palette, 1, sizeof( palette ), bmp_file );
87     }
88     fwrite( pixel_data_ptr, 1, pixel_data_size, bmp_file );
89 
90     fclose( pic_file );
91     fclose( bmp_file );
92     delete [ ] pixel_data_ptr;
93 }
94 
95 int main( int argc, char * argv[ ] ){
96     convertPICtoBMP( "aka.PIC" );
97     convertPICtoBMP( "abura.PIC" );
98     return 0;
99 }

 

上面代码中,convertPICtoBMP( ) 函数把一张 PIC 图片转换成一张 BMP 图片,buildBMPFileNameFromPicFileName( ) 函数则将文件的 PIC 后缀名改成 BMP 后缀名;

最后展示一下转换好的 BMP 图片:

技术分享

 

技术分享

 

日式冒险游戏《巫女小镜大冒险》PIC 图片转 BMP 图片

标签:

原文地址:http://www.cnblogs.com/gamedes/p/5061478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!