/////////////////////////////////////////////////////////////
//源文件名:logobar.c
//作者:易华卫
//编写日期:2004年6月
//开发环境:DJGPP2+ALLEGRO3
//用途:用一个图文件生成Windows9x启动动画LOGO文件
//命令行说明:
//LOGOBAR 源图像 [/选项]
//源图像 是一个您已经设计好的图像文件,格式可以是BMP,PCX,LBM,TGA,BTW,
//最好是Windows标准的BMP格式,图像的尺寸可以是320X400,色彩数
//为256。也可是其他值,程序可以自动转换成320X400X256。
//选项:
///TO=LOGO文件 将加了动画条的图像保存成LOGO文件,缺省值为LOGO.SYS。你可以使
//用选项“/TO=C:\LOGO.SYS”来直接安装。
///PO=BOTTON|TOP|LEFT|RIGHT|MASK[-]n 添加动画条的位置,缺省值为:BOTTON
//BOTTON 在图像下方添加动画条,类似Windows9x自带方式
//TOP 在图像上方添加动画条
//LEFT 在图像左侧添加动画条
//RIGHT 在图像右侧添加动画条
//MASK[-]n 在图像中指定为蒙板区域按指定规则绘制动画条(见“高级选项”)
///BC=n 动画条使用的色彩数,缺省值为20
///C1=色彩1 渐变色的起始色,以16进制表示RGB, 缺省值为 00FF00 (绿色)
///C2=色彩2 渐变色的结束色,以16进制表示RGB, 缺省值为 000000 (黑色)
///NP 不预览 /MT- 使用微软的另一种动画方式(不推荐)
//高级选项:
///PO=MASK[-]n 在图像中指定为蒙板区域按指定规则绘制动画条,约定图像的左上角
//(0,0)像素点的颜色为蒙板色,图中所有以该色填充的区域构成蒙板区
//域,在蒙板区域中根据n值有7种方式来绘制色条动画。
//n=1 从左向右画竖色条,动画效果为色条向右运动
//n=2 从上向下画横色条,动画效果为色条向下运动
//n=3 从左上向右下画//形色条,动画效果为色条向右下运动
//n=4 从右上向左下画\\形色条,动画效果为色条向左下运动
//n=5 从中心向四周画辐射色,动画效果如风车顺时针转动
//n=6 从中心向四周画同心椭圆,动画效果为椭圆由小变大
//n=7 从中心向四周画同心矩形,动画效果为矩形由小变大
//如果你在n前使用了“-”,那动画的运动方向将和上面相反。
//详细说明见 logobar_cn.txt
/////////////////////////////////////////////////////////////
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include "allegro.h"
#define AT_BOTTON0
#define AT_TOP1
#define AT_LEFT2
#define AT_RIGHT3
#define AT_MASK4
#define FILL_H1 //Left - right
#define FILL_V2 //top - botton
#define FILL_LTRB3 //left_top - right_botton
#define FILL_RTLB4 //right_top - left_botton
#define FILL_ROTATE5 //rotate right/left
#define FILL_CIRCLE6 //Circle center to outer
#define FILL_RECT7 //Rectange
#define FILL_END7
//globe variable
char srcfile[256]="\0",tagfile[256]="LOGO.SYS";
int barcolors=20; //motion logo used colors
int motiontype=0; //MS';s mode of pallete motion
int position=AT_BOTTON; //Add bar here
int fillmode=FILL_H; //Bar color filled mode
int colordirect=0; //0=L-R/U-D/turn right, 1=R-L/D-U/turn left
int maskcolor=0;
RGB startcolor={0,255,0},endcolor={0,0,0};
int nopreview=0;
char cmd_msg[]=
"Yisir';s WIN9x LOGO.SYS animate bar maker V1.0beta, 2004-6-25, Tianmen Hubei\n"
"Usage: LOGOBAR srcfile [/option]\n"
"\tsrcfile A image file(*.BMP,*.PCX,*.LBM,*.TGA)."
"BTW, the Windows LOGO is 320*200 256 colors BMP file, but don';t worry, "
"I will convert it for you.\n"
"Option:\n"
"\t/TO=filename Save TO a bitmap file, default=LOGO.SYS.\n"
"\t You can use /TO=C:\\LOGO.SYS to install it now.\n"
"\t/PO=BOTTON|TOP|LEFT|RIGHT|MASK[-]n position of colorbar, default:BOTTON\n"
"\t/BC=n color number of bar\n"
"\t/C1=color1 Gradient start color, default: 00FF00 (green)\n"
"\t/C2=color2 Gradient end color, default: 000000 (black)\n"
"\t/NP No preview /MT- use other Windows animate Type\n";
// "Press any key to see more options...\n";
char more_msg[]=
"Advanced options:"
"/PO=MASK[-]n use the color of top-left point as mask, with 7 fill mode\n"
"\tn=1 from left to right in mask area\n"
"\tn=2 from top to botton in mask area\n"
"\tn=3 from top-left to botton-right in mask area\n"
"\tn=4 from top-right to botton-left in mask area\n"
"\tn=5 windmill rotate in mask area\n"
"\tn=6 circle from center to outer in mask area\n"
"\tn=7 rectangle from center to outer in mask area\n"
"\tIf you use \"-\" , it will be filled with the contrary direction.\n"
"This is a freeware, welcome to visit my site http://yisir.9126.com to find more."
"Thank you for testing it, and I wish you like it."
;
char yisir_info[]=
"made by Yisir';s LOGOBAR, welcome to visit http://yisir.9126.com";
int htoi(char *hex);
int adject_pallete(BITMAP *bmp, RGB *pal);
int gen_barcolor(RGB *pal);
int preview(BITMAP *bmp, RGB *bmppal);
int makelogobar(void);
int init_argv(int argc, char* argv[]);
main(int argc, char* argv[])
{
allegro_init();
install_keyboard();
if (!init_argv(argc,argv))
{
printf("source file is %s, target file is: %s\n",srcfile,tagfile);
makelogobar();
}
allegro_exit();
return 0;
}
//convert hex string to integer
int htoi(char *hex)
{
int v=0;
char *p;
for(p=hex;*p;p++)
{
if (*p>=';0';&&*p<=';9';)
{
v*=16;
v+=*p-';0';;
}
else if (*p>=';A';&&*p<=';F';)
{
v*=16;
v+=*p-';A';+10;
}
else break;
}
return v;
}
//将源图像中的实际用色移到调色板的前端
int adject_pallete(BITMAP *bmp, RGB *pal)
{
int i,colorcounter,ips,ipt,x,y;
struct cpal_struct
{
int used;
int newidx;
} cpal[256];
PALLETE tmp;
//caculate color counter
printf("Adject color pallete, please wait a while.\n");
for (i=0;i<256;i++)
{
cpal.used=0;
cpal.newidx=0;
}
for (i=0;i<bmp->h;i++)
{
int x;
for (x=0;x<bmp->w;x++)
{
cpal[bmp->line[x]].used++;
}
}
for (i=0,colorcounter=0;i<256;i++)
colorcounter+=(cpal.used?1:0);
printf("Used color number: %d\nNow pallete is being sorted...",colorcounter);
//Move maskcolor to the fisrt item in pallete
if (position==AT_MASK)
{
maskcolor=bmp->line[0][0];
bmp->line[0][0]=bmp->line[0][1];
cpal[maskcolor].newidx=0;
cpal[maskcolor].used=0;
maskcolor=0;
}
//the first color will be used to display background, so it is black.
tmp[0].r=0;
tmp[0].g=0;
tmp[0].b=0;
//adject, sort color, move used color to begin space.
ips=0;
ipt=1;
while (ips<256)
{
if (cpal[ips].used)
{
cpal[ips].newidx=ipt;
tmp[ipt]=pal[ips];
ipt++;
}
ips++;
}
//write new color index in picture
for (y=0;y<bmp->h;y++)
{
for (x=0;x<bmp->w;x++)
{
int t;
t=bmp->line[y][x];
bmp->line[y][x]=cpal[t].newidx;
}
}
//write picture pallete
for (i=0;i<256;i++)
pal=tmp;
printf(" Finished.\n");
return colorcounter;
}
//生成COLORBAR所用的渐变色
int gen_barcolor(RGB *pal)
{
//green
int i; //single color has 6 bits.
float dr,dg,db;
dr=(0.0+endcolor.r-startcolor.r)/barcolors*2;
dg=(0.0+endcolor.g-startcolor.g)/barcolors*2;
db=(0.0+endcolor.b-startcolor.b)/barcolors*2;
for (i=0;i<barcolors/2;i++)
{
pal[256-barcolors+i].r=pal[255-i].r=(startcolor.r+dr*i)/4;
pal[256-barcolors+i].g=pal[255-i].g=(startcolor.g+dg*i)/4;
pal[256-barcolors+i].b=pal[255-i].b=(startcolor.b+db*i)/4;
}
return 0;
}
//preview logo animater
int preview(BITMAP *bmp, RGB *bmppal)
{
PALLETE pal;
int i;
printf("\nPress any key to preview...\n");
while (!keypressed());
readkey();
for (i=0;i<256;i++)
pal=bmppal;
set_color_depth(8);
i=set_gfx_mode(GFX_MODEX,320,400,0,0);
/* Checks if any error occured during screen mode initialization */
if ( i != 0 )
{
printf("Error setting graphics mode\n%s\n\n", allegro_error);
/* Shut down Allegro */
/*allegro_exit ();*/
return 1;
}
set_palette(pal);
blit(bmp,screen,0,0,0,0,bmp->w,bmp->h);
textout_centre(screen,font,"Press any key to end...",160,370,255-barcolors/2);
while (!keypressed())
{
RGB tmp;
tmp=pal[256-barcolors];
for (i=256-barcolors;i<255;i++)
pal=pal[i+1];
pal[255]=tmp;
set_palette_range(pal,256-barcolors,255,1);
delay(200);
}
set_gfx_mode(GFX_TEXT,640,480,0,0);
return 0;
}
//主要程序
//在图像上加上色条并做成MS要求的格式
int makelogobar(void)
{
BITMAP *filebmp,*bmp;
PALLETE pal;
int i;
FILE *fp;
unsigned char *buf;
//Load image from file.
set_color_depth(8);
set_color_conversion(COLORCONV_REDUCE_TO_256);
filebmp=load_bitmap(srcfile,pal);
if (!filebmp)
{
allegro_exit();
printf("Error loading %s!\n", srcfile);
exit(1);
}
bmp=create_bitmap_ex(8,320,400);
stretch_blit(filebmp, bmp, 0,0, filebmp->w,filebmp->h, 0,0, 320,400);
destroy_bitmap(filebmp);
//caculate color counter
adject_pallete(bmp,pal);
printf("StartColor:%02X%02X%02X, EndColor:%02X%02X%02X", startcolor.r,startcolor.g,
startcolor.b, endcolor.r,endcolor.g,endcolor.b);
printf("\nNow add color bar...\n");
gen_barcolor(pal);
switch(position)
{
BITMAP *mask_bmp;
case AT_BOTTON: //Bar at bottom of screen
for (i=0;i<barcolors;i++)
{
rectfill(bmp,bmp->w*i/barcolors,bmp->h-10, (i+1)*bmp->w/barcolors-1,bmp->h-1,
colordirect?256-barcolors+i:255-i);
}
break;
case AT_TOP: //Bar at top of screen
for (i=0;i<barcolors;i++)
{
rectfill(bmp,i*bmp->w/barcolors,0, (i+1)*bmp->w/barcolors-1,9,
colordirect?256-barcolors+i:255-i);
}
break;
case AT_LEFT: //Bar at left of screen
for (i=0;i<barcolors;i++)
{
rectfill(bmp, 0, i*bmp->h/barcolors,9, (i+1)*bmp->h/barcolors-1,
colordirect?256-barcolors+i:255-i);
}
break;
case AT_RIGHT: //Bar at left of screen
for (i=0;i<barcolors;i++)
{
rectfill(bmp,bmp->w-10,i*bmp->h/barcolors, bmp->w-1,(i+1)*bmp->h/barcolors-1,
colordirect?256-barcolors+i:255-i);
}
break;
case AT_MASK:
mask_bmp=create_bitmap_ex(8,320,400);
//rectfill(mask_bmp,0,0,319,399,0);
switch (fillmode)
{
int ix,iy;
case FILL_H:
for (i=0;i<barcolors;i++)
{
int c=colordirect?256-barcolors+i:255-i;
rectfill(mask_bmp,mask_bmp->w*i/barcolors,0, (i+1)*mask_bmp->w/barcolors-1,mask_bmp->
h-1,c);
}
break;
case FILL_V:
for (i=0;i<barcolors;i++)
{
int c=colordirect?256-barcolors+i:255-i;
rectfill(mask_bmp,0,mask_bmp->h*i/barcolors, mask_bmp->w-1,(i+1)*mask_bmp->
h/barcolors-1,c);
}
break;
case FILL_LTRB:
for (i=0;i<barcolors;i++)
{
int ii;
int c=colordirect?256-barcolors+i:255-i;
for (iy=i*(mask_bmp->h+mask_bmp->w)/barcolors;iy<(i+1)*(mask_bmp->h+mask_bmp->
w)/barcolors;iy++)
{
line(mask_bmp,0,iy,iy,0,c);
}
}
break;
case FILL_RTLB:
for (i=0;i<barcolors;i++)
{
int c=colordirect?256-barcolors+i:255-i;
int ii;
for (iy=i*(mask_bmp->h+mask_bmp->w)/barcolors;iy<(i+1)*(mask_bmp->h+mask_bmp->
w)/barcolors;iy++)
{
line(mask_bmp,mask_bmp->w-iy,0,mask_bmp->w,iy,c);
}
}
break;
case FILL_ROTATE:
{
rectfill(mask_bmp,0,0,mask_bmp->w-1,mask_bmp->h-1,255);
for (i=0;i<barcolors;i++)
{
int x1,y1,x2,y2;
int c=colordirect?256-barcolors+i:255-i;
x1=bmp->w/2+bmp->h/2*cos(i*2*PI/barcolors);
y1=bmp->h/2+bmp->h*sin(i*2*PI/barcolors);
x2=bmp->w/2+bmp->h/2*cos((i+1)*2*PI/barcolors);
y2=bmp->h/2+bmp->h*sin((i+1)*2*PI/barcolors);
triangle(mask_bmp,mask_bmp->w/2,mask_bmp->h/2,x1,y1,x2,y2,c);
}
}
break;
case FILL_CIRCLE:
case FILL_RECT:
{
rectfill(mask_bmp,0,0,mask_bmp->w-1,mask_bmp->h-1,255);
for (i=0;i<barcolors;i++)
{
int c=colordirect?255-i:256-barcolors+i;
int r=sqrt(mask_bmp->w*mask_bmp->w+mask_bmp->h*mask_bmp->
h)/2*(barcolors-i)/barcolors;
if (fillmode==FILL_CIRCLE)
ellipsefill(mask_bmp,mask_bmp->w/2,mask_bmp->h/2,r,r,c);
else if (fillmode==FILL_RECT)
rectfill(mask_bmp,mask_bmp->w/2-r,mask_bmp->h/2-r,mask_bmp->w/2+r,mask_bmp->h/2+r,
c);
}
}
break;
} //end switch(fillmode)
draw_sprite(mask_bmp,bmp,0,0);
destroy_bitmap(bmp);
bmp=mask_bmp;
break;
}
//preview
if (!nopreview)
preview(bmp,pal);
//Save to new file: LOGO.SYS
i=save_bmp(tagfile,bmp,pal);
if (i)
{
destroy_bitmap(bmp);
allegro_exit();
printf("Error write to %s\n",tagfile);
exit(2);
}
//Modify used color index
fp=fopen(tagfile,"rb");
i=filelength(fileno(fp));
buf=(unsigned char*) malloc(i);
fread(buf,1,i,fp);
fclose(fp);
buf[0x32]=256-barcolors;
buf[0x33]=motiontype;
fp=fopen(tagfile,"wb");
fwrite(buf,1,i,fp);
fwrite(yisir_info,1,strlen(yisir_info),fp);
fclose(fp);
free(buf);
printf("Success write to %s\n",tagfile);
destroy_bitmap(bmp);
return 0;
}
//Read and do command options
//处理命令行参数
int init_argv(int argc, char* argv[])
{
if (argc==1)
{
printf("%s",cmd_msg);
printf("%s",more_msg);
return -1;
}
else
{
int i;
for (i=1;i<argc;i++)
{
if (argv[0]!=';/'; && argv[0]!=';-';)
{
strcpy(srcfile,argv);
}else
{
char para[256],*p;
strcpy(para,argv);
for (p=para;*p;p++)
*p=toupper(*p);
if (!strncmp(para+1,"TO=",3))
{
strcpy(tagfile,argv+4);
} else if (!strncmp(para+1,"PO=",3))
{
if (!strcmp(para+4,"BOTTON"))
position=AT_BOTTON;
else if (!strcmp(para+4,"TOP"))
position=AT_TOP;
else if (!strcmp(para+4,"LEFT"))
position=AT_LEFT;
else if (!strcmp(para+4,"RIGHT"))
position=AT_RIGHT;
else if (!strncmp(para+4,"MASK",4))
{
position=AT_MASK;
colordirect=(para[8]==';-';?1:0);
fillmode=abs(atoi(para+8));
if (fillmode<=0 || fillmode>FILL_END)
fillmode=FILL_H;
}
} else if (!strncmp(para+1,"BC=",3))
{
barcolors=atoi(para+4);
} else if (!strncmp(para+1,"MT-",3))
{
motiontype=1;
} else if (!strncmp(para+1,"C1=",3))
{
int c=htoi(para+4);
startcolor.r = c>>16 & 0xff;
startcolor.g = c>>8 & 0xff;
startcolor.b = c & 0xff;
} else if (!strncmp(para+1,"C2=",3))
{
int c=htoi(para+4);
endcolor.r = c>>16 & 0xff;
endcolor.g = c>>8 & 0xff;
endcolor.b = c & 0xff;
} else if (!strncmp(para+1,"NP",2))
{
nopreview=1;
}
}
}
if (srcfile[0]==0)
{
printf("Need srcfile! Run again without any option to display the usage.\n");
return -1;
}
return 0;
} //end if(argc==1)
return 0;
}
下面引用由useronce在 2005/01/27 09:15am 发表的内容:
- 支持楼主的开放、创新的精神!
欢迎光临 无忧启动论坛 (http://bbs.wuyou.net./) | Powered by Discuz! X3.3 |