不同图像文件格式之间的转换

作者在 2008-07-29 23:37:35 发布以下内容
BMPtoAVI

//生成avi
void Cbmp2aviDlg::BMPtoAVI(CString szAVIName, CString strBmpDir)
{
 CFileFind finder;
 strBmpDir += _T("\\*.*");
 AVIFileInit();
 AVISTREAMINFO strhdr;
 PAVIFILE pfile;
 PAVISTREAM ps;
 int nFrames =0;
 HRESULT hr;

 BOOL bFind = finder.FindFile(strBmpDir);
 while(bFind)
 {
  bFind = finder.FindNextFile();
  if(!finder.IsDots() && !finder.IsDirectory())
  {
   CString str = finder.GetFilePath();
   FILE *fp = fopen(str,"rb");
   BITMAPFILEHEADER bmpFileHdr;
   BITMAPINFOHEADER bmpInfoHdr;
   fseek( fp,0,SEEK_SET);
   fread(&bmpFileHdr,sizeof(BITMAPFILEHEADER),1, fp);
   fread(&bmpInfoHdr,sizeof(BITMAPINFOHEADER),1, fp);

   BYTE *tmp_buf = NULL;
   if(nFrames ==0 )
   {
    AVIFileOpen(&pfile,szAviName,OF_WRITE | OF_CREATE,NULL);
    _fmemset(&strhdr, 0, sizeof(strhdr));
    strhdr.fccType = streamtypeVIDEO;// stream type
    strhdr.fccHandler = 0;
    strhdr.dwScale = 1;
    strhdr.dwRate = 15; // 15 fps
    strhdr.dwSuggestedBufferSize = bmpInfoHdr.biSizeImage ;
    SetRect(&strhdr.rcFrame, 0, 0, bmpInfoHdr.biWidth, bmpInfoHdr.biHeight);

    // And create the stream;
    hr = AVIFileCreateStream(pfile,&ps,&strhdr);
    // hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
   }
   tmp_buf = new BYTE[bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3];
   fread(tmp_buf, 1, bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3, fp);
   hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
   hr = AVIStreamWrite(ps, // stream pointer
      nFrames , // time of this frame
      1, // number to write
      (LPBYTE) tmp_buf,
      bmpInfoHdr.biSizeImage , // size of this frame
      AVIIF_KEYFRAME, // flags....
      NULL,
      NULL);

   nFrames ++;
   fclose(fp);
  }
 }

 AVIStreamClose(ps);

 if(pfile != NULL)
  AVIFileRelease(pfile);
 AVIFileExit();
}
图像 | 阅读 10822 次
文章评论,共3条
vfdff(作者)
2008-07-29 23:38
1
BMP转成PCX文件<br />
<br />
自己用ACSEE把BMP转成PCX文件就行了注意文件格式:320*200*256<br />
http://bbs.pfan.cn/showpost.asp?id=56348&amp;t=o<br />
#include&lt;io.h&gt;<br />
#include&lt;stdio.h&gt;<br />
#include&lt;dos.h&gt;<br />
#include&lt;string.h&gt;<br />
#include&lt;math.h&gt;<br />
#include&lt;stdio.h&gt;<br />
#include&lt;bios.h&gt;<br />
#include&lt;mem.h&gt;<br />
#include&lt;fcntl.h&gt;<br />
#include&lt;stdlib.h&gt;<br />
#include&lt;conio.h&gt;<br />
<br />
#define SCREEN_HEIGHT 200<br />
#define SCREEN_WIDTH 320<br />
#define PALETTE_MASK 0x3c6<br />
#define PALETTE_REGISTER_RD 0x3c7<br />
#define PALETTE_REGISTER_WR 0x3c8<br />
#define PALETTE_DATA 0x3c9<br />
<br />
#define VGA256 0x13<br />
#define TEXT_MODE 0x03<br />
unsigned char far *video_buffer=(char far *)0xA0000000L;<br />
typedef struct pcx_header_typ<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; char manufacturer;<br />
&nbsp;&nbsp;&nbsp; char version;<br />
&nbsp;&nbsp;&nbsp; char encoding;<br />
&nbsp;&nbsp;&nbsp; char bits_per_pixel;<br />
&nbsp;&nbsp;&nbsp; int x,y;<br />
&nbsp;&nbsp;&nbsp; int width,height;<br />
&nbsp;&nbsp;&nbsp; int horz_res;<br />
&nbsp;&nbsp;&nbsp; int vert_res;<br />
&nbsp;&nbsp;&nbsp; char ega_palette[48];<br />
&nbsp;&nbsp;&nbsp; char reserved;<br />
&nbsp;&nbsp;&nbsp; char num_color_planes;<br />
&nbsp;&nbsp;&nbsp; int bytes_per_line;<br />
&nbsp;&nbsp;&nbsp; int palette_type;<br />
&nbsp;&nbsp;&nbsp; char padding[58];<br />
<br />
&nbsp;&nbsp;&nbsp; } pcx_header, *pcx_header_ptr;<br />
<br />
typedef struct RGB_color_typ<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
}RGB_color,*RGB_color_ptr;<br />
<br />
<br />
<br />
typedef struct pcx_picture_typ<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; pcx_header header;<br />
&nbsp;&nbsp;&nbsp; RGB_color palette[256];<br />
&nbsp;&nbsp;&nbsp; char far *buffer;<br />
<br />
&nbsp;&nbsp;&nbsp; } pcx_picture, *pcx_picture_ptr;<br />
<br />
<br />
void Set_Palette_Register(int index,RGB_color_ptr color)<br />
{<br />
outp(PALETTE_MASK,0xff);<br />
outp(PALETTE_REGISTER_WR,index);<br />
outp(PALETTE_DATA,color-&gt;red);<br />
outp(PALETTE_DATA,color-&gt;green);<br />
outp(PALETTE_DATA,color-&gt;blue);<br />
}<br />
<br />
<br />
void PCX_Load_Screen(char *filename,int enable_palette)<br />
{<br />
// this function loads a pcx file into a picture structure, the actual image<br />
// data for the pcx file is decompressed and expanded into a secondary buffer<br />
// within the picture structure, the separate images can be grabbed from this<br />
// buffer later.&nbsp;&nbsp;also the header and palette are loaded<br />
<br />
FILE *fp;<br />
int num_bytes,index;<br />
unsigned int count;<br />
unsigned char data;<br />
RGB_color palette[256];<br />
// open the file<br />
<br />
<br />
fp = fopen(filename,&quot;rb&quot;);<br />
<br />
<br />
fseek(fp,128L,SEEK_SET);<br />
// load the data and decompress into buffer<br />
count=0;<br />
<br />
<br />
while(count&lt;=(unsigned int)SCREEN_WIDTH * SCREEN_HEIGHT)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// get the first piece of data<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = getc(fp);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// is this a rle?<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (data&gt;=192 &amp;&amp; data&lt;=255)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; // how many bytes in run?<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;num_bytes = data-192;<br />
<br />
&nbsp;&nbsp;&nbsp; // get the actual data for the run<br />
<br />
&nbsp;&nbsp;&nbsp; data&nbsp;&nbsp;= getc(fp);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// replicate data in buffer num_bytes times<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(num_bytes--&gt;0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image-&gt;buffer[count++] = data;<br />
&nbsp;&nbsp;video_buffer[count++]=data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} // end while<br />
<br />
&nbsp;&nbsp;&nbsp; } // end if rle<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; // actual data, just copy it into buffer at next location<br />
<br />
&nbsp;&nbsp;&nbsp; //image-&gt;buffer[count++] = data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;video_buffer[count++]=data;<br />
&nbsp;&nbsp;&nbsp; } // end else not rle<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} // end while<br />
for (index=0; index&lt;256; index++)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; // get the red component<br />
<br />
&nbsp;&nbsp;&nbsp; palette[index].red&nbsp;&nbsp;&nbsp;= (getc(fp) &gt;&gt; 2);<br />
<br />
&nbsp;&nbsp;&nbsp; // get the green component<br />
<br />
&nbsp;&nbsp;&nbsp; palette[index].green = (getc(fp) &gt;&gt; 2);<br />
<br />
&nbsp;&nbsp;&nbsp; // get the blue component<br />
<br />
&nbsp;&nbsp;&nbsp; palette[index].blue&nbsp;&nbsp;= (getc(fp) &gt;&gt; 2);<br />
<br />
&nbsp;&nbsp;&nbsp; } // end for index<br />
<br />
fclose(fp);<br />
<br />
// change the palette to newly loaded palette if commanded to do so<br />
<br />
if (enable_palette)<br />
&nbsp;&nbsp;&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;for (index=0; index&lt;256; index++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set_Palette_Register(index,(RGB_color_ptr)&amp;palette[index]);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } // end for index<br />
<br />
&nbsp;&nbsp;&nbsp;} // end if change palette<br />
<br />
} // end PCX_Load<br />
<br />
void Set_Video_Mode(int mode)<br />
{<br />
&nbsp;&nbsp;&nbsp; union REGS inregs,outregs;<br />
&nbsp;&nbsp;&nbsp; inregs.h.ah=0;<br />
&nbsp;&nbsp;&nbsp; inregs.h.al=(unsigned char)mode;<br />
&nbsp;&nbsp;&nbsp; int86(0x10,&amp;inregs,&amp;outregs);<br />
}<br />
<br />
void Delay(int clicks)<br />
{<br />
&nbsp;&nbsp;&nbsp; unsigned int far *clock=(unsigned int far *)0x0000046CL;<br />
&nbsp;&nbsp;&nbsp; unsigned int now;<br />
&nbsp;&nbsp;&nbsp; now=*clock;<br />
&nbsp;&nbsp;&nbsp; while(abs(*clock-now)&lt;clicks){}<br />
}<br />
<br />
<br />
void main(void)<br />
{<br />
int i;<br />
char *pcx[5];<br />
pcx[1]=&quot;mark.pcx&quot;;<br />
pcx[2]=&quot;mark1.pcx&quot;;<br />
pcx[3]=&quot;mark2.pcx&quot;;<br />
<br />
Set_Video_Mode(VGA256);<br />
for(i=1;i&lt;=3;i++)/*循环变量的值为数组的大小*/<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; PCX_Load_Screen(pcx[i],1);<br />
&nbsp;&nbsp;&nbsp; Delay(30);<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
getch();<br />
Set_Video_Mode(TEXT_MODE);<br />
<br />
}
vfdff(作者)
2008-07-29 23:39
2
不同比特深度的图像之间转换<br />
<br />
Evan Tan的意见: <br />
&nbsp;&nbsp;&nbsp; 我的理解,抛砖引玉啦: <br />
&nbsp;&nbsp;&nbsp; 24位位图和32位位图的区别在于后者多了一个Alpha通道(多了8位),Alpha通道信息可以作抛弃处理; <br />
&nbsp;&nbsp;&nbsp; 24位位图是R8G8B8,16位一般是R5G6B5,我曾经做过,方法是从24位位图中去掉RGB的最低几位(R3G2B3),变成R5G6B5; <br />
&nbsp;&nbsp;&nbsp; 8位位图转成16位位图,简单的做法,与24位转16位相反,RGB后面各自补适当个数的0;但要图像效果稍好,需要做插值处理了。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 寒轩的意见: <br />
&nbsp;&nbsp;&nbsp; 24bit或32位的这些转换成16bit的图像,很明显这只能是逐个像素RGBA的转换,从24和32转到16位的(这16位的还没说清楚是什么,因为16位的有1555和565两种格式),最简单的方法就是每一个像素的RGBA抛掉相应的位数就行了。例如24位的颜色值是RGB(没有A),16位的如果采用565格式的话,那么就是每像的R除以8(2的3次方),G除以4,B也除以8。这样就得到565格式了。不过这样做等于是每将相近的颜色合并了,就以R位除以8的情况来说,0~7除完之后就是0了,所以原本0~7的颜色就全变成了0了。这样将过渡的信息丢失了很多。处理的方法可以是采用误差扩散或者抖动算法来解决一下。 <br />
&nbsp;&nbsp;&nbsp; 同理的,从8位变到16位的道理完全一样。因为8位色用的是调色板,而调色板上的颜色本来就是24位,所以转换的时候就可以先将8位色索引展开后得到24位图,再用前面所说的算法变成16位的。
vfdff(作者)
2008-08-15 23:01
3
位图BMP文件头<br />
其数据结构中包含了BMP文件的类型、大小等信息,称为BITMAPFILEHEADER,长度固定为14字节<br />
typedef struct tagBITMAPFILEHEADER <br />
{ <br />
WORD&nbsp;&nbsp;&nbsp; bfType;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 位图文件的类型,必须为BM <br />
DWORD&nbsp;&nbsp;&nbsp;bfSize;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 位图文件的大小,以字节为单位 <br />
WORD&nbsp;&nbsp;&nbsp; bfReserved1;&nbsp;&nbsp;// 位图文件保留字,必须为0 <br />
WORD&nbsp;&nbsp;&nbsp; bfReserved2;&nbsp;&nbsp;// 位图文件保留字,必须为0 <br />
DWORD&nbsp;&nbsp;&nbsp;bfOffBits;&nbsp;&nbsp;&nbsp; // 位图数据的起始位置,以相对于位图 <br />
// 文件头的偏移量表示,以字节为单位 <br />
} BITMAPFILEHEADER; <br />
<br />
位图信息头<br />
BMP位图信息头数据用于说明位图的尺寸等信息,其长度固定为40字节<br />
typedef struct tagBITMAPINFOHEADER{ <br />
DWORD&nbsp;&nbsp;biSize;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 本结构所占用字节数 <br />
LONG&nbsp;&nbsp;&nbsp;biWidth;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 位图的宽度,以像素为单位 <br />
LONG&nbsp;&nbsp;&nbsp;biHeight;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 位图的高度,以像素为单位 <br />
WORD&nbsp;&nbsp;&nbsp;biPlanes;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 目标设备的级别,必须为1 <br />
WORD&nbsp;&nbsp;&nbsp;biBitCount;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 每个像素所需的位数,必须是1(双色), <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 4(16色),8(256色)或24(真彩色)之一 <br />
DWORD&nbsp;&nbsp;biCompression;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 位图压缩类型,必须是 0(不压缩), <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 <br />
DWORD&nbsp;&nbsp;biSizeImage;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 位图的大小,以字节为单位 <br />
LONG&nbsp;&nbsp;&nbsp;biXPelsPerMeter;&nbsp;&nbsp;&nbsp;// 位图水平分辨率,每米像素数 <br />
LONG&nbsp;&nbsp;&nbsp;biYPelsPerMeter;&nbsp;&nbsp;&nbsp;// 位图垂直分辨率,每米像素数 <br />
DWORD&nbsp;&nbsp;biClrUsed;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 位图实际使用的颜色表中的颜色数 <br />
DWORD&nbsp;&nbsp;biClrImportant;&nbsp;&nbsp;&nbsp; // 位图显示过程中重要的颜色数 <br />
} BITMAPINFOHEADER; <br />
<br />
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色<br />
typedef struct tagRGBQUAD { <br />
BYTE&nbsp;&nbsp;rgbBlue;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 蓝色的亮度(值范围为0-255) <br />
BYTE&nbsp;&nbsp;rgbGreen;&nbsp;&nbsp;&nbsp; // 绿色的亮度(值范围为0-255) <br />
BYTE&nbsp;&nbsp;rgbRed;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 红色的亮度(值范围为0-255) <br />
BYTE&nbsp;&nbsp;rgbReserved; // 保留,必须为0 <br />
} RGBQUAD; <br />
颜色表中RGBQUAD结构数据的个数由biBitCount来确定: <br />
当biBitCount=1,4,8时,分别有2,16,256个表项; 当biBitCount=24时,没有颜色表项。<br />
<br />
typedef struct tagBITMAPINFO { <br />
BITMAPINFOHEADER bmiHeader;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 位图信息头 <br />
RGBQUAD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bmiColors[];&nbsp;&nbsp;// 颜色表 <br />
} BITMAPINFO;<br />
<br />
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。<br />
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数<br />
位图数据的大小(不压缩情况下):DataSize= DataSizePerLine* biHeight<br />
单色图像每字节记录8个像素;16色图像每字节记录两个像素,其中,左四位记录第一个像素,右四位记录第二个像素;<br />
256色图像以一个字节记录一个像素;真彩色图像以三个字节记录一个像素.(从高位到低位存放)
游客请输入验证码
浏览1936682次