bmiHeader.biWidth; SrcHeight=BI->bmiHeader.biHeight; if (Resize"> bmiHeader.biWidth; SrcHeight=BI->bmiHeader.biHeight; if (Resize"> bmiHeader.biWidth; SrcHeight=BI->bmiHeader.biHeight; if (Resize">
//-----------------------------------------------------------------------------
// 이미지 크기 변경 (축소, 확대 가능)
// ResizeWidth, ResizeHeight 는 원래 이미지를 변경시킬 새로운 크기
// ResizeHeight==0 이면 ResizeWidth 기준으로 이미지 비율을 유지한 높이로 처리
//-----------------------------------------------------------------------------
HBITMAP WINAPI ResizeImage(HDC hDC, HBITMAP hBtmIn, int ResizeWidth, int ResizeHeight)
{
int DX, DY, SrcWidth, SrcHeight, Src1LineBytes, Dest1LineBytes, SrcPixelBytes;
UINT PSplitX, Ox1, Ox2, Oxp1, Oxp2, px, w,
PSplitY, Oy1, Oy2, Oyp1, Oyp2, py, h, Area, R,G,B;
LPBYTE lpD, lpS, lpSrcBits, lpDestBits;
HBITMAP hBtmOut=NULL;
CONST RGBQUAD *lpPal;
BITMAPINFO *BI;
if ((BI=GetBitmapBitsData(hDC, hBtmIn))==NULL) goto ProcExit; //주어진 HBITMAP의 이미지 데이터 추출
if (BI->bmiHeader.biBitCount<8) {Printf("ResizeImage() Not Support" CRLF); goto ProcExit;}
SrcWidth=BI->bmiHeader.biWidth;
SrcHeight=BI->bmiHeader.biHeight;
if (ResizeHeight==0) ResizeHeight=MulDiv(SrcHeight, ResizeWidth, SrcWidth);
lpPal=BI->bmiColors;
Src1LineBytes=GetBmp1LineBytes(SrcWidth, BI->bmiHeader.biBitCount); //클립보드에서 캡춰했을 때는 32임
SrcPixelBytes=BI->bmiHeader.biBitCount>>3;
if ((hBtmOut=MyCreateDIBitmapEx(hDC, ResizeWidth, ResizeHeight, 24, (LPVOID*)&lpDestBits, lpPal))==NULL) goto ProcExit; //새로 만들어질 HBITMAP 데이터의 이미지 버퍼를 얻음
Dest1LineBytes=GetBmp1LineBytes(ResizeWidth, 24);
PSplitX=(ResizeWidth<<8) / SrcWidth; //소스 1픽셀 폭이 목적지 256단계중 얼마냐?
PSplitY=(ResizeHeight<<8) / SrcHeight;
lpSrcBits=(LPBYTE)BI + BI->bmiHeader.biSize;
if (BI->bmiHeader.biBitCount<=8) lpSrcBits+=(int)(1<<BI->bmiHeader.biBitCount)*sizeof(RGBQUAD);
else if (BI->bmiHeader.biCompression==BI_BITFIELDS) lpSrcBits+=12;
Oy1=Oyp1=0;
for (DY=0; DY<ResizeHeight; DY++)
{
//lpD=lpDestBits + (ResizeHeight-DY-1)*Dest1LineBytes;
lpD=lpDestBits + DY*Dest1LineBytes;
Oy2=DivMod((DY+1)*SrcHeight, ResizeHeight, (int*)&Oyp2);
Oyp2=Oyp2*PSplitY/ResizeHeight; //Oyp2: 소숫점이하를 목적픽셀 256단계 중 얼마인지 계산
Ox1=Oxp1=0;
for (DX=0; DX<ResizeWidth; DX++)
{
Ox2=DivMod((DX+1)*SrcWidth, ResizeWidth, (int*)&Oxp2);
Oxp2=Oxp2*PSplitX/ResizeWidth;
R=G=B=0;
for (py=Oy1; py<=Oy2; py++)
{
if (py==Oy1) //첫번째줄
{
if (py==Oy2) h=Oyp2-Oyp1; //확대되는 경우
else h=PSplitY-Oyp1;
}
else if (py==Oy2) //마지막줄
{
if ((h=Oyp2)==0) break;
}
else h=PSplitY; //모든 픽셀이 포함된 줄
lpS=lpSrcBits + (SrcHeight-py-1)*Src1LineBytes + Ox1*SrcPixelBytes; //GetVScrMemPos(Ox1, py);
for (px=Ox1; px<=Ox2; px++)
{
if (px==Ox1) //시작점
{
if (px==Ox2) w=Oxp2-Oxp1;//확대되는 경우
else w=PSplitX-Oxp1;
}
else if (px==Ox2) //끝점
{
if ((w=Oxp2)==0) break;
}
else w=PSplitX; //중간점
Area=w*h; //뽑아낼 셀의 면적
if (SrcPixelBytes==1)
{
CONST RGBQUAD *P;
P=lpPal + *lpS;
B+=P->rgbBlue*Area;
G+=P->rgbGreen*Area;
R+=P->rgbRed*Area;
}
else if (SrcPixelBytes==2) //16Bit DIB는 565임
{
UINT Col;
Col=*(WORD*)lpS;
B+=((Col<<3)&0xF8)*Area;
G+=((Col>>3)&0xFC)*Area;
R+=((Col>>8)&0xF8)*Area;
}
else if (SrcPixelBytes==3)
{
B+=lpS[0]*Area;
G+=lpS[1]*Area;
R+=lpS[2]*Area;
}
else if (SrcPixelBytes==4)
{
DWORD Col;
Col=*(DWORD*)lpS;
B+=(Col&0xFF)*Area;
G+=((Col>>8)&0xFF)*Area;
R+=((Col>>16)&0xFF)*Area;
}
lpS+=SrcPixelBytes;
}
}
B>>=16; if (B>255) B=255;
G>>=16; if (G>255) G=255;
R>>=16; if (R>255) R=255;
*lpD++=(BYTE)B;
*lpD++=(BYTE)G;
*lpD++=(BYTE)R;
Ox1=Ox2; Oxp1=Oxp2;
}
Oy1=Oy2; Oyp1=Oyp2;
}
ProcExit:
FreeMem(BI);
return hBtmOut;
}