?? bmp24.cpp
字號:
// Bmp24.cpp: implementation of the CBmp24 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Bmp24.h"
#include <stdio.h>
#include <wingdi.h>
#include<malloc.h>
//===================================================================================================================
void CBmp24::CreateBmp(long w,long h)
{
//是不是已經用過了,先把原先的內存釋放了
if(m_pBits!=NULL) {free(m_pBits); m_pBits=NULL;}
m_BmpInf.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_BmpInf.bmiHeader.biWidth = w;
m_BmpInf.bmiHeader.biHeight = h;
m_BmpInf.bmiHeader.biPlanes = 1;
m_BmpInf.bmiHeader.biBitCount = 24;
m_BmpInf.bmiHeader.biCompression = BI_RGB;
m_BmpInf.bmiHeader.biSizeImage = w*h*3;
m_BmpInf.bmiHeader.biXPelsPerMeter = 0;
m_BmpInf.bmiHeader.biYPelsPerMeter = 0;
m_BmpInf.bmiHeader.biClrUsed = 0;
m_BmpInf.bmiHeader.biClrImportant = 0;
m_pBits=(unsigned char*)malloc(w*h*3);
memset(m_pBits,0,w*h*3);//新創建的圖片完全抹黑
}
//===================================================================================================================
bool CBmp24::LoadBmp(char *fileName)
{
FILE *fp;
BITMAPFILEHEADER bmpFileHeader;
unsigned long count=0;
//是不是已經用過了,先把原先的內存釋放了
if(m_pBits!=NULL) {free(m_pBits); m_pBits=NULL;}
//打開圖像文件
if( (fp = fopen( fileName, "rb")) == NULL )
{
TRACE("無法打開文件: %s\n", fileName );
return false;
}
//讀取圖像文件頭
if ((count=fread(&bmpFileHeader, 1, sizeof(bmpFileHeader), fp)) != sizeof(bmpFileHeader))
{
TRACE( "ERR004 讀取 BMP 文件頭失敗: count=%d\n", count);
return false;
}
//如果不是圖像文件,下面也就沒戲了
if(bmpFileHeader.bfType!='MB')
{
TRACE("不是BMP文件\n");
return false;
}
//讀取圖像信息頭,是m_BmpInf.bmiHeader,而不是m_BmpInf,操!
if ((count=fread(&m_BmpInf.bmiHeader, 1, sizeof(BITMAPINFOHEADER), fp)) != sizeof(BITMAPINFOHEADER))
{
TRACE( "ERR004 讀取 BMP 信息失敗: count=%d\n", count);
return false;
}
//如果不是24真彩位圖,下面還是沒戲
if(m_BmpInf.bmiHeader.biBitCount!=24)
{
TRACE("不是24位BMP文件\n");
return false;
}
//為了安全起見,重新計算圖像數據長度,因為有的圖的biSizeImage為零
m_BmpInf.bmiHeader.biSizeImage=m_BmpInf.bmiHeader.biWidth*m_BmpInf.bmiHeader.biHeight*3;
m_pBits=(unsigned char*)malloc(m_BmpInf.bmiHeader.biSizeImage);
if(!m_pBits)//居然沒申請到內存,我無語了,嗚嗚!
{
TRACE("ERROR CBmp24::LoadBmp malloc\n");
return false;
}
//讀取圖像的像素數據
if ((count=fread(m_pBits, 1, m_BmpInf.bmiHeader.biSizeImage, fp)) != m_BmpInf.bmiHeader.biSizeImage)
{
TRACE( "ERR004 讀取 BMP 文件數據失敗: count=%d\n", count);
return false;
}
fclose(fp);//讀完了,請關上文件,謝謝!
return true;//終于成功了,操!
}
//===================================================================================================================
bool CBmp24::LoadBmp(char *fileName,COLORREF cTransparentColor)
{
m_bTrasparented=1; //是否需要透明顯示
m_TransparentColor=cTransparentColor; //透明色
return LoadBmp(fileName);
}
//===================================================================================================================
//將全圖在hdc指向的窗口顯示,(x,y,w,h)為窗口上的矩形
void CBmp24::DrawDC(HDC hdc,int x,int y,int w,int h)
{
StretchDIBits(hdc,x,y,w,h,0,0,m_BmpInf.bmiHeader.biWidth,m_BmpInf.bmiHeader.biHeight,m_pBits,&m_BmpInf,DIB_RGB_COLORS,SRCCOPY);
}
//===================================================================================================================
void CBmp24::DrawBmp(CBmp24*p,int tx,int ty,int Idx,int effectFlag)
{
if(!m_bTrasparented) DrawBmpEx(p,tx,ty,0,0,m_BmpInf.bmiHeader.biWidth,m_BmpInf.bmiHeader.biHeight,effectFlag);
else DrawBmpEx(p,tx,ty,0,0,m_BmpInf.bmiHeader.biWidth,m_BmpInf.bmiHeader.biHeight,effectFlag,m_TransparentColor);
}
//==============================================================================================
//參數: CBmp24* p 指向目標圖
// int tx 在目標圖上開始畫圖的水平坐標
// int ty 在目標圖上開始畫圖的垂直坐標
// int sx 本圖上需畫圖的水平起始坐標
// int sy 本圖上需畫圖的垂直起始坐標
// int w 本圖上需畫圖的水平長度
// int h 本圖上需畫圖的垂直高度
// int flipType 畫圖的翻轉標志,0不翻轉,1水平翻轉,2垂直翻轉,3完全翻轉
//===============================================================================================
//功能:將本圖上的(sx,sy,w,h)矩形,畫到p指向的目標圖上,在目標圖上以坐標(tx,ty)開始花起
// 同時,flipType指定了畫圖時的翻轉操作。
//===============================================================================================
void CBmp24::DrawBmpEx(CBmp24*p,int tx,int ty,int sx,int sy,int w,int h,int flipType)
{
int i,j,t,s,cx=w,cy=h;
long w1=p->GetWidth();
long h1=p->GetHeight();
long w0=m_BmpInf.bmiHeader.biWidth;
long h0=m_BmpInf.bmiHeader.biHeight;
unsigned char* pBits1=p->GetDateBits();
unsigned char* pBits0=this->GetDateBits();
if(tx+cx>=w1) cx=w1-tx;//先檢查下是否超界
if(ty+cy>=h1) cy=h1-ty;
if(tx<0) {sx-=tx;cx=cx+tx;tx=0;}
if(ty<0) {sy-=ty;cy=cy+ty;ty=0;}
for(j=0;j<cy;j++)
for(i=0;i<cx;i++)
{
t=((h1-ty-j-1)*w1+tx+i)*3;
s=FlipCount(flipType,sx,sy,cx,cy,j,i);
pBits1[t+0]=pBits0[s+0];
pBits1[t+1]=pBits0[s+1];
pBits1[t+2]=pBits0[s+2];
}
}
//==============================================================================================
//與上面的函數唯一的區別,就是cTransparentColor指定的透明色不會被畫
void CBmp24::DrawBmpEx(CBmp24*p,int tx,int ty,int sx,int sy,int w,int h,int flipType,COLORREF cTransparentColor)
{
int i,j,t,s,cx=w,cy=h;
long w1=p->GetWidth();
long h1=p->GetHeight();
long w0=m_BmpInf.bmiHeader.biWidth;
long h0=m_BmpInf.bmiHeader.biHeight;
unsigned char* pBits1=p->GetDateBits();
unsigned char* pBits0=this->GetDateBits();
unsigned char *pTrasparentColor=(unsigned char *)&cTransparentColor;
if(tx+cx>=w1) cx=w1-tx;
if(ty+cy>=h1) cy=h1-ty;
if(tx<0) {sx-=tx;cx=cx+tx;tx=0;}
if(ty<0) {sy-=ty;cy=cy+ty;ty=0;}
for(j=0;j<cy;j++)
for(i=0;i<cx;i++)
{
t=((h1-ty-j-1)*w1+tx+i)*3;
s=FlipCount(flipType,sx,sy,cx,cy,j,i);
if(pTrasparentColor[2]!=pBits0[s+0]|| pTrasparentColor[1]!=pBits0[s+1]|| pTrasparentColor[0]!=pBits0[s+2])
{
pBits1[t+0]=pBits0[s+0];
pBits1[t+1]=pBits0[s+1];
pBits1[t+2]=pBits0[s+2];
}
}
}
//==============================================================================================
//參數: type 畫圖的翻轉標志,0不翻轉,1水平翻轉,2垂直翻轉,3完全翻轉
// x 本圖上需畫圖的水平起始坐標
// y 本圖上需畫圖的垂直起始坐標
// w 本圖上需畫圖的水平長度
// h 本圖上需畫圖的垂直高度
// i 在本圖上需畫圖的矩形區域中的水平坐標(相對小矩形的)
// j 在本圖上需畫圖的矩形區域中的垂直坐標(相對小矩形的)
//==============================================================================================
//功能:指定矩形(x,y,w,h)中的坐標(i,j),及所需要翻轉的標志,算出該點在本圖像素緩沖區中的位置。
//===============================================================================================
int CBmp24::FlipCount(int type,int x,int y,int w,int h,int j,int i)
{
int W=m_BmpInf.bmiHeader.biWidth;
int H=m_BmpInf.bmiHeader.biHeight;
if(type==0)//不翻轉
{
y=y+j;
x=x+i;
}
else if(type==1)//水平翻轉
{
y=y+j;
x=x+w-i-1;
}
else if(type==2)//垂直翻轉
{
y=y+h-j-1;
x=x+i;
}
else if(type==3) //完全翻轉
{
y=y+h-j-1;
x=x+w-i-1;
}
return ((H-y-1)*W+x)*3;
}
//===================================================================================================================
void CBmp24::MemsetBits(int i)
{
memset(m_pBits,i,m_BmpInf.bmiHeader.biSizeImage);
}
//===================================================================================================================
CBmp24::CBmp24()
{
memset(&m_BmpInf,0,sizeof(m_BmpInf));
m_pBits=NULL;
}
//===================================================================================================================
CBmp24::~CBmp24()
{
if(m_pBits!=NULL)
{
free(m_pBits);
m_pBits=NULL;
}
}
//=====================組圖處理的具體實現=====================================================
bool CMultiBmp::LoadBmp(char *fileName,int colum,int row)
{
bool r;
m_Colum=colum; //有多少列小圖
m_Row=row; //有多少行小圖
m_bTrasparented=0;
r=CBmp24::LoadBmp(fileName);
m_SubWidth = m_BmpInf.bmiHeader.biWidth/m_Colum;
m_SubHeight = m_BmpInf.bmiHeader.biHeight/m_Row;
return r;
}
//===================================================================================================================
bool CMultiBmp::LoadBmp(char *fileName,int colum,int row,COLORREF cTransparentColor)
{
bool r;
m_Colum=colum; //有多少列小圖
m_Row=row; //有多少行小圖
m_bTrasparented=1;
m_TransparentColor=cTransparentColor;
r=CBmp24::LoadBmp(fileName);
m_SubWidth = m_BmpInf.bmiHeader.biWidth/m_Colum;
m_SubHeight = m_BmpInf.bmiHeader.biHeight/m_Row;
return r;
}
//===================================================================================================================
void CMultiBmp::DrawBmp(CBmp24*p,int tx,int ty,int Idx,int effectFlag)
{
Idx=Idx%(m_Row*m_Colum);
int c=Idx%m_Colum;
int r=Idx/m_Colum;
int w=m_SubWidth;
int h=m_SubHeight;
if(!m_pBits) return;
if(!m_bTrasparented) DrawBmpEx(p,tx,ty,c*w,r*h,w,h,effectFlag);
else DrawBmpEx(p,tx,ty,c*w,r*h,w,h,effectFlag,m_TransparentColor);
}
//===================================================================================================================
void CMultiBmp::DrawDC(HDC hdc,int x,int y,int w,int h,int Idx)
{
int c=Idx%m_Colum;
int r=m_Row-Idx/m_Colum-1;//bmp圖像是按照從下往上放的
StretchDIBits(hdc,x,y,w,h,c*m_SubWidth,r*m_SubHeight,m_SubWidth,m_SubHeight,m_pBits,&m_BmpInf,DIB_RGB_COLORS,SRCCOPY);
}
//===================================================================================================================
CMultiBmp::CMultiBmp()
{
memset(&m_BmpInf,0,sizeof(m_BmpInf));
m_pBits=NULL;
}
//===================================================================================================================
CMultiBmp::~CMultiBmp()
{
if(m_pBits!=NULL)
{
free(m_pBits);
m_pBits=NULL;
}
}
//===================================================================================================================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -