我用过StrecthDIBits,不错啊,而且好像一般放大缩小都用这个int DrawDIB(HDC hDC, CRect DCRect, HANDLE hDIB, CRect DIBRect, CPalette* pPal)
{
LPSTR    lpDIBHdr;
LPSTR    lpDIBBits;
int     bSuccess = 0;
HPALETTE hPal = NULL;
HPALETTE hOldPal = NULL;

if(hDIB == NULL)
return 0;
lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL) hDIB);
lpDIBBits = (LPSTR)(lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr));

if(pPal != NULL)
{
hPal = (HPALETTE) pPal->m_hObject;
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
} ::SetStretchBltMode(hDC, COLORONCOLOR);
bSuccess = ::StretchDIBits(hDC, DCRect.left, DCRect.top,
DCRect.Width(), DCRect.Height(),
DIBRect.left, DIBRect.top,
DIBRect.Width(), DIBRect.Height(),
lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); ::GlobalUnlock((HGLOBAL)hDIB);
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE);
}
return bSuccess;
}

解决方案 »

  1.   

    可以用StretchBlt啊,但Screen设置要>8bit color。
    可以把CreateDIBSection的返回值选进HDC
    StretchBlt硬件支持,比StretchDIBits要快。
    缩放的效果不太好,你可以用高通滤波。
    BOOL  FCDibEffect::Stretch (DWORD dwWidth, DWORD dwHeight, int iType)
    {
    FCDib Old ;
    Old = *this ;
    this->Unload () ;
    BITMAPV4HEADER Bmif ;
    Old.GetDibInfo (&Bmif) ; if (iType)
    if (dwWidth > dwHeight)
    dwWidth = Old.Width() * dwHeight / Old.Height() ;
    else
    dwHeight = Old.Height() * dwWidth / Old.Width() ; HDC hdcDesc = CreateCompatibleDC (NULL),
    hdcSrc  = CreateCompatibleDC (NULL) ;
    if ((!this->Create (dwWidth, dwHeight, Bmif.bV4BitCount, Bmif.bV4V4Compression, &Bmif.bV4RedMask)) || (hdcDesc == NULL) || (hdcSrc == NULL))
    return FALSE ; int iTe = ::SetStretchBltMode (hdcDesc, COLORONCOLOR) ;
    HBITMAP hTa = (HBITMAP)SelectObject (hdcDesc, this->GetHandle ()) ;
    HBITMAP hTb = (HBITMAP)SelectObject (hdcSrc, Old.GetHandle ()) ;
    BOOL res = ::StretchBlt (hdcDesc, 0, 0, dwWidth, dwHeight, 
     hdcSrc, 0, 0, Old.Width(), Old.Height(), SRCCOPY) ;
    SelectObject (hdcDesc, hTa) ;
    SelectObject (hdcSrc, hTb) ;
    ::SetStretchBltMode (hdcDesc, iTe) ;
    DeleteDC (hdcDesc) ;
    DeleteDC (hdcSrc) ;
    return res ;
    }滤波用的卷积函数.
    void  FCDibEffect::ConvoluteDIB_3x3 (CONVOLUTEKERNEL_3x3 kernel)
    {
    FCDib Old ;
    Old = *this ; this->Unload () ;
    if (!this->Create (Old.Width(), Old.Height(), 32))
    return ; RGBQUAD * pCurLineSrc, * pCurLineSrc_UP, * pCurLineSrc_DOWN, * pCurLineDest ;
    int iBlue, iGreen, iRed ;
    int iCou1, x, y, ixMax = (int)Old.Width() - 2 ; for (y = Old.Height() - 2 ; y >=1 ; y--) // 行
    {
    pCurLineDest  = (RGBQUAD *) this->GetBits (y) ;
    pCurLineSrc  = (RGBQUAD *) Old.GetBits (y) ;
    pCurLineSrc_UP  = (RGBQUAD *) Old.GetBits (y - 1) ;
    pCurLineSrc_DOWN = (RGBQUAD *) Old.GetBits (y + 1) ;
    for (x = 1 ; x < ixMax ; x++) // 列
    {
    iBlue = iRed = iGreen = 0 ;
    for (iCou1 = 0 ; iCou1 < 3 ; iCou1++)
    {
    iBlue += pCurLineSrc_UP[iCou1].rgbBlue * kernel.iElement[iCou1] + pCurLineSrc[iCou1].rgbBlue * kernel.iElement[iCou1 + 3] + pCurLineSrc_DOWN[iCou1].rgbBlue * kernel.iElement[iCou1 + 6] ;
    iGreen += pCurLineSrc_UP[iCou1].rgbGreen * kernel.iElement[iCou1] + pCurLineSrc[iCou1].rgbGreen * kernel.iElement[iCou1 + 3] + pCurLineSrc_DOWN[iCou1].rgbGreen * kernel.iElement[iCou1 + 6] ;
    iRed += pCurLineSrc_UP[iCou1].rgbRed * kernel.iElement[iCou1] + pCurLineSrc[iCou1].rgbRed * kernel.iElement[iCou1 + 3] + pCurLineSrc_DOWN[iCou1].rgbRed * kernel.iElement[iCou1 + 6] ;
    }
    pCurLineDest[x].rgbBlue = ::fooBound (iBlue / kernel.iDivisor, 0, 0xFF) ;
    pCurLineDest[x].rgbGreen = ::fooBound (iGreen / kernel.iDivisor, 0, 0xFF) ;
    pCurLineDest[x].rgbRed = ::fooBound (iRed / kernel.iDivisor, 0, 0xFF) ;
    pCurLineSrc_UP++ ; pCurLineSrc++ ; pCurLineSrc_DOWN++ ;
    }
    }
    return ;
    } case EFFECT_SMOOTH_1 :
    this->InitKernel (&kernel, 1, 1, 1  ,   1, 1, 1  ,   1, 1, 1 , 9 ) ;
    this->ConvoluteDIB_3x3 (kernel) ; break ;
      

  2.   

    楼上的“狂”,你程序速度将会太漫,我没有听说过在实际系统中做卷积居然还在时频域做的,小子,去看看书吧,时域卷积等于频域相乘,知道了吧,先用FFT,然后,自己去看书吧!冒皮皮