📄 dib.cpp
字号:
deltax=(float)xs/xd;
deltay=(float)ys/yd;
DWORD dwBitsSize = sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD)+(DWORD)xd*(DWORD)yd;
HDIB d=(HDIB)::GlobalReAlloc(m_hDIB,dwBitsSize,GMEM_MOVEABLE | GMEM_ZEROINIT);
LPSTR pDIB;
LPBITMAPINFOHEADER lpBMIH;
LPBITMAPINFO lpbmi;
m_hDIB=d;
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpBMIH = (LPBITMAPINFOHEADER)pDIB;
lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth = (DWORD)xd;
lpBMIH->biHeight = (DWORD)yd;
m_nWidth=lpBMIH->biWidth;
m_nHeight=lpBMIH->biHeight;
lpBMIH->biPlanes = 1;
lpBMIH->biBitCount = 8;
lpBMIH->biCompression = 0;
lpBMIH->biSizeImage = (DWORD)xd*(DWORD)yd;
lpBMIH->biXPelsPerMeter = 0;
lpBMIH->biYPelsPerMeter = 0;
lpBMIH->biClrUsed =256;
lpBMIH->biClrImportant =0;
lpbmi=(LPBITMAPINFO)pDIB;
for (i = 0; i < 256; i++)
{
lpbmi->bmiColors[i].rgbRed=i;
lpbmi->bmiColors[i].rgbGreen=i;
lpbmi->bmiColors[i].rgbBlue=i;
lpbmi->bmiColors[i].rgbReserved = 0;
}
m_nWidth=xd;
m_nHeight=yd;
oi=new unsigned char*[xd];
array=(LPSTR)FindDIBBits(); // TODO: Add your command handler code here
for(y=0;y<yd;y++)
{
oi[y]=(unsigned char*)array+xd*y;
}
for(gy=0;gy<=yd-1;gy++)
{
ydist=gy-1;
yy=1.0+ydist*deltay;
y1=yy;y2=y1+1;
for(gx=0;gx<=xd-1;gx++)
{
xdist=gx-1;
xx=1.0+xdist*deltax;
x1=xx;x2=x1+1;
dx=xx-x1;dx1=1.0-dx;
dy=yy-y1;dy1=1.0-dy;
zz=(float)image[y1][x1]*dx1*dy1+(float)image[y2][x1]*dx*dy1+(float)image[y1][x2]*dx1*dy+(float)image[y2][x2]*dx*dy;
oi[gy][gx]=zz+.5;
}
}
delete oi;
}
//得到一行的象素值
void CDIB::ReplaceHDIB(HDIB hDIB)
{
if(m_hDIB!=NULL)
{
::GlobalFree((HGLOBAL)m_hDIB);
}
m_hDIB=hDIB;
}
void CDIB::InitDIBData()
{
if (m_pPal != NULL)
{
delete m_pPal;
m_pPal = NULL;
}
if (m_hDIB == NULL)
{
return;
}
// Set up document size
if (DIBWidth() > INT_MAX || DIBHeight() > INT_MAX)
{
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalFree((HGLOBAL) m_hDIB);
m_hDIB = NULL;
CString strMsg;
MessageBox(NULL, "位图太大了,无法完成操作!", NULL, MB_ICONINFORMATION | MB_OK);
return;
}
m_nWidth =DIBWidth();
m_nHeight =DIBHeight();
::GlobalUnlock((HGLOBAL) m_hDIB);
// Create copy of palette
m_pPal = new CPalette;
if (m_pPal == NULL)
{
// we must be really low on memory
::GlobalFree((HGLOBAL) m_hDIB);
m_hDIB = NULL;
return;
}
}
void CDIB::Enlarge(CSize dSize)
{
LPSTR array;
int x,y,nSourWidth,nSourHeight;
RGBTRIPLE** oi;
RGBTRIPLE** Old;
nSourWidth =m_nWidth;
nSourHeight =m_nHeight;
oi=new RGBTRIPLE *[m_nHeight];
array=(LPSTR)FindDIBBits();
for(y=0;y<m_nHeight;y++)
{
oi[y]=(RGBTRIPLE *)array+m_nWidth*y;
}
Make2DArray(Old,m_nHeight,m_nWidth);
//保存原先的值
for(y=0;y<m_nHeight;y++)
for(x=0;x<m_nWidth;x++)
{
Old[y][x].rgbtRed=oi[y][x].rgbtRed;
Old[y][x].rgbtGreen=oi[y][x].rgbtGreen;
Old[y][x].rgbtBlue=oi[y][x].rgbtBlue;
}
delete oi;
::GlobalUnlock(array);
DWORD dwBitsSize = sizeof(BITMAPINFOHEADER)+WIDTHBYTES(dSize.cx*24)*dSize.cy;
HDIB d=(HDIB)::GlobalReAlloc(m_hDIB,dwBitsSize,GMEM_MOVEABLE | GMEM_ZEROINIT);
LPSTR pDIB;
LPBITMAPINFOHEADER lpBMIH;
m_hDIB=d;
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpBMIH = (LPBITMAPINFOHEADER)pDIB;
lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth = (DWORD)dSize.cx ;
lpBMIH->biHeight = (DWORD)dSize.cy ;
lpBMIH->biPlanes = 1;
lpBMIH->biBitCount = 24;
lpBMIH->biCompression = BI_RGB;
lpBMIH->biSizeImage = 0;
lpBMIH->biXPelsPerMeter = 0;
lpBMIH->biYPelsPerMeter = 0;
lpBMIH->biClrUsed =0;
lpBMIH->biClrImportant =0;
m_nWidth=lpBMIH->biWidth;
m_nHeight=lpBMIH->biHeight;
oi=new RGBTRIPLE *[m_nHeight];
array=(LPSTR)FindDIBBits();
for(y=0;y<m_nHeight;y++)
{
oi[y]=(RGBTRIPLE *)array+m_nWidth*y;
}
int xdist,ydist,x1,x2,y1,y2;
float deltax,deltay,dx,dx1,dy,dy1,xx,yy,zz;
deltax=(float)nSourWidth/m_nWidth;
deltay=(float)nSourHeight/m_nHeight;
for(int gy=0;gy<=m_nHeight-1;gy++)
{
ydist=gy-1;
yy=1.0+ydist*deltay;
y1=yy;
y2=y1+1;
for(int gx=0;gx<=m_nWidth-1;gx++)
{
xdist=gx-1;
xx=1.0+xdist*deltax;
x1=xx;
x2=x1+1;
dx=xx-x1;
dx1=1.0-dx;
dy=yy-y1;
dy1=1.0-dy;
if(y1<0)y1=0;
if(y1>=nSourHeight)y1=nSourHeight-1;
if(x1<0)x1=0;
if(x1>=nSourWidth)x1=nSourWidth-1;
if(y2<0)y2=0;
if(y2>=nSourHeight)y2=nSourHeight-1;
if(x2<0)x2=0;
if(x2>=nSourWidth)x2=nSourWidth-1;
zz=(float)Old[y1][x1].rgbtRed*dx1*dy1+
(float)Old[y2][x1].rgbtRed*dx*dy1+
(float)Old[y1][x2].rgbtRed*dx1*dy+
(float)Old[y2][x2].rgbtRed*dx*dy;
oi[gy][gx].rgbtRed=zz+.5;
zz=(float)Old[y1][x1].rgbtGreen*dx1*dy1+
(float)Old[y2][x1].rgbtGreen*dx*dy1+
(float)Old[y1][x2].rgbtGreen*dx1*dy+
(float)Old[y2][x2].rgbtGreen*dx*dy;
oi[gy][gx].rgbtGreen=zz+.5;
zz=(float)Old[y1][x1].rgbtBlue*dx1*dy1+
(float)Old[y2][x1].rgbtBlue*dx*dy1+
(float)Old[y1][x2].rgbtBlue*dx1*dy+
(float)Old[y2][x2].rgbtBlue*dx*dy;
oi[gy][gx].rgbtBlue=zz+.5;
}
}
delete oi;
Delete2DArray(Old,nSourHeight);
::GlobalUnlock((HGLOBAL)m_hDIB);
}
//Rotate the picture to a certain angle
void CDIB::Rotate(BOOL bLeftOrRight)
{
int nNewWidth,nNewHeight,x,y;
int Width=m_nWidth,Height=m_nHeight;
nNewWidth=Height;
nNewHeight=Width;
LPBITMAPINFOHEADER lpBmp,lpSourBitmapHeader;
LPSTR lpDib,lpNewDib;
LPBYTE lpRgb_Sour,lpRgb_Dest;
DWORD dwBytesPerLine_Sour,dwBytesPerLine_Dest;
DWORD dwSourPos,dwDestPos,dwMemSize;
HDIB m_hNewDib;
dwBytesPerLine_Sour=WIDTHBYTES((int)(24*Width));
dwBytesPerLine_Dest=WIDTHBYTES((int)(24*nNewWidth));
dwMemSize=dwBytesPerLine_Dest*nNewHeight+sizeof(BITMAPINFOHEADER);
//开始分配旋转后的内存
m_hNewDib=(HDIB)::GlobalAlloc(GHND,dwMemSize);
if(m_hNewDib==NULL)
{
// AfxMessageBox("无法分配内存!",MB_OK+MB_ICONSTOP);
return ;
}
//新缓冲区
lpNewDib=(LPSTR)::GlobalLock((HGLOBAL)m_hNewDib);
//源缓冲区
lpDib =(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
memset(lpNewDib,0,dwMemSize);
lpSourBitmapHeader=(LPBITMAPINFOHEADER)lpDib;
lpBmp=(LPBITMAPINFOHEADER)lpNewDib;
lpBmp->biWidth=nNewWidth;
lpBmp->biHeight=nNewHeight;
lpBmp->biBitCount=24;
lpBmp->biClrImportant=lpSourBitmapHeader->biClrImportant;
lpBmp->biClrUsed=lpSourBitmapHeader->biClrUsed;
lpBmp->biCompression=lpSourBitmapHeader->biCompression;
lpBmp->biPlanes=lpSourBitmapHeader->biPlanes;
lpBmp->biSize=sizeof(BITMAPINFOHEADER);
lpBmp->biSizeImage=0;
lpBmp->biXPelsPerMeter=lpSourBitmapHeader->biXPelsPerMeter ;
lpBmp->biYPelsPerMeter=lpSourBitmapHeader->biYPelsPerMeter ;
lpRgb_Sour =(LPBYTE)(lpDib+*(LPDWORD)lpDib);
lpRgb_Dest =(LPBYTE)(lpNewDib+*(LPDWORD)lpNewDib);
if(bLeftOrRight)//左旋
{
for(y=0;y<Width;y++)
for(x=0;x<Height;x++)
{
dwSourPos=y*dwBytesPerLine_Dest+x*3;
dwDestPos=x*dwBytesPerLine_Sour+(Width-y-1)*3;
*(lpRgb_Dest+dwSourPos+2)=*(lpRgb_Sour+dwDestPos+2);
*(lpRgb_Dest+dwSourPos+1)=*(lpRgb_Sour+dwDestPos+1);
*(lpRgb_Dest+dwSourPos+0)=*(lpRgb_Sour+dwDestPos+0);
dwSourPos+=3;
dwDestPos+=3;
}
}
else //右旋
{
for(y=0;y<Width;y++)
for(x=0;x<Height;x++)
{
dwSourPos=y*dwBytesPerLine_Dest+x*3;
dwDestPos=(Height-x-1)*dwBytesPerLine_Sour+y*3;
*(lpRgb_Dest+dwSourPos+2)=*(lpRgb_Sour+dwDestPos+2);
*(lpRgb_Dest+dwSourPos+1)=*(lpRgb_Sour+dwDestPos+1);
*(lpRgb_Dest+dwSourPos+0)=*(lpRgb_Sour+dwDestPos+0);
dwSourPos+=3;
dwDestPos+=3;
}
}
m_lpBitmapInfoHeader=(LPBITMAPINFOHEADER)lpNewDib;
m_lpDIB=(lpNewDib+ *(LPDWORD)lpNewDib+PaletteSize(lpNewDib));
m_nWidth=nNewWidth;
m_nHeight=nNewHeight;
m_nWidthOfByte=WIDTHBYTES(m_nWidth*24);
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
::GlobalUnlock((HGLOBAL)m_hNewDib);
m_hDIB=m_hNewDib;
}
//旋转任意角度
void CDIB::Rotate(float fAngle)
{
float PI;
PI=(float)4.0*atan(1.0);
if(fAngle<0.0)
fAngle=fAngle+360;
fAngle=fAngle*PI/180.0;
//求新的高和宽
float x1,x2,x3,x4,y1,y2,y3,y4,xmax,xmin;
float x11,x22,x33,x44,y11,y22,y33,y44,ymax,ymin;
int nNewWidth,nNewHeight;
float nWidth=m_nWidth,nHeight=m_nHeight;
x1=0;
x2=0;
x3 =nWidth-1;
x4 =nWidth-1;
y1=0;
y2=nHeight-1;
y3=0;
y4=nHeight-1;
x1=float(x1-nWidth/2);
y1=float(-y1+nHeight/2);
x11=float(x1*cos(fAngle)-y1*sin(fAngle));
y11=float(x1*sin(fAngle)+y1*cos(fAngle));
x2=float(x2-nWidth/2);
y2=float(-y2+nHeight/2);
x22=float(x2*cos(fAngle)-y2*sin(fAngle));
y22=float(x2*sin(fAngle)+y2*cos(fAngle));
x3=float(x3-nWidth/2);
y3=float(-y3+nHeight/2);
x33=float(x3*cos(fAngle)-y3*sin(fAngle));
y33=float(x3*sin(fAngle)+y3*cos(fAngle));
x4=float(x4-nWidth/2);
y4=float(-y4+nHeight/2);
x44=float(x4*cos(fAngle)-y4*sin(fAngle));
y44=float(x4*sin(fAngle)+y4*cos(fAngle));
xmax =max(x11,max(x22,max(x33,x44)));
xmin=min(x11,min(x22,min(x33,x44)));
ymax=max(y11,max(y22,max(y33,y44)));
ymin=min(y11,min(y22,min(y33,y44)));
nNewWidth=xmax-xmin+1;
nNewHeight=ymax-ymin+1;
LPBITMAPINFOHEADER lpBmp,lpSourBitmapHeader;
LPSTR lpDib,lpNewDib;
LPBYTE lpRgb_Sour,lpRgb_Dest;
DWORD dwBytesPerLine_Sour,dwBytesPerLine_Dest;
DWORD dwMemSize;
HDIB m_hNewDib;
dwBytesPerLine_Sour=WIDTHBYTES((int)(24*nWidth));
dwBytesPerLine_Dest=WIDTHBYTES((int)(24*nNewWidth));
dwMemSize=dwBytesPerLine_Dest*nNewHeight+sizeof(BITMAPINFOHEADER);
//开始分配旋转后的内存
m_hNewDib=(HDIB)::GlobalAlloc(GHND,dwMemSize);
if(m_hNewDib==NULL)
{
AfxMessageBox("无法分配内存!",MB_OK+MB_ICONSTOP);
return ;
}
//新缓冲区
lpNewDib=(LPSTR)::GlobalLock((HGLOBAL)m_hNewDib);
//源缓冲区
lpDib =(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
memset(lpNewDib,255,dwMemSize);
lpSourBitmapHeader=(LPBITMAPINFOHEADER)lpDib;
lpBmp=(LPBITMAPINFOHEADER)lpNewDib;
lpBmp->biWidth=nNewWidth;
lpBmp->biHeight=nNewHeight;
lpBmp->biBitCount=24;
lpBmp->biClrImportant=lpSourBitmapHeader->biClrImportant;
lpBmp->biClrUsed=lpSourBitmapHeader->biClrUsed;
lpBmp->biCompression=lpSourBitmapHeader->biCompression;
lpBmp->biPlanes=lpSourBitmapHeader->biPlanes;
lpBmp->biSize=sizeof(BITMAPINFOHEADER);
lpBmp->biSizeImage=0;
lpBmp->biXPelsPerMeter=lpSourBitmapHeader->biXPelsPerMeter ;
lpBmp->biYPelsPerMeter=lpSourBitmapHeader->biYPelsPerMeter ;
lpRgb_Sour =(LPBYTE)(lpDib+*(LPDWORD)lpDib);
lpRgb_Dest =(LPBYTE)(lpNewDib+*(LPDWORD)lpNewDib);
double x5,x6,y5,y6;
for(int y=0;y<nNewHeight;y++)
{
for(int x=0;x<nNewWidth;x++)
{
x5=double(x-nNewWidth/2);
y5=double(-y+nNewHeight/2);
x6=double(x5*cos(fAngle)-y5*sin(fAngle)+0.5);
y6=double(x5*sin(fAngle)+y5*cos(fAngle)+0.5);
x5=double(x6+nWidth/2);
y5=double(-y6+nHeight/2);
if( (x5>=0) && (x5<nWidth) && (y5>=0) && (y5<nHeight) )
{
if(y5<0) y5=0;
if(x5<0) x5=0;
if(y5>nHeight) y5=nHeight-1;
if(x5>nWidth) x5=nWidth-1;
//边界处理
if( ((int)x5==0)||((int)x5==nWidth-1)||((int)y5==0)||((int)y5==nHeight-1) )
{
for(int i=0;i<3;i++)
*(lpRgb_Dest +x*3+i+y*dwBytesPerLine_Dest)=*(lpRgb_Sour +(int)x5*3+i+(int)y5*dwBytesPerLine_Sour);
}
else
{
double r1,r2,r3,r4;
double g1,g2,g3,g4;
double b1,b2,b3,b4;
double dis1=x5-(int)x5;
double dis2=1-x5+(int)x5;
double dis3=y5-(int)y5;
double dis4=1-y5+(int)y5;
r1=*(lpRgb_Sour+(int)x5*3+0+(int)y5*dwBytesPerLine_Sour);
g1=*(lpRgb_Sour+(int)x5*3+1+(int)y5*dwBytesPerLine_Sour);
b1=*(lpRgb_Sour+(int)x5*3+2+(int)y5*dwBytesPerLine_Sour);
r2=*(lpRgb_Sour+((int)x5+1)*3+0+(int)y5*dwBytesPerLine_Sour);
g2=*(lpRgb_Sour+((int)x5+1)*3+1+(int)y5*dwBytesPerLine_Sour);
b2=*(lpRgb_Sour+((int)x5+1)*3+2+(int)y5*dwBytesPerLine_Sour);
r3=*(lpRgb_Sour+(int)x5*3+0+((int)y5+1)*dwBytesPerLine_Sour);
g3=*(lpRgb_Sour+(int)x5*3+1+((int)y5+1)*dwBytesPerLine_Sour);
b3=*(lpRgb_Sour+(int)x5*3+2+((int)y5+1)*dwBytesPerLine_Sour);
r4=*(lpRgb_Sour+((int)x5+1)*3+0+((int)y5+1)*dwBytesPerLine_Sour);
g4=*(lpRgb_Sour+((int)x5+1)*3+1+((int)y5+1)*dwBytesPerLine_Sour);
b4=*(lpRgb_Sour+((int)x5+1)*3+2+((int)y5+1)*dwBytesPerLine_Sour);
int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1));
if(r>255)r=255;
int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1));
if(g>255)g=255;
int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1));
if(b>255)b=255;
*(lpRgb_Dest+x*3+0+y*dwBytesPerLine_Dest)=(BYTE)r;
*(lpRgb_Dest+x*3+1+y*dwBytesPerLine_Dest)=(BYTE)g;
*(lpRgb_Dest+x*3+2+y*dwBytesPerLine_Dest)=(BYTE)b;
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -