正文

C语言实现在DOS下显示图片2006-05-16 21:28:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/mrli81/14208.html

分享到:

请问用c 语言,怎样才能实现在DOS下显示图片。
undercontrol (兵临城下)     2004-07-07 12:37:34 在 C/C++ / C语言 提问
图片格式任意。

问题点数:20、回复次数:13

1楼  snowegale888   (dragon)   回复于 2004-07-07 12:49:40  得分 5
用c语言的图形接口函数。查一查,应该是没有问题的  
  可能是要用循环一点一点的画出来的吧   
Top
2楼  undercontrol   (兵临城下)   回复于 2004-07-07 12:54:52  得分 0
问题是图片一般都是二进制文件,提取这些二进制没有问题,但怎样区分他们,   
怎样才能把它们转化为对应的色点。最后把它们从屏幕上画出来到是很简单。

Top
3楼  archim   (PRC)   回复于 2004-07-07 13:49:11  得分 0
对于每一种类型的图片,仔细阅读关于这种图片文件格式的详细说明

Top
4楼  storyboy   (故事)   回复于 2004-07-07 13:54:14  得分 5
这就要看具体的图片格式了,比如24位真彩色的图象24位表示一个点8×8×8(R×G×B);256色的图象存的是一个调色板和8位的索引值

Top
5楼  wangwei8117   (还没学会编程。)   回复于 2004-07-07 15:29:55  得分 0
学习中

Top
6楼  scyangd   (Thinking)   回复于 2004-07-07 18:05:15  得分 0
关注。

Top
7楼  xjp6688   (大平/要做必须最好)   回复于 2004-07-07 18:40:49  得分 0
关注,真还没遇到在DOS能显示图片的,楼主有什么特殊的用途吗?

Top
8楼  cnxiaohai   (相声独一处(放假就是好,就如同纯C一样!舒服!))   回复于 2004-07-07 22:19:02  得分 0
可以用CONIO.H来尝试一下  
   
  我用过多次  
   
  效果不错

Top
9楼  jiang8360   (姜)   回复于 2004-07-08 08:57:56  得分 0
UP

Top
10楼  alongfly   (fang)   回复于 2004-07-08 09:50:14  得分 0
有用Direct   STD编程的人在吗?偶也想领教一下。  
  不过一般的图片你只样知道它的文件格式,把数据取出来一个点一个点的画在屏幕上就行了  
  它的格式你就研究它的二进制文本了

Top
11楼  ZhangYaoxing   (westxx)   回复于 2004-07-08 10:30:22  得分 0
DOS一般情况下不是最高只到256色吗?为什么要用它来显示图片呢?

Top
12楼  wensusy   (星之冰点)   回复于 2004-07-08 11:01:32  得分 0
你看看GRAPHICS.H,这里面有不少画图的函数,或许你能用的上。我作过一些图像显示的程序。

Top
13楼  chillman   (天才老头)(灌水是我无言的抗议)   回复于 2004-07-08 13:08:13  得分 10
GRX   graphics   library     http://grx.gnu.de/     支持几乎所有的图片格式  
   
  On   DOS   it   supports   EGA,   VGA   and   VESA   compliant   cards.   On   Linux   console   it   uses   svgalib   or   the   framebuffer.   On   X11   only   Linux   is   directly   supported,   but   it   must   work   on   any   X11R5   (or   later)   system   after   a   few   changes   in   a   config   file.   From   the   2.4   version,   GRX   comes   with   a   Win32   driver,   from   2.4.6   you   can   considere   it   stable.   The   Linux   console   framebuffer   video   driver   was   new   in   2.4.2,   it   is   in   alpha   stage.    
   
   
   
  直接用吧.不要再浪费时间了  
   
  你要自己写,就去读VESA文档!

来源:某论坛!

在C语言中,我们也可以给软件加上一个好的封面,这会给你的程序添色不少。
学习目标
  ·BMP文件的存储格式
  ·DOS方式下调用BMP图像的手段
  ·艺术再现BMP图像
BMP文件的存储格式
BMP文件是标准的Windows位图文件,有16色、256色、16位真彩色及24位真彩色等格式。客观存在按文件头、图像控制信息、彩色表和位图点阵数据的格式来存储。文件头是定义图像文件的类型、长度等的数据结构:图像控制信息是定义图像颜色格式、图像大小、颜色数等的数据结构:彩色表是定义图像颜色的调色板的数组位图点阵,是定义图像数据的数组。
未经压缩的BMP文件中,位图点阵信息是按扫描线从下至上(bottom to top)存储的,即图像的第一个像素值在位图阵列的左下角,最后一个像素值在位图阵列的右上角。对16色位图,每个像素占4位,每个字节存放相邻的两个像素值,高4位存放的第1个像素值在扫描线的前面,低4位存放的第2个像素值在扫描线后面。对256色位图,1个字节存放1个像素值。对24位位图,颜色表为空,位图数据的每3个字节对应1个像素值,其中每个字节分别对应该像素值的P、R、G值。

DOS方式下调用BMP图像的手段
再现一副非压缩静止位图,主要需下面三个步骤:
·设置显示模式;
·打开位图文件,读取图像控制信息,设置调色板;
·读取位图数据度进行显示。
若图像数据是以堵塞压缩的,那么先解压,然后再按上面的步骤进行。
设置显示模式
  随着计算机硬件的不断发展,尤其是显示卡和显示椿性能的提高,显示效果越来越好。图像显示效果主要体现在图像分辨率和颜色两个方面,分辨率反映图像的清晰和谐,而颜色则反映了图像与物体本来颜色的逼真程度。虽然,对一个图形图像界面的评价涉及人的审美观,心理因素等主观原因,但也有客观的标准。高分辨率和真彩色是人分辨率追求的最高目标。现在,性能好的显示卡和显示器(如SUPER VGA)能支持高达1024X768的分辨率,可以表示的颜色数目可达2:4种。对于DOS用户而言,常用的是640X480分辨率/16色、320X200分辨率/256色和640X480分辨率/256色等几种模式,它们分别是VGA/TVGA中的12h、13h和5dh模式。可通过直接调用DOS的10h中断来设置:
  相应的函数定义如下:
  int Set640_480 (void)
  {
    asm mov ax,4fO2h
    asm mov bx,OlOlh
    asm int lob
    if((_AL==0x4f)&&(_AH==0))
  {
      return(0);
  }
  return(1)
  }
  调色板的设置
  在DOS环境下显示Windows位图时,由于DOS调色板与Windows调色板不同,因此需自行设置Windows调色板,这样,图像才能不失真地显示所需的颜色并与原图像颜色相匹配。具体操作是从图像文件中读出彩色表数值,调用函数int86x写入Windows调色板控制区域。
  相应的函数定义如下:
  void set_windows_palette16(unsigned char bmp_top[])
  /*设置调色板*/
  { int i;
  unsigned char chg[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
  int f[16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15 };
  for(i=O;i<-I 5;i++)
    (outportb(Ox3c8,chg[f]);
    outportb(Ox3c9,bmp top[54+i*4+2]/4);
    outportb(Ox3c9,bmp_top[5,~+i*4+ 1 ]/4);
    outportb(Ox3c9 ,bmp top [54+i* 4~-0]/4);}
  }
int bmp_out(int x,int y,char *bmp_name)
  /*打开文件名为*bmp_name的文件,在(x,y)位置输出图像*/
{
  int i,j,k,l=0,c1,c2,x1,y1;
  unsigned char h,bmp_top[ 128],w,b=0x80,x0;
  char far *ptr=-(char far *)0xa0000000;
  char far *p;
  int fi16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15 };
  FILE *fp;
  if((fp=fopen(bmp name,"rb"))==NULL) return(1)
  fread(bmp_top,118,1,fp);
  set_windows_palette16(bmp_top);
  xl=bmp_top[18]+bmp_top[19]*256;
  y1=bmp_top[22]+bmp_top[23]*256;
  c1=(8-x1%8)/2; c2=x1%8;
  x0=b>>(x%8);
  ptr+=(rdS+80*(y+yl ));
  outportb(Ox3ce,5);outportb(Ox3cf, 2);
  for(i=O;i<yl i++)
    {
    j=0;b=x0;
    for(l=0;l<x1;l+=2)
      {
        h=getc(fp);
        outportb(Ox3ce,8);outportb(Ox3cf,b);b>>=1;
        p=ptr-i*80+j;
        w=*p;
        *p=f[h>>4];
        if(!b) {b=OxSO;j++; }
        if(x1%2&&l==x1-1) break;
        outportb(Ox3ce,8);outportb(Ox3cf,b);b>>= 1
        p=ptr-i*80+j;
        w=*p;
        *p=f[h&OxOf];
        if(!b) {b=Ox80;j++;}
      }
      if(c2) for(k--O;k<c1 k++) getc(fp);
    }
  outportb(Ox3ce,8);outportb(Ox3cf,255);
  outportb(Ox3ce,5) outportb(Ox3cf,O);
  fclose(fp);
  return(O);}
图像再现
  下面我们来看一个例子,调出一幅BMP图像。
#include "conio.h"
#include "stdio.h"
#include "dos.h"
#include "stdlib.h"
#define lengthlimit 640
#define   highlimit 480
int Set640_480 (void)
{
asm mov ax,4f02h
asm mov bx,0101h
asm int 10h
if((_AL==0x4f)&&(_AH==0))
{
  return(0);
}
return(1);
}
void Set_Page(int page)
{
asm mov ax,4f05h
asm mov bx,0
asm mov dx,page
asm int 10h
}
void myputpixel (int row,int col,unsigned char color)
/*(row,col)画点的坐标,color画点颜色*/
{
unsigned long dantance;
unsigned y;
static int totalpage=0;
int page;
dantance=1l*col*lengthlimit+row;
y=(unsigned)(dantance&0X0000ffffl);
page=(int)(1.0*dantance/65536);
if (totalpage!=page) { totalpage=page; Set_Page(page); }
asm {
    mov ax,0a000h
    mov es,ax
    mov si,y
    mov al,color
    mov es:[si],al
  }
}
void bmpout(char *bmpstr)
/* 打开文件名为*bmpstr的BMP文件,输出图象*/
{
FILE *bmpfp;
struct bmp{
      int bftype;
      long bfsize;
      long bfr;
      long bfoff;
      long bisize;
      long biwidth
      long biheight;
    } bmpp;
struct DAC{
    char blue;
    char green;
    char red;
    };
struct DAC dacp[256];
char pp;
int colorcount,x,y,i,j,x0=0,y0=470,k,bibit,svg;
char resev,buf1
void *buf;
Set640_480();
if((bmpfp=fopen(bmpstr,"rb"))==NULL)
{
printf("can't open file");
return;
}
fread(&bmpp,sizeof(bmpp),1,bmpfp);
fseek(bmpfp,28l,SEEK_SET);
fread(&bibit,2,1,bmpfp);
fseek(bmpfp,46l,SEEK_SET);
fread(&colorcount,sizeof(colorcount),1,bmpfp);
if (colorcount==0) { colorcount=256;}
fseek (bmpfp,54l,SEEK_SET);
for (i=0;i<colorcount;i++)
{
  fread(&dacp,3,1,bmpfp);
  fread(&resev,1,1,bmpfp);
}
for(i=0;i<colorcount;i++)
{
  pp=dacp.red>>2;
  dacp.red=dacp.blue>>2;
  dacp.blue=pp;
  dacp.green=(dacp.green>>2);
}
asm push es
_ES=FP_SEG(dacp);
_DX=FP_OFF (dacp);
asm mov bx,0
asm mov cx,colorcount
asm mov ah,10h
asm mov al,12h
asm int 10h
asm pop es
fseek(bmpfp,bmpp.bfoff,SEEK_SET);
buf=malloc(bmpp.biwidth);
for(i=0;i<bmpp.biheight;i++)
{
  y=y0-i;
  fread(buf,bmpp.biwidth,1,bmpfp);
  for( j=x0;j<x0+bmpp.biwidth;j++)
  myputpixel(j,y,*((unsigned char*)buf+j));
  }
free(buf);
getch();
fclose(bmpfp);
delay(500);
return;
}
void main()
{
bmpout("*.bmp"); /* 打开某一BMP文件并输出图象*/
}
  下例采用了随即函数产生点的颜色,输出到屏幕缓冲区,得到迷幻的图像。
#include <stdio.h>
#include <dos.h>
#include <math.h>
long Addr[768];
int Mode;
Set_Mode (int mode)
{
  union REGS r;
  r.h.ah=0;
  r.h.al=mode;
  int86 (0x10,&r,&r);
}
Set_Graphics_Mode (unsigned x,unsigned y)
{
  long i;
  if ((x<321)&&(y<201)) {
    Set_Mode (0x13);
    Mode=0x13;
    for (i=0;i<200;i++) Addr=320*i;
  }
  else if ((x<641)&&(y<401)) {
    Set_Mode (0x5c);
    Mode=0x5c;
    for (i=0;i<400;i++) Addr=640*i;
  }
  else if ((x<641)&&(y<481)) {
    Set_Mode (0x5d);
    Mode=0x5d;
    for (i=0;i<480;i++) Addr=640*i;
  }
  else if ((x<641)&&(y<481)) {
    Set_Mode (0x5d);
    Mode=0x5d;
    for (i=0;i<480;i++) Addr=640*i;
  }
  else if ((x<801)&&(y<601)) {
    Set_Mode (0x5e);
    Mode=0x5e;
    for (i=0;i<600;i++) Addr=800*i;
  }
  else if ((x<1025)&&(y<769)) {
    Set_Mode (0x62);
    Mode=0x62;
    for (i=0;i<768;i++) Addr=1024*i;
  }
  else {
    Set_Mode (3);
    printf ("Not support this mode .\n");
    getch ();
  }
}
set_pattern ()
{
  int i;
  unsigned char pat[256][3];
  struct SREGS inreg;
  union REGS reg;
  pat[0][0]=0;pat[0][1]=0;pat[0][2]=0;
  for (i=1;i<=255;i++) {
    pat[0]=(unsigned char)((float)(abs(i-127)*63)/127.0+0.5);
    pat[1]=(unsigned char)((float)(abs(i-127)*63)/127.0+0.5);
    pat[2]=63;
  }
  reg.x.ax=0x1012;
  reg.x.bx=0;
  reg.x.cx=256;
  reg.x.dx=FP_OFF(pat);
  inreg.es=FP_SEG(pat);
  int86x (0x10,?,?,&inreg);
}
plot (int x,int y,unsigned char color)
{
  long offset;
  char Page;
  unsigned char far *address;
  switch (Mode) {
    case 0x13:
        offset=Addr[y]+x;
        address=(unsigned char far *)(0xa0000000L+offset);
        *address=color;
        break;
    case 0x5c:
    case 0x5d:
    case 0x5e:
        offset=Addr[y]+x;
        Page=(offset>>16);
        outportb (0x3c4,0xe);
        outportb (0x3c5,Page^0x02);
        offset=offset&65535;
        address=(unsigned char far *)(0xa0000000L+offset);
        *address=color;
        break;
    case 0x62:
        offset=Addr[y]+x;
        Page=y>>6;
        outportb (0x3c4,0xe);
        outportb (0x3c5,Page^0x02);
        offset=offset&65535;
        address=(unsigned char far *)(0xa0000000L+offset);
        *address=color;
        break;
    default:
        break;
  }
}
get_pixel (int x,int y)
{
  long offset;
  char Page;
  unsigned char far *address;
  unsigned char color;
  switch (Mode) {
    case 0x13:
        offset=Addr[y]+x;
        address=(unsigned char far *)(0xa0000000+offset);
        color=*address;
        break;
    case 0x5c:
    case 0x5d:
    case 0x5e:
        offset=Addr[y]+x;
        Page=(offset>>16);
        outportb (0x3c4,0xe);
        outportb (0x3c5,Page^0x02);
        offset=offset&65535;
        address=(unsigned char far *)(0xa0000000L+offset);
        color=*address;
        break;
    case 0x62:
        offset=Addr[y]+x;
        Page=y>>6;
        outportb (0x3c4,0xe);
        outportb (0x3c5,Page^0x02);
        offset=offset&65535;
        address=(unsigned char far *)(0xa0000000L+offset);
        color=*address;
        break;
    default:
        break;
  }
  return (color);
}
randint (unsigned int range)
{
  float sigma=423.1966;
  static double OldRand=0.4231967;
  double temp;
  temp=sigma*OldRand;
  OldRand=temp-(int)temp;
  return (int)(OldRand*(float)range);
}
void New_Col (int xa,int ya,int x,int y,int xb,int yb)
{
  unsigned int color;
  color=abs(xa-xb)+abs(ya-yb);
  color=randint(color<<1)-color;
  color=color+(get_pixel(xa,ya)+get_pixel(xb,yb)+1)>>1;
  if (color<1) color=1;
  else if (color>255) color=255;
  if ((get_pixel(x,y)==0)) plot (x,y,color);
}
void Sub_Divide (int x1,int y1,int x2,int y2)
{
  int x,y;
  unsigned char color;
  if (!((x2-x1<2)&&(y2-y1<2))) {
    x=(x1+x2)>>1;
    y=(y1+y2)>>1;
    New_Col (x1,y1,x,y1,x2,y1);
    New_Col (x2,y1,x2,y,x2,y2);
    New_Col (x1,y2,x,y2,x2,y2);
    New_Col (x1,y1,x1,y,x1,y2);
    color=(get_pixel(x1,y1)+get_pixel(x2,y1)+get_pixel(x2,y2)+get_pixel (x1,y2)+2)>>2;
    plot (x,y,color);
    Sub_Divide (x1,y1,x,y);
    Sub_Divide (x,y1,x2,y);
    Sub_Divide (x,y,x2,y2);
    Sub_Divide (x1,y,x,y2);
  }
}
main ()
{
  int x,y;
  x=320;y=200;
  Set_Graphics_Mode (x,y);
  set_pattern ();
  plot (0,0,randint(254)+1);
  plot (x-1,0,randint(254)+1);
  plot (x-1,y-1,randint(254)+1);
  plot (0,y-1,randint(254)+1);
  Sub_Divide (0,0,x-1,y-1);
  getch();
  Set_Mode (0x03);
}

 

阅读(8813) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册