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

📄 gdiplus_image.cpp

📁 Windows Mobile平台上使用GDI+。GDI+功能很强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "stdafx.h"
#include "GdiplusShunt.h"


#ifdef _WIN32_WCE
//----------------------------------------------------------------------------
// Helper functions for Windows CE implementation
//----------------------------------------------------------------------------
HGLOBAL g_hBufferCE = NULL;

// Returns the number of storage bytes needed for each scanline in the bitmap
static
int BytesPerLine(int nWidth, int nBitsPerPixel)
{
    return ( (nWidth * nBitsPerPixel + 31) & (~31) ) / 8;
}

static inline
DWORD GetBmpCompression(int nBitsPixel)
{
#ifdef _WIN32_WCE
	if (nBitsPixel == 16 || nBitsPixel == 32)
		return BI_BITFIELDS;
	else
		return BI_RGB;
#else
	return BI_RGB;
#endif
}

static inline
int NumColorEntries(int nBitsPerPixel, int nCompression, DWORD biClrUsed /*= 0*/)
{
	int nColors = 0;

    switch (nBitsPerPixel) 
    {
	case 1:		{ nColors = 2; break; }
#ifdef _WIN32_WCE
	case 2:		{ nColors = 4; break; }
#endif
	case 4:		{ nColors = 16; break; }
	case 8:		{ nColors = 256; break; }
	case 24:	{ nColors = 0; break; }
	case 16:
	case 32:
#ifdef _WIN32_WCE
		nColors = 3;
#else
		nColors = (nCompression == BI_BITFIELDS) ? 3 : 0;
#endif
		break;
    }

    // If biClrUsed is provided, and it is a legal value, use it
    if (biClrUsed > 0 && biClrUsed <= (DWORD)nColors)
        return biClrUsed;

    return nColors;
}

struct DIBINFO : public BITMAPINFO 
{ 
	RGBQUAD arColors[255]; 
	// Color table info - adds an extra 255 entries to palette 
	operator LPBITMAPINFO() { return (LPBITMAPINFO) this; } 
	operator LPBITMAPINFOHEADER() { return &bmiHeader; } 
	RGBQUAD* ColorTable() { return bmiColors; } 
}; 

/***********************************************************************
UINT CEGetDIBColorTable( HDC, UINT, UINT, RGBQUAD * )

PARAMETERS:
HBITMAP - the Device Context in which the DIBSection is selected
UINT - the index of the first color table entry to retrieve
UINT - the number of color table entries to retrieve
RGBQUAD - a buffer large enough to hold the number of RGBQUAD
entries requested

RETURNS:
UINT - the number of colors placed in the buffer

**********************************************************************
*/ 
UINT CEGetDIBColorTable(
						HDC hdc,
						UINT uStartIndex,
						UINT cEntries,
						RGBQUAD *pColors
						)
{
	HBITMAP         hDIBSection;
	DIBSECTION      ds;
	DWORD           dwSize;
	UINT            iColor, cColors, TestPixelY;
	BYTE            OldPalIndex;
	LPBYTE          pBits;
	WORD            wIndexMask;

	if (pColors == NULL)
		return 0;                       // No place to put them, fail

	// Get a description of the DIB Section
	hDIBSection = (HBITMAP)GetCurrentObject( hdc, OBJ_BITMAP );
	dwSize = GetObject( hDIBSection, sizeof(DIBSECTION), &ds );

	if (dwSize != sizeof(DIBSECTION))
		return 0;                      // Must not be a DIBSection, fail

	if (ds.dsBmih.biBitCount > 8)
		return 0;                      // Not Palettized, fail

	// get the number of colors to return per BITMAPINFOHEADER docs
	if (ds.dsBmih.biClrUsed)
		cColors = ds.dsBmih.biClrUsed;
	else
		cColors = 1 << (ds.dsBmih.biBitCount*ds.dsBmih.biPlanes);

	// Create a mask for the palette index bits for 1, 2, 4, and 8 bpp
	wIndexMask = (0xFF << (8 - ds.dsBmih.biBitCount)) & 0x00FF;

	// Get the pointer to the image bits
	pBits = (LPBYTE) ds.dsBm.bmBits;

	// Initialize the loop variables
	cColors = min( cColors, cEntries );
	OldPalIndex = *pBits;
	if (ds.dsBmih.biHeight > 0 )
		// If button up DIB, pBits points to last row
		TestPixelY = ds.dsBm.bmHeight-1;
	else
		// If top down DIB, pBits points to first row
		TestPixelY = 0;

	for (iColor = uStartIndex; iColor < cColors; iColor++)
	{
		COLORREF    rgbColor;

		// Set the palette index for the test pixel,
		// modifying only the bits for one pixel
		*pBits = (iColor << (8 - ds.dsBmih.biBitCount)) |
			(*pBits & ~wIndexMask);

		// now get the resulting color
		rgbColor = GetPixel( hdc, 0, TestPixelY );

		pColors[iColor - uStartIndex].rgbReserved = 0;
		pColors[iColor - uStartIndex].rgbBlue = GetBValue(rgbColor);
		pColors[iColor - uStartIndex].rgbRed = GetRValue(rgbColor);
		pColors[iColor - uStartIndex].rgbGreen = GetGValue(rgbColor);
	}

	// Restore the test pixel
	*pBits = OldPalIndex;

	return cColors;
}



#endif

//----------------------------------------------------------------------------
// Image APIs
//----------------------------------------------------------------------------


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipLoadImageFromStreamPtr)(IStream* stream, GpImage **image));
DEFINE_MEMBER(GdipLoadImageFromStream);

GpStatus WINGDIPAPI
GdipLoadImageFromStream(IStream* stream, GpImage **image)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipLoadImageFromStream == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipLoadImageFromStream);
        }
        if ( g_GdipLoadImageFromStream != NULL )
        {
            status = (*g_GdipLoadImageFromStream)(stream, image);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipLoadImageFromFilePtr)(GDIPCONST WCHAR* filename, GpImage **image));
DEFINE_MEMBER(GdipLoadImageFromFile);

GpStatus WINGDIPAPI
GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipLoadImageFromFile == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipLoadImageFromFile);
        }
        if ( g_GdipLoadImageFromFile != NULL )
        {
            status = (*g_GdipLoadImageFromFile)(filename, image);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipLoadImageFromStreamICMPtr)(IStream* stream, GpImage **image));
DEFINE_MEMBER(GdipLoadImageFromStreamICM);

GpStatus WINGDIPAPI
GdipLoadImageFromStreamICM(IStream* stream, GpImage **image)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipLoadImageFromStreamICM == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipLoadImageFromStreamICM);
        }
        if ( g_GdipLoadImageFromStreamICM != NULL )
        {
            status = (*g_GdipLoadImageFromStreamICM)(stream, image);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipLoadImageFromFileICMPtr)(GDIPCONST WCHAR* filename, GpImage **image));
DEFINE_MEMBER(GdipLoadImageFromFileICM);

GpStatus WINGDIPAPI
GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename, GpImage **image)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipLoadImageFromFileICM == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipLoadImageFromFileICM);
        }
        if ( g_GdipLoadImageFromFileICM != NULL )
        {
            status = (*g_GdipLoadImageFromFileICM)(filename, image);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipCloneImagePtr)(GpImage *image, GpImage **cloneImage));
DEFINE_MEMBER(GdipCloneImage);

GpStatus WINGDIPAPI
GdipCloneImage(GpImage *image, GpImage **cloneImage)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipCloneImage == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipCloneImage);
        }
        if ( g_GdipCloneImage != NULL )
        {
            status = (*g_GdipCloneImage)(image, cloneImage);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipDisposeImagePtr)(GpImage *image));
DEFINE_MEMBER(GdipDisposeImage);

GpStatus WINGDIPAPI
GdipDisposeImage(GpImage *image)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipDisposeImage == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipDisposeImage);
        }
        if ( g_GdipDisposeImage != NULL )
        {
            status = (*g_GdipDisposeImage)(image);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipSaveImageToFilePtr)(GpImage *image, GDIPCONST WCHAR* filename,
                                   GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams));
DEFINE_MEMBER(GdipSaveImageToFile);

#if 0
GpStatus WINGDIPAPI
GdipSaveImageToFileCE(GpImage *image, GDIPCONST WCHAR* filename,
                    GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams)
{
	GpStatus status;
	HRESULT hr;

	if (!image || !filename || !clsidEncoder)
		return InvalidParameter;

	// We fill ImageInfo for BeginSink
	REAL Xdpi;
	REAL Ydpi;
	ImageInfo imginfo = {0};
	GdipGetImagePixelFormat(image, &imginfo.PixelFormat);
	GdipGetImageWidth(image, &imginfo.Width);
	GdipGetImageHeight(image, &imginfo.Height);
	GdipGetImageHorizontalResolution(image, &Xdpi);
	imginfo.Xdpi = Xdpi;
	GdipGetImageVerticalResolution(image, &Ydpi);
	imginfo.Ydpi = Ydpi;
	imginfo.RawDataFormat = ImageFormatMemoryBMP;
	imginfo.Flags		|= SinkFlagsTopDown | SinkFlagsFullWidth;
	if (IsAlphaPixelFormat(imginfo.PixelFormat))
		imginfo.Flags	|= SinkFlagsHasAlpha;
	
	//WORD bmBitsPixel	= GetPixelFormatSize( bitmap.GetPixelFormat() );
	// Needs to play between GDI Rect and Gdiplus::Rect
	RECT rect;
	Rect gdiprect;
	rect.top	= gdiprect.Y		= 0;
	rect.bottom =  gdiprect.Height	= imginfo.Height;
	rect.left	= gdiprect.X		= 0;
	rect.right	= gdiprect.Width	= imginfo.Width;


	BitmapData bmpdata;

	IImageEncoder* imageEncoder=NULL;
	hr = g_pImgFactory->CreateImageEncoderToFile(clsidEncoder, filename, &imageEncoder); 
	if ( hr == S_OK) {

		IImageSink* imageSink = NULL;
		hr = imageEncoder->GetEncodeSink(&imageSink);
		if (hr == S_OK) {


			if (imageSink->BeginSink(&imginfo, NULL) == S_OK) {

				ColorPalette* palette = NULL;
				if( IsIndexedPixelFormat( imginfo.PixelFormat ) )
				{
					INT nPaletteSize;
					GdipGetImagePaletteSize(image, &nPaletteSize);

					palette = static_cast< ColorPalette* >( malloc( nPaletteSize ) );
					status = GdipGetImagePalette(image, palette, nPaletteSize);
					if (status == Ok)
					{
						for( UINT iColor = 0; iColor < palette->Count; iColor++ )
						{
							palette->Entries[iColor]= Color::MakeARGB(255,iColor ,iColor ,iColor );
						}
					}
				} 

				if (palette != NULL)
				{
					if (imginfo.PixelFormat == PixelFormat32bppARGB) 
						palette->Flags = PALFLAG_HASALPHA;

					hr = imageSink->SetPalette(palette);
				}

				status = GdipBitmapLockBits(static_cast<GpBitmap*>(image), &gdiprect, ImageLockModeRead,imginfo.PixelFormat, &bmpdata);
				if (status == Ok)
				{
					if (bmpdata.Stride < 0)
					{
						bmpdata.Stride  = bmpdata.Stride * -1;
						int biBitCount	= GetPixelFormatSize(bmpdata.PixelFormat);
						DWORD biSizeImage	= BytesPerLine(bmpdata.Width, biBitCount) * bmpdata.Height;

						bmpdata.Scan0 = (void*) ( ((DWORD)bmpdata.Scan0 + bmpdata.Stride) - biSizeImage);
					}

					hr = imageSink->PushPixelData(&rect, &bmpdata, TRUE);
					status = GdipBitmapUnlockBits(static_cast<GpBitmap*>(image), &bmpdata);
					hr = imageSink->EndSink(S_OK);
				}
				if (palette)
					free(palette);

				imageEncoder->TerminateEncoder();
				imageEncoder->Release();
				imageSink->Release();
			}

		}
	}
	return (hr == S_OK) ? Ok : GenericError;
}
#endif

GpStatus WINGDIPAPI
GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filename,
                    GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )
    {
        if ( g_GdipSaveImageToFile == NULL )
        {
            INITIALIZE_MEMBER(g_hGdiplusModule, GdipSaveImageToFile);
        }
        if ( g_GdipSaveImageToFile != NULL )
        {
            status = (*g_GdipSaveImageToFile)(image, filename, clsidEncoder, encoderParams);
        }
    }
    return status;
}


DEFINE_POINTER(GpStatus (WINGDIPAPI *GdipSaveImageToStreamPtr)(GpImage *image, IStream* stream,
                         GDIPCONST CLSID* clsidEncoder, 
                         GDIPCONST EncoderParameters* encoderParams));
DEFINE_MEMBER(GdipSaveImageToStream);

GpStatus WINGDIPAPI
GdipSaveImageToStream(GpImage *image, IStream* stream,
                      GDIPCONST CLSID* clsidEncoder, 
                      GDIPCONST EncoderParameters* encoderParams)
{
    GpStatus status = GdiplusNotInitialized;
    if ( g_hGdiplusModule != 0 )

⌨️ 快捷键说明

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