回 帖 发 新 帖 刷新版面

主题:在作图模式下显示16色PCX图像

请注意:这里说的16色pcx文件的格式是以前最早的pcx格式。现在用acdsee,photoshop等作图工具转换,这个程序不能够显示。为此我花了两三个小时的冤枉时间检查一个本来并没有错误的程序。最后用老掉牙的软件:dos下的alchemy.exe,或者是windows下的photoimpact 3.01转了一下文件,才显示得出来! >_<

如果你要一个pcx文件样本的话我可以寄给你。

因为这个程序也是参考一本老掉牙的书的!原书是用C编的。我偏要用PASCAL来编!因为用pascal来编这种东东的书几乎找不到一本!

这下可惨了,C的指针可以随便乱指,PASCAL语言的指针可没有C那么灵活!仅仅为了定位一个指针,就费了九牛二虎之力。

TURBO PASCAL 7.0,可以提供了下一个640*480*16色的作图模式。缺省定义好了16种颜色。但并不是说就一定要用这16种颜色,你可以自己定义另外的16种颜色来用。但每次调色板里,最多只能有16种颜色。你可以这一次,用这16种颜色,下一次换屏幕显示时,用另外16种颜色。这主要和机器的基本显存有关系。

以前念书时,偷了windows 3.1接龙的扑克牌图案,用显示pcx图像的方法,用C语言做了个扑克牌游戏,让同学们大吃一惊:这些牌的图案你是怎么做出来的?我说:“我一点一点地描出来的!”哈!其实那些牌的图案,全部颜色加起来也不到16种。编起来绰绰有余。

可惜我经常乱删程序,常常把自己编的程序删得一干二净。在这里也要告诉大家:自己编的程序要珍惜噢!不要象我,一个删除把长时间的劳动成果在一秒钟之内删掉。

下面程序,你可以看到改调色板的过程,连汇编语言都出来了。因为我认为调用DOS中断,也其调用函数,还不如直接打汇编语言更简单。

程序在TURBO PASCAL 7.0下通过。

==========================

(*    16 colors PCX file viewer.
      Programmed by j.t.Chang.
*)

program pcx16demo;
uses crt,graph;
type
    paltype=array[0..47] of byte;

    pcxhead=record
        manufac:byte;
        version:byte;
        encoding:byte;
        bits_per_pixel:byte;
        xmin,ymin:integer;
        xmax,ymax:integer;
        hres:integer;
        vres:integer;
        palette:paltype;
        reserved:byte;
        colour_planes:byte;
        bytes_per_line:integer;
        palette_type:integer;
        filler:array[0..57] of byte;
    end;

     pbyte=^byte;

var
   ch      : char;
   pcxhdr  : pcxhead;
   bytes,width,depth,showdepth,size  : word;
   p  : pointer;
   f0 : file of pcxhead;
   f  : file of byte;
   filename  : string;

(*************************************)
procedure init;
var
   gd,gm,ErrCode  : integer;
begin
    gd:=detect;
    initgraph(gd,gm,'');
    ErrCode:=graphresult;
    if  ErrCode<>grOK then
     begin
       Writeln('Graphics error: ', GraphErrorMsg(ErrCode));
       exit;
     end;
end;

(*************************************)
procedure Loadpalette;
var
   t1,t2  : word;
   k      : byte;
begin
    for k:=0 to 15 do
      begin
         asm mov ah,10h
             mov al,0
             mov bh,k
             mov bl,k
             int 10h
         end;
      end;
    for k:=0 to 47 do
       pcxhdr.palette[k]:= pcxhdr.palette[k] shr 2;

    t1:=OFS(pcxhdr.palette);
    t2:=SEG(pcxhdr.palette);

    asm mov ax,1012h
        mov bx,0
        mov cx,16
        mov dx,t1
        mov es,t2
        int 10h
    end;
end;

(*************************************)
procedure RPL(p:Pbyte);
var
   t    : pbyte;
   n, i : integer;
   b,c  : byte;
begin
   n:=0;   t:=p;
   repeat
     read(f,c);
     if (c and $c0) = $c0  then
       begin
           i:=c and $3f;
           read(f,c);
           while i>0 do
            begin
               t^:=c;
               inc(t,1);
               n:=n+1;
               i:=i-1;
            end;
       end
     else
        begin
           t^:=c;
           inc(t,1);
           n:=n+1;
        end;
   until n>=bytes ;
end;

(*************************************)
procedure unpackpcx;
var
   q         : Pbyte;
   i,j,n,st  : integer;
begin
     n:=0;  st:=0;   q:=p;

     q^:=width-1; inc(q,1);
     q^:=(width-1) shr 8; inc(q,1);
     q^:=120; inc(q,1);
     q^:=120 shr 8; inc(q,1);
     for i:=0 to showdepth-1 do
      begin
         j:=pcxhdr.colour_planes;
         j:=j-1; q:=p;
         inc(q,bytes*(n+j)+4);
         RPL(q);
         j:=j-1; q:=p;
         inc(q,bytes*(n+j)+4);
         RPL(q);
         j:=j-1; q:=p;
         inc(q,bytes*(n+j)+4);
         RPL(q);
         j:=j-1; q:=p;
         inc(q,bytes*(n+j)+4);
         RPL(q);
         n:=n+pcxhdr.colour_planes;
         if n>=(120*pcxhdr.colour_planes) then
          begin
              PutImage(0, st*120, P^, NormalPut);
              st:=st+1;
              n:=0;
          end;
      end;
     if (showdepth mod 120<>0) then
       begin
          q:=p;  inc(q,2);
          q^:=showdepth mod 120-1; inc(q,1);
          q^:= (showdepth mod 120-1) shr 8;
          PutImage(0, st*120, P^, NormalPut);
       end;
end;



(*************************************)
begin
     clrscr;
     write('Enter a 16 colors PCX file name:  ');
     readln(filename);
     assign(f0,filename);
     reset(f0);
     read(f0,pcxhdr);
     close(f0);
     if pcxhdr.manufac<>$a then
       begin
         writeln('Not an invalide PCX file.');
         exit;
       end;
     if (pcxhdr.bits_per_pixel<>1) then
        if (pcxhdr.bits_per_pixel<>4) then
          begin
             writeln('Not a 16 colors PCX file.');
             exit;
          end;

     assign(f,filename);
     reset(f);
     seek(f,sizeof(pcxhead));

     width:=pcxhdr.xmax-pcxhdr.xmin+1;
     depth:=pcxhdr.ymax-pcxhdr.ymin+1;
     bytes:=pcxhdr.bytes_per_line;
     if depth>480 then  showdepth:=480
       else showdepth:=depth;
     size:=4;
     size:= 4+size*bytes*120;
     GetMem(P,Size);

     init;

     Loadpalette;
     Unpackpcx;

     close(f);
     ch:=readkey;
     closegraph;
     freemem(p,size);
end.
=======================

回复列表 (共7个回复)

沙发

当之无愧的精华贴

板凳

酷!!!!!!!!!!

3 楼

请问如何用dos下的alchemy.exe获得PCX文件??

4 楼

alchemy是dos下比较早的图形格式查看和转换工具,操作比来当然没acdsee那么方便,不过那时计算机可是刚刚发展啊!
把其它格式的图形(比如BMP、JPG)转换成16色pcx类型:
alchemy -p -c16 输入文件名 输出文件名
对参数的大小写敏感,输入文件名最好最前面是字母(纯数字文件名,经常识别错,说我打错参数,呵呵~)。查看详细帮助可以打
alchemy -h0
alchemy -h1
alchemy -h2
……
alchemy -h6

上面这个程序,pcx图片在某些大小时不能正确显示,请先调好图片大小。最好用640*480,编其它程序要用到时,再换成TP7能识别的getimage、putimage数据格式。(象我那个扑克牌显示图形一样)。

5 楼

256色的如何?

6 楼

不知楼主是否有alchemy.exe的参数使用教程, 我做图象急需. 方便的话请和我联系.
MSN: zhang_h_xia@hotmail.com
qq: 165709275

谢谢谢~~~~~.

7 楼


可以给我吗?
hylcrazy@126.com

我来回复

您尚未登录,请登录后再回复。点此登录或注册