⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ximawnd.cpp

📁 用Cximage 库显示各种格式图片小程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
											scanline   += delta_y;
											break;
										}
									default :
										second_byte = *(lpDIBBits++);
										BYTE* sline = iter.GetRow(scanline);
										for (int i = 0; i < status_byte; i++) {
											if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
												if (low_nibble) {
													if (i&1)
														*(sline + bits) |= (second_byte & 0x0f);
													else
														*(sline + bits) |= (second_byte & 0xf0)>>4;
													bits++;
												} else {
													if (i&1)
														*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
													else
														*(sline + bits) = (BYTE)(second_byte & 0xf0);
												}
											}

											if ((i & 1) && (i != (status_byte - 1)))
												second_byte = *(lpDIBBits++);

											low_nibble = !low_nibble;
										}
										if ((((status_byte+1) >> 1) & 1 ) == 1)
											second_byte = *(lpDIBBits++);												
										break;
									};
									break;
									default :
									{
										BYTE* sline = iter.GetRow(scanline);
										second_byte = *(lpDIBBits++);
										for (unsigned i = 0; i < status_byte; i++) {
											if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
												if (low_nibble) {
													if (i&1)
														*(sline + bits) |= (second_byte & 0x0f);
													else
														*(sline + bits) |= (second_byte & 0xf0)>>4;
													bits++;
												} else {
													if (i&1)
														*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
													else
														*(sline + bits) = (BYTE)(second_byte & 0xf0);
												}
											}
											low_nibble = !low_nibble;
										}
									}
									break;
								};
							}
						}
						break;
					case BI_RLE8 :
						{
							BYTE status_byte = 0;
							BYTE second_byte = 0;
							int scanline = 0;
							int bits = 0;
							CImageIterator iter(this);

							for (BOOL bContinue = TRUE; bContinue; ) {
								status_byte = *(lpDIBBits++);
								if (status_byte==RLE_COMMAND) {
									status_byte = *(lpDIBBits++);
									switch (status_byte) {
									case RLE_ENDOFLINE :
										bits = 0;
										scanline++;
										break;
									case RLE_ENDOFBITMAP :
										bContinue = FALSE;
										break;
									case RLE_DELTA :
										{
											// read the delta values
											BYTE delta_x;
											BYTE delta_y;
											delta_x = *(lpDIBBits++);
											delta_y = *(lpDIBBits++);
											// apply them
											bits     += delta_x;
											scanline += delta_y;
										}
										break;
									default :
										int nNumBytes = sizeof(BYTE) * status_byte;
										memcpy((void *)(iter.GetRow(scanline) + bits), lpDIBBits, nNumBytes);
										lpDIBBits += nNumBytes;
										// align run length to even number of bytes 
										if ((status_byte & 1) == 1)
											second_byte = *(lpDIBBits++);
										bits += status_byte;
										break;
									};
								} else {
									BYTE *sline = iter.GetRow(scanline);
									second_byte = *(lpDIBBits++);
									for (unsigned i = 0; i < status_byte; i++) {
										if ((DWORD)bits<info.dwEffWidth){
											*(sline + bits) = second_byte;
											bits++;
										} else {
											bContinue = FALSE; //don't delete: we are in memory, it is not as with files
											break;
										}
									}
								}
							}
						}
						break;
					default :
						{
							// "compression type not supported";
							GlobalUnlock(lpVoid);
							return false;
						}
					}
				}
			}
		} else {
			//normal bitmap (not compressed)
			memcpy(pDib,lpVoid,GetSize());
		}

		GlobalUnlock(lpVoid);

		if (bTopDownDib) Flip();

		return true;
	}
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Transfer the image in a  bitmap handle
 * \param hdc: target device context (the screen, usually)
 * \return bitmap handle, or NULL if an error occurs.
 */
HBITMAP CxImage::MakeBitmap(HDC hdc)
{
	if (!pDib)
		return NULL;

	if (!hdc){
		// this call to CreateBitmap doesn't create a DIB <jaslet>
		// // Create a device-independent bitmap <CSC>
		//  return CreateBitmap(head.biWidth,head.biHeight,	1, head.biBitCount, GetBits());
		// use instead this code
		HDC hMemDC = CreateCompatibleDC(NULL);
		LPVOID pBit32;
		HBITMAP bmp = CreateDIBSection(hMemDC,(LPBITMAPINFO)pDib,DIB_RGB_COLORS, &pBit32, NULL, 0);
		if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
		DeleteDC(hMemDC);
		return bmp;
	}

	// this single line seems to work very well
	//HBITMAP bmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)pDib, CBM_INIT,
	//	GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
	// this alternative works also with _WIN32_WCE
	LPVOID pBit32;
	HBITMAP bmp = CreateDIBSection(hdc, (LPBITMAPINFO)pDib, DIB_RGB_COLORS, &pBit32, NULL, 0);
	if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);

	return bmp;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Bitmap resource constructor
 * \param hbmp : bitmap resource handle
 * \param hpal : (optional) palette, useful for 8bpp DC 
 * \return true if everything is ok
 */
bool CxImage::CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal)
{
	if (!Destroy())
		return false;

	if (hbmp) { 
        BITMAP bm;
		// get informations about the bitmap
        GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
		// create the image
        if (!Create(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, 0))
			return false;
		// create a device context for the bitmap
        HDC dc = ::GetDC(NULL);
		if (!dc)
			return false;

		if (hpal){
			SelectObject(dc,hpal); //the palette you should get from the user or have a stock one
			RealizePalette(dc);
		}

		// copy the pixels
        if (GetDIBits(dc, hbmp, 0, head.biHeight, info.pImage,
			(LPBITMAPINFO)pDib, DIB_RGB_COLORS) == 0){ //replace &head with pDib <Wil Stark>
            strcpy(info.szLastError,"GetDIBits failed");
			::ReleaseDC(NULL, dc);
			return false;
        }
        ::ReleaseDC(NULL, dc);
		return true;
    }
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * icon resource constructor
 * \param hico : icon resource handle
 * \return true if everything is ok
 * \author []; changes [Arlen Albert Keshabian]
 */
#if !defined (_WIN32_WCE)
bool CxImage::CreateFromHICON(HICON hico)
{
	if (!Destroy() || !hico)
		return false;

	bool l_bResult = true;

	ICONINFO iinfo;
	GetIconInfo(hico,&iinfo);

	BITMAP l_Bitmap;
	GetObject(iinfo.hbmColor, sizeof(BITMAP), &l_Bitmap);

	if(l_Bitmap.bmBitsPixel == 32)
	{
		BITMAPINFO l_BitmapInfo;
		l_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		l_BitmapInfo.bmiHeader.biWidth = l_Bitmap.bmWidth;
		l_BitmapInfo.bmiHeader.biHeight = l_Bitmap.bmHeight;
		l_BitmapInfo.bmiHeader.biPlanes = l_Bitmap.bmPlanes;
		l_BitmapInfo.bmiHeader.biBitCount = l_Bitmap.bmBitsPixel;
		l_BitmapInfo.bmiHeader.biCompression = BI_RGB;

		RGBQUAD *l_pRawBytes = new RGBQUAD[l_Bitmap.bmWidth * l_Bitmap.bmHeight];

		HDC dc = ::GetDC(NULL);

		if(dc)
		{
			if(GetDIBits(dc, iinfo.hbmColor, 0, l_Bitmap.bmHeight, l_pRawBytes, &l_BitmapInfo, DIB_RGB_COLORS))
				l_bResult = CreateFromArray((BYTE*)l_pRawBytes, l_Bitmap.bmWidth, l_Bitmap.bmHeight, l_Bitmap.bmBitsPixel, l_Bitmap.bmWidthBytes, false);
			else
				l_bResult = false;

			::ReleaseDC(NULL, dc);
		}
		else
			l_bResult = false;

		delete [] l_pRawBytes;
	}
	else
	{
		l_bResult = CreateFromHBITMAP(iinfo.hbmColor);
#if CXIMAGE_SUPPORT_ALPHA
		if(l_bResult)
		{
			CxImage mask;
			mask.CreateFromHBITMAP(iinfo.hbmMask);
			mask.GrayScale();
			mask.Negative();
			AlphaSet(mask);
		}
#endif
	}

	DeleteObject(iinfo.hbmColor); //<Sims>
	DeleteObject(iinfo.hbmMask);  //<Sims>
	
	return l_bResult;
}
#endif //_WIN32_WCE
////////////////////////////////////////////////////////////////////////////////
long CxImage::Draw(HDC hdc, const RECT& rect, RECT* pClipRect, bool bSmooth)
{
	return Draw(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pClipRect,bSmooth);
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Draws the image in the specified device context, with support for alpha channel, alpha palette, transparency, opacity.
 * \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
 *
 * \param pClipRect : limit the drawing operations inside a given rectangle in the output device context.
 * \param bSmooth : activates a bilinear filter that will enhance the appearence for zommed pictures.
 *                   Quite slow. Needs CXIMAGE_SUPPORT_INTERPOLATION.
 * \return true if everything is ok
 */
long CxImage::Draw(HDC hdc, long x, long y, long cx, long cy, RECT* pClipRect, bool bSmooth)
{
	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;
	bool bAlpha = pAlpha != 0;

	//required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
	int hdc_Restore = ::SaveDC(hdc);
	if (!hdc_Restore) 
		return 0;

#if !defined (_WIN32_WCE)
	RECT mainbox; // (experimental) 
	if (pClipRect){
		GetClipBox(hdc,&mainbox);
		HRGN rgn = CreateRectRgnIndirect(pClipRect);
		ExtSelectClipRgn(hdc,rgn,RGN_AND);
		DeleteObject(rgn);
	}
#endif

	//find the smallest area to paint
	RECT clipbox,paintbox;
	GetClipBox(hdc,&clipbox);

	paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
	paintbox.left = min(clipbox.right,max(clipbox.left,x));
	paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
	paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));

	long destw = paintbox.right - paintbox.left;
	long desth = paintbox.bottom - paintbox.top;

	if (!(bTransparent || bAlpha || info.bAlphaPaletteEnabled)){
		if (cx==head.biWidth && cy==head.biHeight){ //NORMAL
#if !defined (_WIN32_WCE)
			SetStretchBltMode(hdc,COLORONCOLOR);
#endif
			SetDIBitsToDevice(hdc, x, y, cx, cy, 0, 0, 0, cy,
						info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS);
		} else { //STRETCH
			//pixel informations
			RGBQUAD c={0,0,0,0};
			//Preparing Bitmap Info
			BITMAPINFO bmInfo;
			memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
			bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -