现在急需一个vc6.0下面的dib缩放的函数,但是因为以前对图形处理不太熟悉,所以请教各位了。
找到一个vc.net的代码,不过在vc6.0无法通过编译,如何通过一些修改使其在vc6.0下工作?HDIB ChangeDIBSize(HDIB hDIB, int nWidth, int nHeight)
{
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap,
hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;
HDIB hNewDIB;
DWORD dwSize; WaitCursorBegin(); // Get DIB pointer
if (! hDIB)
{
WaitCursorEnd();
return NULL;
} LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
if (! lpSrcDIB)
{
WaitCursorEnd();
return NULL;
} // Allocate and fill out a BITMAPINFO struct for the new DIB dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) +PaletteSize(lpSrcDIB); lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize ); memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize); lpbmi->bmiHeader.biWidth = nWidth; lpbmi->bmiHeader.biHeight = nHeight; // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em hDC = GetDC( NULL ); hTargetBitmap = CreateDIBSection( hDC, lpbmi,DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 ); hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB,DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 ); hSourceDC = CreateCompatibleDC( hDC ); hTargetDC = CreateCompatibleDC( hDC ); // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight *BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader)); dwTargetBitsSize = lpbmi->bmiHeader.biHeight *BytesPerLine((LPBYTE)&(lpbmi->bmiHeader)); memcpy( lpSourceBits, FindDIBBits((LPBYTE)lpSrcDIB), dwSourceBitsSize ); lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize; // Select DIBSections into DCs hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap ); hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap ); // put old bitmap in new bitmap SetStretchBltMode( hTargetDC, COLORONCOLOR ); StretchBlt( hTargetDC, 0, 0,lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight,hSourceDC, 0, 0,lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight,SRCCOPY ); // Clean up and delete the DCs SelectObject( hSourceDC, hOldSourceBitmap ); SelectObject( hTargetDC, hOldTargetBitmap );
DeleteDC( hSourceDC );
DeleteDC( hTargetDC );
ReleaseDC( NULL, hDC ); // Flush the GDI batch, so we can play with the bits
GdiFlush(); // Allocate enough memory for the new CF_DIB, and copy bits dwSize = dwTargetHeaderSize + dwTargetBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize);
lpResult = (LPBYTE)GlobalLock(hNewDIB);
memcpy( lpResult, lpbmi, dwTargetHeaderSize );
memcpy( FindDIBBits( (LPBYTE)lpResult ), lpTargetBits, dwTargetBitsSize );
// final cleanup DeleteObject( hTargetBitmap );
DeleteObject( hSourceBitmap );
free( lpbmi );
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
WaitCursorEnd();
return hNewDIB;}
找到一个vc.net的代码,不过在vc6.0无法通过编译,如何通过一些修改使其在vc6.0下工作?HDIB ChangeDIBSize(HDIB hDIB, int nWidth, int nHeight)
{
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap,
hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;
HDIB hNewDIB;
DWORD dwSize; WaitCursorBegin(); // Get DIB pointer
if (! hDIB)
{
WaitCursorEnd();
return NULL;
} LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
if (! lpSrcDIB)
{
WaitCursorEnd();
return NULL;
} // Allocate and fill out a BITMAPINFO struct for the new DIB dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) +PaletteSize(lpSrcDIB); lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize ); memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize); lpbmi->bmiHeader.biWidth = nWidth; lpbmi->bmiHeader.biHeight = nHeight; // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em hDC = GetDC( NULL ); hTargetBitmap = CreateDIBSection( hDC, lpbmi,DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 ); hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB,DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 ); hSourceDC = CreateCompatibleDC( hDC ); hTargetDC = CreateCompatibleDC( hDC ); // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight *BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader)); dwTargetBitsSize = lpbmi->bmiHeader.biHeight *BytesPerLine((LPBYTE)&(lpbmi->bmiHeader)); memcpy( lpSourceBits, FindDIBBits((LPBYTE)lpSrcDIB), dwSourceBitsSize ); lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize; // Select DIBSections into DCs hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap ); hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap ); // put old bitmap in new bitmap SetStretchBltMode( hTargetDC, COLORONCOLOR ); StretchBlt( hTargetDC, 0, 0,lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight,hSourceDC, 0, 0,lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight,SRCCOPY ); // Clean up and delete the DCs SelectObject( hSourceDC, hOldSourceBitmap ); SelectObject( hTargetDC, hOldTargetBitmap );
DeleteDC( hSourceDC );
DeleteDC( hTargetDC );
ReleaseDC( NULL, hDC ); // Flush the GDI batch, so we can play with the bits
GdiFlush(); // Allocate enough memory for the new CF_DIB, and copy bits dwSize = dwTargetHeaderSize + dwTargetBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize);
lpResult = (LPBYTE)GlobalLock(hNewDIB);
memcpy( lpResult, lpbmi, dwTargetHeaderSize );
memcpy( FindDIBBits( (LPBYTE)lpResult ), lpTargetBits, dwTargetBitsSize );
// final cleanup DeleteObject( hTargetBitmap );
DeleteObject( hSourceBitmap );
free( lpbmi );
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
WaitCursorEnd();
return hNewDIB;}
下面这个是我写的使用双二次线性插值的图像缩放函数:#ifdef __cplusplus
extern "C"{
#endif#define SIZING_BY_PROPORTION 0 //根据比例缩放图像
#define SIZING_BY_SIZE 1 //根据给定的新尺寸缩放图像typedef struct tagImageData{
DWORD dwWidth;
DWORD dwHeight;
LPBYTE lpData32;
}IMAGEDATA,*PIMAGEDATA;typedef struct tagProcessData{
DWORD dwSize; // 结构尺寸
DWORD dwProcType; // 处理类型
HWND hParent; // 主窗口
DWORD dwPara1; // 参数1
DWORD dwPara2; // 参数2
DWORD dwPara3; // 参数3
DWORD dwPara4; // 参数4
LPVOID lpVoid; // 附加数据指针
} PROCESSDATA,*PPROCESSDATA;
DWORD WINAPI Mirror(IN PIMAGEDATA dataIn,
IN PPROCESSDATA dataProc,
OUT PIMAGEDATA dataOut);
DWORD WINAPI Rote(IN PIMAGEDATA dataIn,
IN PPROCESSDATA dataProc,
OUT PIMAGEDATA dataOut);
DWORD WINAPI Scale(IN PIMAGEDATA dataIn,
IN PPROCESSDATA dataProc,
OUT PIMAGEDATA dataOut);
#ifdef __cplusplus
};
#endif
__inline int Bound(int x,int min,int max)
{
return (x<min)?min:(x>max)?max:x;
}
double SinXpX(double x)
{
double absx = fabs(x);
double xx = absx * absx;
double xxx = xx * absx;
if(absx < 1.0) return 1.0 - 2.0 * xx + xxx;
else if(absx < 2.0) return 4.0 - 8.0 * absx + 5.0 * xx - xxx;
else return 0.0;
}
DWORD WINAPI Scale(IN PIMAGEDATA dataIn,
IN PPROCESSDATA dataProc,
OUT PIMAGEDATA dataOut)
{
if(dataIn->lpData32 == NULL || dataIn->dwHeight<=0 || dataIn->dwWidth<=0)
return -1;
DWORD dwLineBytes = dataIn->dwWidth * 4;
DWORD dwLen = dwLineBytes * dataIn->dwHeight;
if(IsBadReadPtr(dataIn->lpData32,dwLen)) return -1;
// Old Image Size // New Image Size
switch(dataProc->dwProcType){
case SIZING_BY_PROPORTION:
dataOut->dwWidth = (dataIn->dwWidth * dataProc->dwPara1 + 50) / 100;
dataOut->dwHeight = (dataIn->dwHeight * dataProc->dwPara2 + 50) / 100;
break;
case SIZING_BY_SIZE:
dataOut->dwWidth = dataProc->dwPara1;
dataOut->dwHeight = dataProc->dwPara2;
break;
default:
return -1;
}
DWORD dwOutLineBytes = dataOut->dwWidth * 4;
DWORD dwOutLen = dwOutLineBytes * dataOut->dwHeight; // malloc memory for image data
try{
dataOut->lpData32 = new BYTE[dwOutLen];
}catch(CMemoryException*pe){
pe->ReportError();
return -1;
} // calc new image pixel value (Use Three Order Interpolate)
float fScaleX = (float) dataIn->dwWidth / (float) dataOut->dwWidth;
float fScaleY = (float) dataIn->dwHeight / (float) dataOut->dwHeight;
LPBYTE pOut = dataOut->lpData32; for(DWORD dwy = 0;dwy<dataOut->dwHeight;++dwy){
float fInvY = dwy * fScaleY;
int iy = (int)fInvY;
float fv = fInvY - iy; LPBYTE pInLineHead = dataIn->lpData32 + iy * dwLineBytes; for(DWORD dwx = 0;dwx<dataOut->dwWidth;++dwx){
float fInvX = dwx * fScaleX;
int ix = (int)fInvX;
float fu = fInvX - ix; LPBYTE pIn = pInLineHead + ix * 4; // Three Order Interpolate
// Get 16 Pixel near the point(fInvX,fInvY).
int xx[4],yy[4];
xx[0] = -1; xx[1] = 0; xx[2] = 1; xx[3] = 2;
yy[0] = -1; yy[1] = 0; yy[2] = 1; yy[3] = 2; if((ix - 1) < 0) xx[0] = 0;
if((ix + 1) > (int)(dataIn->dwWidth - 1)) xx[2] = 0;
if((ix + 2) > (int)(dataIn->dwWidth - 1)) xx[3] = (xx[2] == 0)?0:1; if((iy - 1) < 0) yy[0] = 0;
if((iy + 1) > (int)(dataIn->dwHeight - 1)) yy[2] = 0;
if((iy + 2) > (int)(dataIn->dwHeight - 1)) yy[3] = (yy[2] == 0)?0:1; // Src pixel value
BYTE red[4][4],green[4][4],blue[4][4]; int i,j;
for(i = 0; i < 4; ++i){
LPBYTE pBaseLine = pIn + yy[i] * dwLineBytes;
for(j = 0; j < 4; ++j){
LPBYTE pBase = pBaseLine + xx[j] * 4;
red [i][j] = *pBase++;
green[i][j] = *pBase++;
blue [i][j] = *pBase++;
}
} // u,v vector
float afu[4],afv[4];
afu[0] = (float)SinXpX(1.0 + fu); afv[0] = (float)SinXpX(1.0 + fv);
afu[1] = (float)SinXpX(fu); afv[1] = (float)SinXpX(fv);
afu[2] = (float)SinXpX(1.0 - fu); afv[2] = (float)SinXpX(1.0 - fv);
afu[3] = (float)SinXpX(2.0 - fu); afv[3] = (float)SinXpX(2.0 - fv); float afr[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float afg[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float afb[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for(i = 0; i < 4; ++i){
for(j = 0; j < 4; ++j){
afr[i] += afv[j] * red[j][i];
afg[i] += afv[j] * green[j][i];
afb[i] += afv[j] * blue[j][i];
}
} // New pixel value
*pOut++ = (BYTE)Bound(
(int)(afu[0] * afr[0] + afu[1] * afr[1] +
afu[2] * afr[2] + afu[3] * afr[3] + 0.5f),0,255);
*pOut++ = (BYTE)Bound(
(int)(afu[0] * afg[0] + afu[1] * afg[1] +
afu[2] * afg[2] + afu[3] * afg[3] + 0.5f),0,255);
*pOut++ = (BYTE)Bound(
(int)(afu[0] * afb[0] + afu[1] * afb[1] +
afu[2] * afb[2] + afu[3] * afb[3] + 0.5f),0,255);
*pOut++ = (BYTE)0; }
} return 0;
}