⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image32.c

📁 matlab 例程
💻 C
字号:

#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <windows.h>
#include <commdlg.h>
#include "image32.h"

char 			szName[256];
struct IMAGE	*image;
int				nHorz,nVert,nPal_f,nBits,nColors;
HDC				hMemDC;
HBITMAP			hBitmap,hOldBitmap;
 
void ImageCreate(struct IMAGE * image, int wid, int hei, int bitcount) 	//  建立DIB
{
   BITMAPINFOHEADER  bmi={40,1,1,1,1,0,0,0,0,0,0};	//  位图信息头初始值
   int	  palette;
   DWORD  size,offset;

   if (image->hdib) ImageClose(image);

   if (bitcount<=8) palette=4*(1<<bitcount); 	//  计算调色板数据字节数
   else          palette=0;	//  真彩色图像无调色板
   image->wid=wid;	//  宽度
   image->hei=hei;	//  高度
   image->bitcount=(WORD) bitcount;	//  每像素位数
   image->bpp=(WORD) ((bitcount+7)/8); 	//  计算每像素字节数
   image->bpl=(WORD) ((wid*bitcount+31)/32*4);	 //  计算每行字节数
   size=40+palette+image->bpl*hei+64; 	//  计算DIB尺寸
   if (bitcount<=8) offset=40+palette; 	//  计算DIB中像素数据起始位置偏移
   else             offset=40;

   image->hdib=GlobalAlloc(GPTR, size); 	//  申请内存空间
   image->lpbi=(BITMAPINFO *) GlobalLock(image->hdib);	 //  得位图信息指针
   image->lpbits=(LPSTR) image->lpbi + offset; 	
                                           //  得DIB中像素数据起始位置

   bmi.biWidth=wid;	//  宽度、高度、每像素位数填入位图信息头
   bmi.biHeight=hei;
   bmi.biBitCount=(WORD) bitcount;
   memcpy(&image->lpbi->bmiHeader,&bmi,40); 	//  传入DIB的位图信息头
}

void ImageClose(struct IMAGE * image) 	//  关闭DIB
{
   GlobalUnlock(image->hdib);
   GlobalFree(image->hdib);	//  释放内存空间
   image->hdib=NULL;	//  指针清零
}

int  LoadBMP(struct IMAGE * image, char *str) 	//  打开并读入BMP图像文件
{
   BITMAPFILEHEADER  bfhead;
   BITMAPINFOHEADER  bmi;
   HFILE	fh;
   int	    wid,hei,bitcount;
   DWORD	biSize,offset, compression, size;

   fh=_lopen(str, OF_READ);	//  打开图像文件
   if (fh==-1)  return 1;	//  文件不存在,退出
   _llseek(fh, 0, SEEK_SET);
   _lread(fh, &bfhead, 14);	//  读入位图文件头
   _lread(fh, &bmi, 40);	//  读入位图信息头

   offset=bfhead.bfOffBits;	//  从位图文件头中得像素数据位置

   biSize  =bmi.biSize; 	//  得位图信息头字节数
   wid     =bmi.biWidth; 	//  得位图宽度
   hei     =bmi.biHeight;	//  得位图高度
   bitcount=bmi.biBitCount;	//  得每像素位数
   compression=bmi.biCompression;	//  得压缩类型
   if (compression) {
      _lclose(fh);
      return 2; 	//  是压缩文件,退出
   }

   ImageCreate(image,wid,hei,bitcount);

   offset-=14;		//  除去位图文件头,偏移减少14字节
   size=image->bpl*hei;	//  计算像素数据字节数

   _llseek(fh,14,SEEK_SET); 	//  指向文件的位图信息位置
   _hread(fh,(BYTE*)image->lpbi,offset);	//  位图信息读入内存DIB 
   _hread(fh,(BYTE*)image->lpbits,size); 	//  像素数据读入内存DIB
   _lclose(fh);		//  关闭图像文件
   return 0;
} 

int  LoadTGA(struct IMAGE * image,char *str)
{
   BITMAPINFOHEADER bmi={40,1,1,1,8,0,0,0,0,0,0};
   HFILE		fh;
   BYTE 	    *buf,buf1[1024];
   int          i,j,pos,bplt,bpl,palette;
   int          wid,hei,bits,type;
   DWORD		size,offset;
 
   if (image->hdib) ImageClose(image);

   fh=_lopen(str,OF_READ);
   if (fh==-1)  {
	  image->hdib=NULL;
	  return 1;
   }

   _llseek(fh,2,SEEK_SET);
   _lread(fh,&type,1);
   if (type & 0x08) {
      _lclose(fh);
 	  return 2;
   }

   _llseek(fh,12,SEEK_SET);
   _lread(fh,&wid,2);
   _lread(fh,&hei,2);
   _lread(fh,&bits,1);

   ImageCreate(image,wid,hei,bits);

   if (bits==8)
      palette = 1024;
   else
	  palette = 0;
   offset = 40 + palette;
   bpl=((wid*bits+7)/8+3)/4*4;
   if (bits==24) {
      size=bpl*hei+offset;
      bplt=3*wid;
   }
   else {
      size=bpl*hei+offset;
      bplt=wid;
   }

   pos=18;
   _llseek(fh,18,SEEK_SET);
   buf=(BYTE*)image->lpbi;
   buf+=40;
   if (type==1) {
 	  _hread(fh,buf1,768);
      for (i=0;i<256;i++) {
         for (j=0;j<3;j++)  buf[4*i+j]=buf1[3*i+j];
	  }
      buf+=1024;
      pos=18+768;
   }
   else if (type==3) {
	  for (i=0;i<256;i++) {
         for (j=0;j<3;j++)  buf[4*i+j]=(BYTE) i;
	  }
      buf+=1024;
   }

   _llseek(fh,pos,SEEK_SET);
   for (i=0;i<hei;i++) {
      _hread(fh,buf,bplt);
      buf+=bpl;
   }
   _lclose(fh);
   return 0;
}

int  ImageOpen(struct IMAGE * image, char *str)	 //  打开并读入图像文件
{
   int  	m,n;

   strupr(str);
   n=strlen(str);
   if (strcmp(&str[n-3], "BMP")==0)	//  检查文件名后缀
	   m=LoadBMP(image, str); 	//  打开并读入BMP图像文件
   else if (strcmp(&str[n-3], "TGA")==0)	//  检查文件名后缀
	   m=LoadTGA(image, str); 	//  打开并读入TGA图像文件
   return m;
}

void ImageSave(struct IMAGE * image, char *str) 	//  存储图像文件
{
    BITMAPFILEHEADER bfhead = { 0x4d42,0,0,0,0};	//  位图文件头初始值 
   HFILE 	fh;
   OFSTRUCT  of;
   int    	palette;
   DWORD 	size, offset;

   if (image->hdib==NULL) return;	//  DIB为空时返回
   fh = OpenFile(str, &of, OF_CREATE | OF_READWRITE);	//  打开图像文件
   if (fh==-1) return;	//  文件不存在,则返回

   if (image->bitcount<=8)  palette = 1<<(image->bitcount+2); 	//  计算调色板数据字节数
   else  palette = 0;
   offset = 40 + palette;	//  计算位图信息字节数
   image->bpl=(WORD) ((image->wid*image->bitcount+31)/32*4);	//  计算每行字节数
   size = image->bpl*image->hei; 	//  计算像素数据字节数
   bfhead.bfOffBits = 14 + offset;	//  计算像素数据在文件中的位置
   bfhead.bfSize = 14 + offset + size;	//  计算BMP图像文件总字节数

   _llseek(fh, 0, SEEK_SET);
   _hwrite(fh, (LPSTR) &bfhead, 14);  	              //  存位图文件头
   _hwrite(fh, (LPSTR) image->lpbi, offset);	     //  存DIB位图信息
   _hwrite(fh, image->lpbits, size);	             //  存DIB像素数据
   _lclose(fh);		                                  //  关闭图像文件
}

DWORD pixel(struct IMAGE * image,int x,int y,DWORD c)
{
   BYTE   	 *hp;
   DWORD      le,dd=0;
   int        yy;
 
   if (image->bitcount<8)  return 0;
   if ((x<0)||(y<0)||(x>=(int) image->wid)||
	          (y>=(int) image->hei)) return 0;
   x *= image->bpp;	 yy = image->hei-1-y;
   le = (DWORD) image->bpl*yy+x;
   hp = (BYTE *) image->lpbits + le;
   if (c==0xffffffff) {
      memcpy(&dd,hp,image->bpp);
   }
   else  memcpy(hp,&c,image->bpp);
   return(dd);
}

DWORD getpixel(struct IMAGE * image,int x,int y)
{
   return(pixel(image,x,y,0xffffffff));
}

void setpixel(struct IMAGE * image,int x,int y,DWORD c)
{
   pixel(image,x,y,c);
}

COLORREF DWORD2CLRREF(DWORD c)
{
   BYTE		i;
   union    COLOR {
      COLORREF  clrref;
	  BYTE		c[4];
   } col;

   col.clrref=c;
   i=col.c[0];		col.c[0]=col.c[2];
   col.c[2]=i;		c=col.clrref;
   return(c);
}

void putpixel(HWND hWnd,struct IMAGE * image,int px,int py,
                                        DWORD c,int sx,int sy)
{
   HDC 		hdc;
   int		r,g,b;
 
   setpixel(image,px,py,c);
   hdc = GetDC(hWnd);
   if (image->bitcount==8) {
      getpalette(image,(int)c,&r,&g,&b);
      c=RGB(r,g,b);
   }
   else {
	  c=DWORD2CLRREF(c);
   }
   SetPixel(hdc,sx,sy,c);
   ReleaseDC(hWnd,hdc);
}

void getset(struct IMAGE * image,int x,int y,int Dx,int Dy,BYTE* buf,int flag)
{
   BYTE  *lp;
   int   i,dw,dh,delta=0;
   
   if ((image->bitcount<8)||(x+Dx<=0))  return;
   if (x<0) {                                             //  左边越界
      delta=-x;    x=0;
   }
   if ((x<0)||(y<0)||(x>=(int) image->wid)||
	          (y>=(int) image->hei)) return;
   Dx *= image->bpp;                //  像素地址转换成字节地址
   delta *= image->bpp;                   //  左边不显示的部分
   dw=min(Dx,(int) image->bpl-image->bpp*x);
   dh=min(Dy,(int) image->hei-y);
   buf += delta;                        //  调整输入输出像素数据首地址
   dw  -= delta;                                  //  调整实际显示宽度
   lp = DibAddress(image,x,y);
   for (i=0;i<dh;i++) {
      if (flag==0) {
         memcpy(lp,buf,dw);                               //  写入数据
      }
      else {
         memcpy(buf,lp,dw);                               //  读出数据
	  }
      buf += Dx;	lp -= image->bpl;
   }
}
 
void getimage(struct IMAGE * image,int x,int y,int Dx,int Dy,BYTE* buf)
{
   getset(image,x,y,Dx,Dy,buf,1);
}

void setimage(struct IMAGE * image,int x,int y,int Dx,int Dy,BYTE* buf)
{
   getset(image,x,y,Dx,Dy,buf,0);
}

void putimage(HWND hWnd,struct IMAGE * image,int px,int py,
                       int Dx,int Dy,BYTE* buf,int sx,int sy)
{
   setimage(image,px,py,Dx,Dy,buf);
   WriteDDB(image,sx,sy,px,py,Dx,Dy);
}

BYTE* DibAddress(struct IMAGE * image,int x,int y)
{
   BYTE   *lp;
   DWORD  le;
   int    yy;
 
   if (image->bitcount<8)  return 0;
   if ((x<0)||(y<0)||((WORD) x>=image->wid)||((WORD) y>=image->hei)) return 0;
   yy = image->hei-1-y;
   le = (DWORD) image->bpl*yy+image->bpp*x;
   lp = (BYTE *) image->lpbits + le;
   return(lp);
}

void setwin(struct IMAGE * image,int x,int y,int Dx,int Dy,DWORD color)
{
   int        i,dw,dh,k,len;
   HANDLE     hbuf;
   BYTE*      buf;

   if (image->bitcount<8) return;
   if ((x<0)||(y<0)||(x>=(int) image->wid)||
	          (y>=(int) image->hei)) return;
   dw=min(Dx,(int) image->bpl/image->bpp-x);   
   dh=min(Dy,(int) image->hei-y);
   if (dw<dh) len=dh;
   else       len=dw;
   hbuf=GlobalAlloc(LMEM_FIXED,len*image->bpp);
   buf=(BYTE*)GlobalLock(hbuf);
   if (image->bpp==1)  memset(buf,(BYTE)color,len);
   else {
	  for (i=0,k=0;i<len;i++,k+=image->bpp)
	     memcpy(&buf[k],&color,image->bpp);
   }
   if (dw==1)
	  setimage(image,x,y,1,dh,(BYTE*) buf);
   else {
	  for (i=0;i<dh;i++) {
		 setimage(image,x,y+i,dw,1,(BYTE*) buf);
	  }
   }
   GlobalUnlock(hbuf);
   GlobalFree(hbuf);
}

void fillw(HWND hWnd,struct IMAGE * image,int x,int y,int Dx,int Dy,DWORD color)
{
   setwin(image,x,y,Dx,Dy,color);
   WriteDDB(image,x,y,x,y,Dx,Dy);
}

void getpalette(struct IMAGE * image,int n,int *pr,int *pg,int *pb)
{
   BYTE       *hpal;

   if (image->bitcount>8)  return;
   hpal=(BYTE *) image->lpbi + 40;
   *pb=hpal[4*n];
   *pg=hpal[4*n+1];
   *pr=hpal[4*n+2];
}

void setpalette(struct IMAGE * image,int n,int r,int g,int b)
{
   BYTE       *hpal;

   if (image->bitcount>8)  return;
   hpal=(BYTE *) image->lpbi + 40;
   hpal[4*n]  =(BYTE) b;
   hpal[4*n+1]=(BYTE) g;
   hpal[4*n+2]=(BYTE) r;
}

void putpalette(HWND hWnd,struct IMAGE * image,int n,int r,int g,int b)
{
   setpalette(image,n,r,g,b);
   WriteDDB(image,0,0,0,0,image->wid,image->hei);
}

void GetSysParam(HDC hdc)
{
   nHorz  =GetDeviceCaps(hdc,HORZRES);
   nVert  =GetDeviceCaps(hdc,VERTRES);
   nPal_f =GetDeviceCaps(hdc,RASTERCAPS) & RC_PALETTE;
   nBits  =GetDeviceCaps(hdc,BITSPIXEL);
   if (nPal_f)
      nColors=1<<(nBits*GetDeviceCaps(hdc,PLANES));
   else nColors=0;
}

HBITMAP CreateDDB(HWND hWnd,int nHorz,int nVert)
{
   HDC  hDC;
   HBITMAP hBitmap;
   
   hDC = GetDC(hWnd);
   hBitmap=CreateCompatibleBitmap(hDC,nHorz,nVert);
   ReleaseDC(hWnd,hDC);
   return hBitmap;
}

void DeleteDDB(HBITMAP hBitmap)
{
   if (hBitmap)
	  DeleteObject(hBitmap);
}

HDC  CreateMemDC(void)
{
   HDC  hMemDC;
 
   hMemDC =CreateCompatibleDC(NULL); 
   SelectObject(hMemDC,hBitmap);
   return hMemDC;
}

void DeleteMemDC(HDC hMemDC)
{
   if (hMemDC) {
      DeleteObject(hMemDC);
	  DeleteDC(hMemDC);
   }
}

void ClearDDB(void) 	//  清除内存设备内容
{
   hMemDC =CreateMemDC();	//  建立内存设备
   PatBlt(hMemDC, 0, 0, nHorz, nVert, WHITENESS); 	//  用白色清除内存设备原来内容
   DeleteMemDC(hMemDC);	//  释放内存设备
}

void WriteDDB(struct IMAGE * image,int sx,int sy,
		int px,int py,int Dx,int Dy)
{
   hMemDC =CreateMemDC();	//  建立内存设备
   StretchDIBits(hMemDC,sx,sy,Dx,Dy,px,image->hei-(Dy+py),Dx,Dy,
		         image->lpbits,image->lpbi,DIB_RGB_COLORS,SRCCOPY);
   DeleteMemDC(hMemDC);	//  释放内存设备
}

void DisplayDDB(HWND hWnd)
{
   HDC     hDC;
  
   hDC = GetDC(hWnd);
   hMemDC=CreateMemDC();
   BitBlt(hDC,0,0,nHorz,nVert,hMemDC,0,0,SRCCOPY);
   DeleteMemDC(hMemDC);	//  释放内存设备
   ReleaseDC(hWnd,hDC);
}

void CMUFileOpen(HWND hWnd,char *str)
{
   OPENFILENAME ofnTemp;
   DWORD Errval;
   char buf[5];
   char Errstr[50]="GetOpenFileName returned Error #";
   char szTemp[] = "BMP Files (*.bmp)\0*.bmp\0TGA Files (*.tga)\0*.tga\0";

   ofnTemp.lStructSize = sizeof( OPENFILENAME );
   ofnTemp.hwndOwner = hWnd;
   ofnTemp.hInstance = 0;
   ofnTemp.lpstrFilter = (LPSTR)szTemp;
   ofnTemp.lpstrCustomFilter = NULL;
   ofnTemp.nMaxCustFilter = 0;
   ofnTemp.nFilterIndex = 1;
   ofnTemp.lpstrFile = (LPSTR)szName;
   ofnTemp.nMaxFile = sizeof( szName );
   ofnTemp.lpstrFileTitle = NULL;
   ofnTemp.nMaxFileTitle = 0;
   ofnTemp.lpstrInitialDir = NULL;
   ofnTemp.lpstrTitle=str;
   ofnTemp.Flags = OFN_FILEMUSTEXIST |
		OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
   ofnTemp.nFileOffset = 0;
   ofnTemp.nFileExtension = 0;
   ofnTemp.lpstrDefExt = "*";
   ofnTemp.lCustData = 0L;
   ofnTemp.lpfnHook = NULL;
   ofnTemp.lpTemplateName = NULL;

   if (GetOpenFileName( &ofnTemp ) != TRUE) {
	  Errval=CommDlgExtendedError();
	  if (Errval!=0) {
		 sprintf(buf,"%ld",Errval);
		 strcat(Errstr,buf);
		 MessageBox(hWnd,Errstr,"WARNING",MB_OK|MB_ICONSTOP);
	  }
   }
   InvalidateRect( hWnd, NULL, TRUE );
}

void CMUSaveFile(HWND hWnd,char *str)
{
   OPENFILENAME ofnTemp;
   DWORD Errval;
   char buf[5];
   char Errstr[50]="GetOpenFileName returned Error #";
   char szTemp[] = "BMP Files (*.bmp)\0*.bmp\0";

   ofnTemp.lStructSize = sizeof( OPENFILENAME );
   ofnTemp.hwndOwner = hWnd;
   ofnTemp.hInstance = 0;
   ofnTemp.lpstrFilter = (LPSTR)szTemp;
   ofnTemp.lpstrCustomFilter = NULL;
   ofnTemp.nMaxCustFilter = 0;
   ofnTemp.nFilterIndex = 1;
   ofnTemp.lpstrFile = (LPSTR)szName;
   ofnTemp.nMaxFile = sizeof( szName );
   ofnTemp.lpstrFileTitle = NULL;
   ofnTemp.nMaxFileTitle = 0;
   ofnTemp.lpstrInitialDir = NULL;
   ofnTemp.lpstrTitle=str;
   ofnTemp.Flags = OFN_FILEMUSTEXIST |
		OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
   ofnTemp.nFileOffset = 0;
   ofnTemp.nFileExtension = 0;
   ofnTemp.lpstrDefExt = "*";
   ofnTemp.lCustData = 0L;
   ofnTemp.lpfnHook = NULL;
   ofnTemp.lpTemplateName = NULL;

   if (GetSaveFileName( &ofnTemp ) != TRUE) {
	  Errval=CommDlgExtendedError();
	  if (Errval!=0) {
		 sprintf(buf,"%ld",Errval);
		 strcat(Errstr,buf);
		 MessageBox(hWnd,Errstr,"WARNING",MB_OK|MB_ICONSTOP);
	  }
   }
   InvalidateRect( hWnd, NULL, TRUE );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -