找回密码
 注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

扫一扫,访问微社区

快捷导航
事务所专题-柯南20周年纪念事件簿
搜索
查看: 1212|回复: 1
打印 上一主题 下一主题

把BMP文件转换为EXE文件的通用方法

[复制链接]

杯户中学生

0

主题

0

好友

19

积分

 

升级
46%
帖子
1935
精华
0
积分
19
威望
0
RP
0
金钱
0 柯币
人气
0 ℃
注册时间
2003-11-18
跳转到指定楼层
顶楼
发表于 2004-3-19 23:34:44 |只看该作者 |倒序浏览
目前出现很多别具特色的图像显示程序, 其中一种特
殊的处理功能就是把图像文件如BMP、GIF等文件直接转换
为.EXE可执行文件, 实际上如果了解了图像显示的一般原
理, 即可以轻松的完成这种文件转换功能。下面以显示16
色BMP 图像为例, 编制一个BMP2EXE转换程序。
一、基本原理:完成此操作的基本过程, 就是在图形
文件的头部加上一段具有图像显示能力的程序段, 当运行
合并后的程序时,打开此文件本身,并移动文件指针到图像
数据段,依次读出内容显示即可。所以一个完整的BMP2COM
程序内部, 应该同时具有显示图像功能及合并文件的功能,
其中的合并文件功能负责把其中的显示图像程序段与图像
文件进行合并处理, 而显示图像功能只有在合并后的 EXE
文件运行时才能得到执行。
二、文件指针的调整问题: 当进行图像显示时, 必须
把文件指针移到正确位置,即跳过显示程序段部分,但由于
程序调试时显示程序段长度是不定的, 无法确定具体的数
值,此时可以采取一种动态记录显示程序段的方法,即合并
显程序与图像文件时, 把显示程序长度记录在合并后程序
的未尾, 运行转换后的可执行文件时, 首先从文件尾部读
出显示程序长度, 即可移到正确位置。另外程序的显示模
式号,及屏幕起始坐标等均采用此方法进行保存和读取。
三、程序使用方法:此程序运行时需要携带两个或二
个以上参数, 段如程序名为BMP2EXE.EXE,则命令格式:
BMP2EXE Source Target Mode Row Col
其中Source为原图像文件内容, Target为转换后的目
标文件名, 后缀必须为EXE, MODE为所使用的显示模式,可
为系统支持的任意16色以上图像模式, 用16进制表示,ROW
及COL 为图像在屏幕上的起始坐标值, 以象素为单位, 可
为256 以内的10进制数值, 主要用于调整图像在屏幕上的
具体位置, 其中显示模式及坐标均可省略, 省略时使用系
统的12H 图像模式, 并从屏幕的始端开始显示图像。转换
之后所产生的EXE 文件即可以单独运行, 运行之后即可以
把当前屏幕置为相应的显示模式, 并在指定的位置显示图
像。本文仅演示了16色BMP 图像的显示过程, 可扩充其
中的图像显示过程, 使之可处理真彩色图像或其它格式的
图像文件。

//BMP图像转换为可执行文件
//适用于16色BMP图像文件
#include <dos.h>
#include <dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
void setmod(int videomode);
void putp(int x,int y,int color);
union REGS r;
void main(int argc,char * argv[])
{
struct ffblk f;
register int done;
int gd,gm,cl,wl,ll,kuan,il,iw,row,col;
long prglen;
char cc,vmode,*end;
FILE *exe,*me,*bmp,*fp;
static int color[16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15};
if(argc>1){ //合并文件段
findfirst(argv[0],&f,55); //取文件长度值
prglen=f.ff_fsize;
me=fopen(argv[0],"rb"); //打开相关文件
exe=fopen(argv[2],"wb");
if(exe==NULL){
printf("Target File Open Error!");exit(0);}
bmp=fopen(argv[1],"rb");
if(bmp==NULL){
printf("Source File Open Error!");exit(0);}
while(1){ //读写显示程序
cc=fgetc(me);
if(!feof(me))
fputc(cc,exe);else break; }
while(1){ //读写图像文件
cc=fgetc(bmp);
if(!feof(bmp))
fputc(cc,exe);else break; }
if(argc>3){
cc=strtol(argv[3],&end,16); //写显示模式号
fputc(cc,exe);}else{
cc=0x12;
fputc(cc,exe);}
if(argc>4){ //写起始横坐标
cc=atoi(argv[4]);
fputc(cc,exe); }else{
cc=0;
fputc(cc,exe); }
if(argc>5){ //写起始纵坐标
cc=atoi(argv[5]);
fputc(cc,exe); }else{
cc=0;
fputc(cc,exe); }
r.x.ax=prglen; //写原始文件长度
cc=r.h.ah;
fputc(cc,exe);
cc=r.h.al;
fputc(cc,exe);
cc=0x55; //写文件识别标志
fputc(cc,exe);
fclose(me);
fclose(exe);
fclose(bmp); //关闭相关文件
printf("Please Disp <%s>",argv[2]);
exit(0);}
else //显示文件段
fp=fopen(argv[0],"rb");
findfirst(argv[0],&f,55); //取文件长度值
prglen=f.ff_fsize;
fseek(fp,prglen-1,SEEK_SET);//移文件指针
cc=fgetc(fp);
if(cc!=0x55){ //判断文件标志
printf("\nHELP:\7"); //提示信息
printf("\nBMP2EXE Source Target Mode Row Col.");
exit(0);}else
fseek(fp,prglen-6,SEEK_SET);
vmode=fgetc(fp); //取显示模式
row=fgetc(fp); //取起始横坐标
col=fgetc(fp); //取起始纵坐标
r.h.ah=fgetc(fp); //取文件长度
r.h.al=fgetc(fp);
prglen=r.x.ax; //移到图形数据段
fseek(fp,prglen+18,SEEK_SET);
fread(&kuan,4,1,fp);
wl=kuan; //图像宽度
fread(&kuan,4,1,fp);
ll=kuan; //图像高度
fseek(fp,prglen+118,SEEK_SET);
setmod(vmode); //置显示模式
for(il=0;il<ll;il++) //显示第一遍
for(iw=0;iw<wl;iw++){
fread(&kuan,1,1,fp);
cl=(kuan&0xf0)>>4;
putp(row+iw,col+ll-il,color[cl]);
iw=iw+1;}
fseek(fp,prglen+118,SEEK_SET);
for(il=0;il<ll;il++) //显示第二遍
for(iw=0;iw<wl;iw++){
fread(&kuan,1,1,fp);
iw=iw+1;
cl=kuan&0x0f;
putp(row+iw,col+ll-il,color[cl]);}
getch(); //程序暂停
fclose(fp); //关闭文件
setmod(0x3); } //恢复文本模式
void setmod(int videomode)
{ //置显示模式函数
r.h.ah=0;
r.h.al=videomode;
int86(0x10,&r,&r);}
void putp(int x,int y,int color)
{r.h.al=color; //写点函数
r.h.ah=0x0c;
r.h.bh=0;
r.x.cx=x;
r.x.dx=y;
int86(0x10,&r,&r);}
近期格言: []★☆←↑→↓ 事务所的姑娘都是我的~ ★☆←↑→↓〓[] 传说中的红心是不死的~

杯户中学生

0

主题

0

好友

1

积分

 

升级
0%
帖子
102
精华
0
积分
1
威望
0
RP
0
金钱
0 柯币
人气
2 ℃
注册时间
2004-3-12
沙发
发表于 2004-3-21 14:49:41 |只看该作者

回复:

3qla
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册 新浪微博登陆

手机版|Archiver|名侦探柯南事务所 ( 沪ICP备17027512号 )

GMT+8, 2024-9-24 06:29 , Processed in 0.029738 second(s), 15 queries , MemCached On.

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部