📄 ximawnd.cpp
字号:
bmInfo.bmiHeader.biWidth=destw;
bmInfo.bmiHeader.biHeight=desth;
bmInfo.bmiHeader.biPlanes=1;
bmInfo.bmiHeader.biBitCount=24;
BYTE *pbase; //points to the final dib
BYTE *pdst; //current pixel from pbase
BYTE *ppix; //current pixel from image
//get the background
HDC TmpDC=CreateCompatibleDC(hdc);
HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
if (pbase){
long xx,yy;
long sx,sy;
float dx,dy;
BYTE *psrc;
long ew = ((((24 * destw) + 31) / 32) * 4);
long ymax = paintbox.bottom;
long xmin = paintbox.left;
float fx=(float)head.biWidth/(float)cx;
float fy=(float)head.biHeight/(float)cy;
for(yy=0;yy<desth;yy++){
dy = head.biHeight-(ymax-yy-y)*fy;
sy = max(0L,(long)floor(dy));
psrc = info.pImage+sy*info.dwEffWidth;
pdst = pbase+yy*ew;
for(xx=0;xx<destw;xx++){
dx = (xx+xmin-x)*fx;
sx = max(0L,(long)floor(dx));
#if CXIMAGE_SUPPORT_INTERPOLATION
if (bSmooth){
if (fx > 1 && fy > 1) {
c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
} else {
c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
}
} else
#endif //CXIMAGE_SUPPORT_INTERPOLATION
{
if (head.biClrUsed){
c=GetPaletteColor(GetPixelIndex(sx,sy));
} else {
ppix = psrc + sx*3;
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix;
}
}
*pdst++=c.rgbBlue;
*pdst++=c.rgbGreen;
*pdst++=c.rgbRed;
}
}
}
//paint the image & cleanup
SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
DeleteObject(SelectObject(TmpDC,TmpObj));
DeleteDC(TmpDC);
}
} else { // draw image with transparent/alpha blending
//////////////////////////////////////////////////////////////////
//Alpha blend - Thanks to Florian Egel
//pixel informations
RGBQUAD c={0,0,0,0};
RGBQUAD ct = GetTransColor();
long* pc = (long*)&c;
long* pct= (long*)&ct;
long cit = GetTransIndex();
long ci = 0;
//Preparing Bitmap Info
BITMAPINFO bmInfo;
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth=destw;
bmInfo.bmiHeader.biHeight=desth;
bmInfo.bmiHeader.biPlanes=1;
bmInfo.bmiHeader.biBitCount=24;
BYTE *pbase; //points to the final dib
BYTE *pdst; //current pixel from pbase
BYTE *ppix; //current pixel from image
//get the background
HDC TmpDC=CreateCompatibleDC(hdc);
HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
BitBlt(TmpDC,0,0,destw,desth,hdc,paintbox.left,paintbox.top,SRCCOPY);
if (pbase){
long xx,yy,alphaoffset,ix,iy;
BYTE a,a1,*psrc;
long ew = ((((24 * destw) + 31) / 32) * 4);
long ymax = paintbox.bottom;
long xmin = paintbox.left;
if (cx!=head.biWidth || cy!=head.biHeight){
//STRETCH
float fx=(float)head.biWidth/(float)cx;
float fy=(float)head.biHeight/(float)cy;
float dx,dy;
long sx,sy;
for(yy=0;yy<desth;yy++){
dy = head.biHeight-(ymax-yy-y)*fy;
sy = max(0L,(long)floor(dy));
alphaoffset = sy*head.biWidth;
pdst = pbase + yy*ew;
psrc = info.pImage + sy*info.dwEffWidth;
for(xx=0;xx<destw;xx++){
dx = (xx+xmin-x)*fx;
sx = max(0L,(long)floor(dx));
if (bAlpha) a=pAlpha[alphaoffset+sx]; else a=255;
a =(BYTE)((a*(1+info.nAlphaMax))>>8);
if (head.biClrUsed){
ci = GetPixelIndex(sx,sy);
#if CXIMAGE_SUPPORT_INTERPOLATION
if (bSmooth){
if (fx > 1 && fy > 1) {
c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
} else {
c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
}
} else
#endif //CXIMAGE_SUPPORT_INTERPOLATION
{
c = GetPaletteColor(GetPixelIndex(sx,sy));
}
if (info.bAlphaPaletteEnabled){
a = (BYTE)((a*(1+c.rgbReserved))>>8);
}
} else {
#if CXIMAGE_SUPPORT_INTERPOLATION
if (bSmooth){
if (fx > 1 && fy > 1) {
c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
} else {
c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
}
} else
#endif //CXIMAGE_SUPPORT_INTERPOLATION
{
ppix = psrc + sx*3;
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix;
}
}
//if (*pc!=*pct || !bTransparent){
//if ((head.biClrUsed && ci!=cit) || ((!head.biClrUsed||bSmooth) && *pc!=*pct) || !bTransparent){
if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
// DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
if (a == 0) { // Transparent, retain dest
pdst+=3;
} else if (a == 255) { // opaque, ignore dest
*pdst++= c.rgbBlue;
*pdst++= c.rgbGreen;
*pdst++= c.rgbRed;
} else { // semi transparent
a1=(BYTE)~a;
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbBlue)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbGreen)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbRed)>>8);
}
} else {
pdst+=3;
}
}
}
} else {
//NORMAL
iy=head.biHeight-ymax+y;
for(yy=0;yy<desth;yy++,iy++){
alphaoffset=iy*head.biWidth;
ix=xmin-x;
pdst=pbase+yy*ew;
ppix=info.pImage+iy*info.dwEffWidth+ix*3;
for(xx=0;xx<destw;xx++,ix++){
if (bAlpha) a=pAlpha[alphaoffset+ix]; else a=255;
a = (BYTE)((a*(1+info.nAlphaMax))>>8);
if (head.biClrUsed){
ci = GetPixelIndex(ix,iy);
c = GetPaletteColor((BYTE)ci);
if (info.bAlphaPaletteEnabled){
a = (BYTE)((a*(1+c.rgbReserved))>>8);
}
} else {
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix++;
}
//if (*pc!=*pct || !bTransparent){
if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
// DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
if (a == 0) { // Transparent, retain dest
pdst+=3;
} else if (a == 255) { // opaque, ignore dest
*pdst++= c.rgbBlue;
*pdst++= c.rgbGreen;
*pdst++= c.rgbRed;
} else { // semi transparent
a1=(BYTE)~a;
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbBlue)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbGreen)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbRed)>>8);
}
} else {
pdst+=3;
}
}
}
}
}
//paint the image & cleanup
SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
DeleteObject(SelectObject(TmpDC,TmpObj));
DeleteDC(TmpDC);
}
#if !defined (_WIN32_WCE)
if (pClipRect){ // (experimental)
HRGN rgn = CreateRectRgnIndirect(&mainbox);
ExtSelectClipRgn(hdc,rgn,RGN_OR);
DeleteObject(rgn);
}
#endif
::RestoreDC(hdc,hdc_Restore);
return 1;
}
////////////////////////////////////////////////////////////////////////////////
long CxImage::Draw2(HDC hdc, const RECT& rect)
{
return Draw2(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Draws (stretch) the image with single transparency support
* \param hdc : destination device context
* \param x,y : (optional) offset
* \param cx,cy : (optional) size.
* - If cx or cy are not specified (or less than 0), the normal width or height will be used
* - If cx or cy are different than width or height, the image will be stretched
*
* \return true if everything is ok
*/
long CxImage::Draw2(HDC hdc, long x, long y, long cx, long cy)
{
if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
if (cx < 0) cx = head.biWidth;
if (cy < 0) cy = head.biHeight;
bool bTransparent = (info.nBkgndIndex >= 0);
//required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
int hdc_Restore = ::SaveDC(hdc);
if (!hdc_Restore)
return 0;
if (!bTransparent){
#if !defined (_WIN32_WCE)
SetStretchBltMode(hdc,COLORONCOLOR);
#endif
StretchDIBits(hdc, x, y, cx, cy, 0, 0, head.biWidth, head.biHeight,
info.pImage,(BITMAPINFO*)pDib, DIB_RGB_COLORS,SRCCOPY);
} else {
// draw image with transparent background
const int safe = 0; // or else GDI fails in the following - sometimes
RECT rcDst = {x+safe, y+safe, x+cx, y+cy};
if (RectVisible(hdc, &rcDst)){
/////////////////////////////////////////////////////////////////
// True Mask Method - Thanks to Paul Reynolds and Ron Gery
int nWidth = head.biWidth;
int nHeight = head.biHeight;
// Create two memory dcs for the image and the mask
HDC dcImage=CreateCompatibleDC(hdc);
HDC dcTrans=CreateCompatibleDC(hdc);
// Select the image into the appropriate dc
HBITMAP bm = CreateCompatibleBitmap(hdc, nWidth, nHeight);
HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(dcImage,bm);
#if !defined (_WIN32_WCE)
SetStretchBltMode(dcImage,COLORONCOLOR);
#endif
StretchDIBits(dcImage, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS,SRCCOPY);
// Create the mask bitmap
HBITMAP bitmapTrans = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
// Select the mask bitmap into the appropriate dc
HBITMAP pOldBitmapTrans = (HBITMAP)SelectObject(dcTrans, bitmapTrans);
// Build mask based on transparent colour
RGBQUAD rgbBG;
if (head.biBitCount<24) rgbBG = GetPaletteColor((BYTE)info.nBkgndIndex);
else rgbBG = info.nBkgndColor;
COLORREF crColour = RGB(rgbBG.rgbRed, rgbBG.rgbGreen, rgbBG.rgbBlue);
COLORREF crOldBack = SetBkColor(dcImage,crColour);
BitBlt(dcTrans,0, 0, nWidth, nHeight, dcImage, 0, 0, SRCCOPY);
// Do the work - True Mask method - cool if not actual display
StretchBlt(hdc,x, y,cx,cy, dcImage, 0, 0, nWidth, nHeight, SRCINVERT);
StretchBlt(hdc,x, y,cx,cy, dcTrans, 0, 0, nWidth, nHeight, SRCAND);
StretchBlt(hdc,x, y,cx,cy, dcImage, 0, 0, nWidth, nHeight, SRCINVERT);
// Restore settings
SelectObject(dcImage,pOldBitmapImage);
SelectObject(dcTrans,pOldBitmapTrans);
SetBkColor(hdc,crOldBack);
DeleteObject( bitmapTrans ); // RG 29/01/2002
DeleteDC(dcImage);
DeleteDC(dcTrans);
DeleteObject(bm);
}
}
::RestoreDC(hdc,hdc_Restore);
return 1;
}
////////////////////////////////////////////////////////////////////////////////
long CxImage::Stretch(HDC hdc, const RECT& rect, DWORD dwRop)
{
return Stretch(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, dwRop);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Stretch the image. Obsolete: use Draw() or Draw2()
* \param hdc : destination device context
* \param xoffset,yoffset : (optional) offset
* \param xsize,ysize : size.
* \param dwRop : raster operation code (see BitBlt documentation)
* \return true if everything is ok
*/
long CxImage::Stretch(HDC hdc, long xoffset, long yoffset, long xsize, long ysize, DWORD dwRop)
{
if((pDib)&&(hdc)) {
//palette must be correctly filled
#if !defined (_WIN32_WCE)
SetStretchBltMode(hdc,COLORONCOLOR);
#endif
StretchDIBits(hdc, xoffset, yoffset,
xsize, ysize, 0, 0, head.biWidth, head.biHeight,
info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS,dwRop);
return 1;
}
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -