📄 gdiplus_image.cpp
字号:
#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 + -