CImageMaster的代码如下:
/ /
// ImageMaster.h: interface for the CImageMaster class.
//
// Version:
// 1.1.1
//
// Date:
// 2007.08.13
/ /
#ifndef IMAGEMASTER_H
#define IMAGEMASTER_H
#include " imaging.h "
// --------------------------------------------------------------------
// Enum value
enum ImageDrawMode
{
// Fit to the play window size. How wide (height) the window is, how
// is the move. Keep aspect ratio.
IMG_FIT,
// Not support.Stretch to the play window size. Don't keep the aspect ratio.
IMG_STRETCH,
// When the size of video is smaller than the play window, it displayes
// as the video size. If it's bigger , it just like the DISP_FIT mode.
IMG_NATIVE
};
class CImageMaster
{
public :
BOOL DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw);
BOOL DrawIntegrity(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect,BOOL bDraw);
BOOL IsOK();
void Close();
UINT GetHeight();
UINT GetWidth();
BOOL Open( const TCHAR * pcszFile);
CImageMaster();
virtual ~ CImageMaster();
protected :
void CalculateDrawArea(ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect,RECT * pDrawRect);
BOOL IsOKImagingInterfaces();
void ReleaseImagingInterfaces();
IImage * m_pImage;
IImagingFactory * m_pImagingFactory;
TCHAR m_szFileName[MAX_PATH];
ImageInfo m_ImageInfo;
RECT m_rcLastThumbnail; // The last drawed area for the DrawThumbnail() function.
// It's for the memory DC information
typedef struct MemoryDCInfo
{
HBITMAP hBitmap;
HDC hdc;
HGDIOBJ hOldSel;
UINT uiWidth;
UINT uiHeight;
}MEMORYDCINFO, * PMEMORYDCINFO;
MEMORYDCINFO m_IntegrityMemDCInfo;
MEMORYDCINFO m_ThumbnailMemDCInfo;
void DeleteMemoryDC(MEMORYDCINFO * pDCInfo);
BOOL CreateMemoryDC(HDC hdc,MEMORYDCINFO * pDCInfo,UINT uiWidth,UINT uiHeight);
BOOL IsOKMemoryDC( const MEMORYDCINFO * pMemDC);
BOOL Draw(HDC hdcDest, const RECT * pDstRect, const MEMORYDCINFO * pSrcDCInfo, const RECT * pSrcRect);
};
#endif // #ifndef IMAGE_H
/ /
// Image.cpp: implementation of the CImageMaster class.
//
/ /
#include " stdafx.h "
#include " initguid.h "
#include " ImageMaster.h "
// ======================================================================
// Link the .lib
#pragma comment (lib,"Ole32.lib")
// =======================================================================
/ /
// Construction/Destruction
/ /
CImageMaster::CImageMaster():
m_pImage(NULL),
m_pImagingFactory(NULL)
{
memset(m_szFileName, 0 , sizeof (m_szFileName));
memset( & m_ImageInfo, 0 , sizeof (m_ImageInfo));
memset( & m_IntegrityMemDCInfo, 0 , sizeof (m_IntegrityMemDCInfo));
memset( & m_ThumbnailMemDCInfo, 0 , sizeof (m_ThumbnailMemDCInfo));
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
}
CImageMaster:: ~ CImageMaster()
{
Close();
}
// ----------------------------------------------------------------------
// Description:
// Open the image file
//
// Parameters:
// pcszFile : [in] The image file to open
//
// Return Value:
// TRUE -- Succeed in opening the file
// FALSE -- Failed in opening the file
// ----------------------------------------------------------------------
BOOL CImageMaster::Open( const TCHAR * pcszFile)
{
BOOL bResult = FALSE;
HRESULT hr;
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
goto END;
}
if (FAILED(hr = CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,( void ** ) & m_pImagingFactory)))
{
goto END;
}
if (FAILED(hr = m_pImagingFactory -> CreateImageFromFile(pcszFile, & m_pImage)))
{
goto END;
}
m_pImage -> GetImageInfo( & m_ImageInfo);
_tcscpy(m_szFileName,pcszFile);
bResult = TRUE;
END:
if (bResult == FALSE)
{
Close();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// Get the width of the image
//
// Parameters:
// NULL
//
// Return Value:
// 0 -- May be failure.
// others -- succeed
// ----------------------------------------------------------------------
UINT CImageMaster::GetWidth()
{
return m_ImageInfo.Width;
}
// ----------------------------------------------------------------------
// Description:
// Get the height of the image
//
// Parameters:
// NULL
//
// Return Value:
// 0 -- May be failure.
// others -- succeed
// ----------------------------------------------------------------------
UINT CImageMaster::GetHeight()
{
return m_ImageInfo.Height;
}
// ----------------------------------------------------------------------
// Description:
// Close the opened image to release the resource
//
// Parameters:
// NULL
//
// Return Value:
// NULL
// ----------------------------------------------------------------------
void CImageMaster::Close()
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_IntegrityMemDCInfo);
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
memset(m_szFileName, 0 , sizeof (m_szFileName));
memset( & m_ImageInfo, 0 , sizeof (m_ImageInfo));
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the object is read for operating. If failed in calling the Open() or never call before,
// it will return FALSE.
//
// Parameters:
// NULL
//
// Return Values:
// TRUE - It's all ready for other operating.
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOK()
{
if (IsOKMemoryDC( & m_IntegrityMemDCInfo) == FALSE &&
IsOKMemoryDC( & m_ThumbnailMemDCInfo) == FALSE &&
IsOKImagingInterfaces() == FALSE)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Release the imaging interfaces resource.
//
// ----------------------------------------------------------------------------------------------
void CImageMaster::ReleaseImagingInterfaces()
{
if (m_pImage != NULL)
{
m_pImage -> Release();
m_pImage = NULL;
}
if (m_pImagingFactory != NULL)
{
m_pImagingFactory -> Release();
m_pImagingFactory = NULL;
}
CoUninitialize();
}
// -----------------------------------------------------------------------------------------------
// Description:
// Create the memory DC for storing the image data.
//
// Parameters:
// hdc : [in] The source DC
// pDCInfo : [out] The created memory DC
// uiWidth : [in] The memory DC width
// uiHeight : [in] The memory DC height
//
// ----------------------------------------------------------------------------------------------
BOOL CImageMaster::CreateMemoryDC(HDC hdc,MEMORYDCINFO * pDCInfo,UINT uiWidth,UINT uiHeight)
{
BOOL bResult = FALSE;
// Create a DC that matches the device
pDCInfo -> hBitmap = CreateCompatibleBitmap(hdc,uiWidth,uiHeight);
if (pDCInfo -> hBitmap == NULL)
{
goto END;
}
pDCInfo -> hdc = CreateCompatibleDC(hdc);
if (pDCInfo -> hdc == NULL)
{
goto END;
}
// Select the bitmap into to the compatible device context
pDCInfo -> hOldSel = SelectObject(pDCInfo -> hdc,pDCInfo -> hBitmap);
pDCInfo -> uiWidth = uiWidth;
pDCInfo -> uiHeight = uiHeight;
bResult = TRUE;
END:
if (bResult == FALSE)
{
DeleteMemoryDC(pDCInfo);
memset(pDCInfo, 0 , sizeof (MEMORYDCINFO));
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Delete the memory DC to release resource
//
// Parameters:
// pDCInfo : [out] The created memory DC to be deleted.
// ----------------------------------------------------------------------------------------------
void CImageMaster::DeleteMemoryDC(MEMORYDCINFO * pDCInfo)
{
SelectObject(pDCInfo -> hdc,pDCInfo -> hOldSel);
DeleteObject(pDCInfo -> hBitmap);
DeleteDC(pDCInfo -> hdc);
memset(pDCInfo, 0 , sizeof (MEMORYDCINFO));
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the imaging interfaces whether ready or not.
//
// Parameters:
// NULL
//
// Return Values:
// TRUE - It's ready
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOKImagingInterfaces()
{
if (m_pImage == NULL || m_pImagingFactory == NULL)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the memory whether ready or not.
//
// Parameters:
// pMemDC : [in] The memory DC to checked.
//
// Return Values:
// TRUE - It's ready
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOKMemoryDC( const MEMORYDCINFO * pMemDC)
{
if (pMemDC -> hdc == NULL || pMemDC -> hBitmap == NULL || pMemDC -> hOldSel == NULL)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Caculate the draw area
//
// Parameters:
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// pDrawRect : [out] The calculated draw area.
//
// -----------------------------------------------------------------------------------------------
void CImageMaster::CalculateDrawArea(ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, RECT * pDrawRect)
{
RECT rcDraw = { 0 };
if (mode == IMG_FIT || mode == IMG_NATIVE)
{
LONG lDstWidth = (pDstRect -> right > pDstRect -> left) ? (pDstRect -> right - pDstRect -> left) : (pDstRect -> left - pDstRect -> right);
LONG lDstHeight = (pDstRect -> bottom > pDstRect -> top) ? (pDstRect -> bottom - pDstRect -> top) : (pDstRect -> top > pDstRect -> bottom);
LONG lSrcWidth = (pSrcRect == NULL) ? m_ImageInfo.Width : (pSrcRect -> right - pSrcRect -> left);
LONG lSrcHeight = (pSrcRect == NULL) ? m_ImageInfo.Height : (pSrcRect -> bottom - pSrcRect -> top);
LONG lDispLeft,lDispTop,lDispWidth,lDispHeight;
if (mode == IMG_NATIVE && lDstWidth >= lSrcWidth && lDstHeight >= lSrcHeight)
{
lDispLeft = (lDstWidth - lSrcWidth) / 2 + pDstRect -> left;
lDispTop = (lDstHeight - lSrcHeight) / 2 + pDstRect -> top;
lDispWidth = lSrcWidth ;
lDispHeight = lSrcHeight ;
}
else
{
if (lSrcWidth * lDstHeight > lDstWidth * lSrcHeight)
{
lDispWidth = lDstWidth;
lDispHeight = (LONG)(( float )lDispWidth / ( float )lSrcWidth * lSrcHeight);
lDispLeft = pDstRect -> left;
lDispTop = (lDstHeight - lDispHeight) / 2 + pDstRect -> top;
}
else if (lSrcWidth * lDstHeight < lDstWidth * lSrcHeight)
{
lDispHeight = lDstHeight;
lDispWidth = (LONG)(( float )lDispHeight / ( float )lSrcHeight * lSrcWidth);
lDispLeft = (lDstWidth - lDispWidth) / 2 + pDstRect -> left;
lDispTop = pDstRect -> top;
}
else
{
lDispWidth = lDstWidth;
lDispHeight = lDstHeight;
lDispLeft = pDstRect -> left;
lDispTop = pDstRect -> top;
}
}
rcDraw.left = lDispLeft;
rcDraw.top = lDispTop;
rcDraw.right = lDispLeft + lDispWidth;
rcDraw.bottom = lDispTop + lDispHeight;
}
else if (mode == IMG_STRETCH)
{
rcDraw = * pDstRect;
}
* pDrawRect = rcDraw;
}
// ----------------------------------------------------------------------
// Description:
// This method displays the whole image onto the specified area as to the mode value.
// If you call the function first, it may cost a long time because of the initializing, but much quickly next time.
// So you could set the bDraw to FALSE and call the function to intialize before.
//
// Parameters:
// hdc : [in] An HDC value that is the graphics context that receives output from this method.
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// bDraw : [in] If it's true, it will draw to the Dest DC immediately, or it only intializes.
//
// Return Value:
// TRUE -- Succeed
// FALSE -- Failed
// ----------------------------------------------------------------------
BOOL CImageMaster::DrawIntegrity(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw)
{
if (pDstRect == NULL)
{
return FALSE;
}
if (IsOKMemoryDC( & m_IntegrityMemDCInfo) == FALSE)
{
// The imaging interfaces may close before,
// we must open again
if (IsOKImagingInterfaces() == FALSE && Open(m_szFileName) == FALSE)
{
return FALSE;
}
if (CreateMemoryDC(hdc, & m_IntegrityMemDCInfo,m_ImageInfo.Width,m_ImageInfo.Height) == FALSE)
{
return FALSE;
}
RECT rcMemDC = { 0 , 0 ,m_ImageInfo.Width,m_ImageInfo.Height};
HRESULT hr = m_pImage -> Draw(m_IntegrityMemDCInfo.hdc, & rcMemDC,NULL);
if (FAILED(hr))
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_IntegrityMemDCInfo);
return FALSE;
}
}
BOOL bResult = TRUE;
if (bDraw == TRUE)
{
RECT rcDraw = { 0 };
CalculateDrawArea(mode,pDstRect,pSrcRect, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_IntegrityMemDCInfo,pSrcRect);
}
if (IsOKImagingInterfaces() == TRUE)
{
ReleaseImagingInterfaces();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// This method displays the Thumbnail image onto the specified area as to the mode value. If the pDstRect value is larger than the pSrcRect,
// it's the same as the DrawIntegrity() function, or it displayed the thumbnail which is not clarity enough.
// If you call the function first, it may cost a long time because of the initializing, but much quickly next time.
// So you could set the bDraw to FALSE and call the function to intialize before.
//
// Parameters:
// hdc : [in] An HDC value that is the graphics context that receives output from this method.
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// bDraw : [in] If it's true, it will draw to the Dest DC immediately, or it only intializes.
//
// Return Value:
// TRUE -- Succeed
// FALSE -- Failed
// ----------------------------------------------------------------------
BOOL CImageMaster::DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw)
{
if (pDstRect == NULL)
{
return FALSE;
}
if (IsOKMemoryDC( & m_ThumbnailMemDCInfo) == FALSE ||
m_rcLastThumbnail.right - m_rcLastThumbnail.left != pDstRect -> right - pDstRect -> left ||
m_rcLastThumbnail.bottom - m_rcLastThumbnail.top != pDstRect -> bottom - pDstRect -> top)
{
m_rcLastThumbnail = * pDstRect;
// The imaging interfaces may close before,
// we must open again
if (IsOKImagingInterfaces() == FALSE && Open(m_szFileName) == FALSE)
{
return FALSE;
}
// Delete the memory DC created before
if (IsOKMemoryDC( & m_ThumbnailMemDCInfo) == TRUE)
{
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
}
// Caculate the minimun thumbnail width and height for creating memory DC.
// The IMG_NATIVE mode is most approximately to the actual image
RECT rcMinImg = { 0 };
CalculateDrawArea(IMG_NATIVE,pDstRect,NULL, & rcMinImg);
int iImgThumWidth = (rcMinImg.right > rcMinImg.left) ? (rcMinImg.right - rcMinImg.left) : (rcMinImg.left - rcMinImg.right);
int iImgThumHeight = (rcMinImg.bottom > rcMinImg.top) ? (rcMinImg.bottom - rcMinImg.top) : (rcMinImg.top - rcMinImg.bottom);
if (CreateMemoryDC(hdc, & m_ThumbnailMemDCInfo,iImgThumWidth,iImgThumHeight) == FALSE)
{
return FALSE;
}
IImage * pImgThumbnail = NULL;
m_pImage -> GetThumbnail(iImgThumWidth,iImgThumHeight, & pImgThumbnail);
RECT rcMem = { 0 , 0 ,iImgThumWidth,iImgThumHeight};
HRESULT hr = pImgThumbnail -> Draw(m_ThumbnailMemDCInfo.hdc, & rcMem,NULL);
if (FAILED(hr))
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
return FALSE;
}
}
BOOL bResult = TRUE;
if (bDraw == TRUE)
{
RECT rcDraw = { 0 };
RECT rcImg = { 0 };
if (pSrcRect == NULL)
{
CalculateDrawArea(mode,pDstRect,NULL, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_ThumbnailMemDCInfo,NULL);
}
else
{
// Get the width and height with the ratio
rcImg.left = m_ThumbnailMemDCInfo.uiWidth * pSrcRect -> left / m_ImageInfo.Width;
rcImg.top = m_ThumbnailMemDCInfo.uiHeight * pSrcRect -> top / m_ImageInfo.Height;
rcImg.right = m_ThumbnailMemDCInfo.uiWidth * pSrcRect -> right / m_ImageInfo.Width;
rcImg.bottom = m_ThumbnailMemDCInfo.uiHeight * pSrcRect -> bottom / m_ImageInfo.Height;
CalculateDrawArea(mode,pDstRect, & rcImg, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_ThumbnailMemDCInfo, & rcImg);
}
}
if (IsOKImagingInterfaces() == TRUE)
{
ReleaseImagingInterfaces();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// Draw the source DC to dest DC
//
// Parameters:
// hdcDest : [in] Handle to the destination device context.
// pDstRect : [in] The dest area
// hdcSrc : [in] The source memory DC information
// pSrcRect : [in] The source area to be drawed
//
BOOL CImageMaster::Draw(HDC hdcDest, const RECT * pDstRect, const MEMORYDCINFO * pSrcDCInfo, const RECT * pSrcRect)
{
BOOL bResult = FALSE;
if (pSrcRect == NULL)
{
bResult = StretchBlt(hdcDest,
pDstRect -> left,
pDstRect -> top,
pDstRect -> right - pDstRect -> left,
pDstRect -> bottom - pDstRect -> top,
pSrcDCInfo -> hdc,
0 ,
0 ,
pSrcDCInfo -> uiWidth,
pSrcDCInfo -> uiHeight,
SRCCOPY);
}
else
{
bResult = StretchBlt(hdcDest,
pDstRect -> left,
pDstRect -> top,
pDstRect -> right - pDstRect -> left,
pDstRect -> bottom - pDstRect -> top,
pSrcDCInfo -> hdc,
pSrcRect -> left,
pSrcRect -> top,
pSrcRect -> right - pSrcRect -> left,
pSrcRect -> bottom - pSrcRect -> top,
SRCCOPY);
}
return bResult;
}
1.Open(const TCHAR *pcszFile)
打开一个图片文件.如果打开成功,需要调用Close()函数进行资源的释放.
2.Close()
调用Open()成功后需调用该函数进行资源的释放.
3.IsOK()
判断是否已经准备好绘制图档.
4.GetHeight()
获取图片的高度.
5.GetWidth()
获取图片的宽度.
6.DrawIntegrity(HDC hdc, ImageDrawMode mode,const RECT *pDstRect, const RECT *pSrcRect,BOOL bDraw)
绘制原始图档.如果图片过大,可能会绘制失败.
hdc:目标DC
mode:绘制的模式.
IMG_FIT - 按比例拉伸至整个pDstRect区域.
IMG_STRETCH - 填充整个pDstRect区域,而不管其比例.
IMG_NATIVE - 如果pSrcRect区域小于pDstRect,则按pSrcRect的大小在pDstRect居中显示;如果pSrcRect区域大于pDstRect,则效果和IMG_FIT相同.
pDstRect: 目标DC所绘制的区域.
pSrcRect: 源DC所需要绘制的区域.
bDraw: 为TRUE时立刻绘制到hdc;为FALSE不绘制到hdc上.因为在DrawIntegrity()函数中需要从文件中获取文件信息并创建图片DC来保存图片信息,所以第一调用的时候会比较慢,但以后由于是将图片DC直接绘制到hdc中,所以速度会大大加快.
7.DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT *pDstRect, const RECT *pSrcRect, BOOL bDraw)
绘制缩略图.如果DrawIntegrity()函数失败,调用该函数绘制缩略图可能会成功.
参数的意义和DrawIntegrity()相同.
/ /
// ImageMaster.h: interface for the CImageMaster class.
//
// Version:
// 1.1.1
//
// Date:
// 2007.08.13
/ /
#ifndef IMAGEMASTER_H
#define IMAGEMASTER_H
#include " imaging.h "
// --------------------------------------------------------------------
// Enum value
enum ImageDrawMode
{
// Fit to the play window size. How wide (height) the window is, how
// is the move. Keep aspect ratio.
IMG_FIT,
// Not support.Stretch to the play window size. Don't keep the aspect ratio.
IMG_STRETCH,
// When the size of video is smaller than the play window, it displayes
// as the video size. If it's bigger , it just like the DISP_FIT mode.
IMG_NATIVE
};
class CImageMaster
{
public :
BOOL DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw);
BOOL DrawIntegrity(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect,BOOL bDraw);
BOOL IsOK();
void Close();
UINT GetHeight();
UINT GetWidth();
BOOL Open( const TCHAR * pcszFile);
CImageMaster();
virtual ~ CImageMaster();
protected :
void CalculateDrawArea(ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect,RECT * pDrawRect);
BOOL IsOKImagingInterfaces();
void ReleaseImagingInterfaces();
IImage * m_pImage;
IImagingFactory * m_pImagingFactory;
TCHAR m_szFileName[MAX_PATH];
ImageInfo m_ImageInfo;
RECT m_rcLastThumbnail; // The last drawed area for the DrawThumbnail() function.
// It's for the memory DC information
typedef struct MemoryDCInfo
{
HBITMAP hBitmap;
HDC hdc;
HGDIOBJ hOldSel;
UINT uiWidth;
UINT uiHeight;
}MEMORYDCINFO, * PMEMORYDCINFO;
MEMORYDCINFO m_IntegrityMemDCInfo;
MEMORYDCINFO m_ThumbnailMemDCInfo;
void DeleteMemoryDC(MEMORYDCINFO * pDCInfo);
BOOL CreateMemoryDC(HDC hdc,MEMORYDCINFO * pDCInfo,UINT uiWidth,UINT uiHeight);
BOOL IsOKMemoryDC( const MEMORYDCINFO * pMemDC);
BOOL Draw(HDC hdcDest, const RECT * pDstRect, const MEMORYDCINFO * pSrcDCInfo, const RECT * pSrcRect);
};
#endif // #ifndef IMAGE_H
/ /
// Image.cpp: implementation of the CImageMaster class.
//
/ /
#include " stdafx.h "
#include " initguid.h "
#include " ImageMaster.h "
// ======================================================================
// Link the .lib
#pragma comment (lib,"Ole32.lib")
// =======================================================================
/ /
// Construction/Destruction
/ /
CImageMaster::CImageMaster():
m_pImage(NULL),
m_pImagingFactory(NULL)
{
memset(m_szFileName, 0 , sizeof (m_szFileName));
memset( & m_ImageInfo, 0 , sizeof (m_ImageInfo));
memset( & m_IntegrityMemDCInfo, 0 , sizeof (m_IntegrityMemDCInfo));
memset( & m_ThumbnailMemDCInfo, 0 , sizeof (m_ThumbnailMemDCInfo));
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
}
CImageMaster:: ~ CImageMaster()
{
Close();
}
// ----------------------------------------------------------------------
// Description:
// Open the image file
//
// Parameters:
// pcszFile : [in] The image file to open
//
// Return Value:
// TRUE -- Succeed in opening the file
// FALSE -- Failed in opening the file
// ----------------------------------------------------------------------
BOOL CImageMaster::Open( const TCHAR * pcszFile)
{
BOOL bResult = FALSE;
HRESULT hr;
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
goto END;
}
if (FAILED(hr = CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,( void ** ) & m_pImagingFactory)))
{
goto END;
}
if (FAILED(hr = m_pImagingFactory -> CreateImageFromFile(pcszFile, & m_pImage)))
{
goto END;
}
m_pImage -> GetImageInfo( & m_ImageInfo);
_tcscpy(m_szFileName,pcszFile);
bResult = TRUE;
END:
if (bResult == FALSE)
{
Close();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// Get the width of the image
//
// Parameters:
// NULL
//
// Return Value:
// 0 -- May be failure.
// others -- succeed
// ----------------------------------------------------------------------
UINT CImageMaster::GetWidth()
{
return m_ImageInfo.Width;
}
// ----------------------------------------------------------------------
// Description:
// Get the height of the image
//
// Parameters:
// NULL
//
// Return Value:
// 0 -- May be failure.
// others -- succeed
// ----------------------------------------------------------------------
UINT CImageMaster::GetHeight()
{
return m_ImageInfo.Height;
}
// ----------------------------------------------------------------------
// Description:
// Close the opened image to release the resource
//
// Parameters:
// NULL
//
// Return Value:
// NULL
// ----------------------------------------------------------------------
void CImageMaster::Close()
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_IntegrityMemDCInfo);
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
memset(m_szFileName, 0 , sizeof (m_szFileName));
memset( & m_ImageInfo, 0 , sizeof (m_ImageInfo));
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the object is read for operating. If failed in calling the Open() or never call before,
// it will return FALSE.
//
// Parameters:
// NULL
//
// Return Values:
// TRUE - It's all ready for other operating.
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOK()
{
if (IsOKMemoryDC( & m_IntegrityMemDCInfo) == FALSE &&
IsOKMemoryDC( & m_ThumbnailMemDCInfo) == FALSE &&
IsOKImagingInterfaces() == FALSE)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Release the imaging interfaces resource.
//
// ----------------------------------------------------------------------------------------------
void CImageMaster::ReleaseImagingInterfaces()
{
if (m_pImage != NULL)
{
m_pImage -> Release();
m_pImage = NULL;
}
if (m_pImagingFactory != NULL)
{
m_pImagingFactory -> Release();
m_pImagingFactory = NULL;
}
CoUninitialize();
}
// -----------------------------------------------------------------------------------------------
// Description:
// Create the memory DC for storing the image data.
//
// Parameters:
// hdc : [in] The source DC
// pDCInfo : [out] The created memory DC
// uiWidth : [in] The memory DC width
// uiHeight : [in] The memory DC height
//
// ----------------------------------------------------------------------------------------------
BOOL CImageMaster::CreateMemoryDC(HDC hdc,MEMORYDCINFO * pDCInfo,UINT uiWidth,UINT uiHeight)
{
BOOL bResult = FALSE;
// Create a DC that matches the device
pDCInfo -> hBitmap = CreateCompatibleBitmap(hdc,uiWidth,uiHeight);
if (pDCInfo -> hBitmap == NULL)
{
goto END;
}
pDCInfo -> hdc = CreateCompatibleDC(hdc);
if (pDCInfo -> hdc == NULL)
{
goto END;
}
// Select the bitmap into to the compatible device context
pDCInfo -> hOldSel = SelectObject(pDCInfo -> hdc,pDCInfo -> hBitmap);
pDCInfo -> uiWidth = uiWidth;
pDCInfo -> uiHeight = uiHeight;
bResult = TRUE;
END:
if (bResult == FALSE)
{
DeleteMemoryDC(pDCInfo);
memset(pDCInfo, 0 , sizeof (MEMORYDCINFO));
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Delete the memory DC to release resource
//
// Parameters:
// pDCInfo : [out] The created memory DC to be deleted.
// ----------------------------------------------------------------------------------------------
void CImageMaster::DeleteMemoryDC(MEMORYDCINFO * pDCInfo)
{
SelectObject(pDCInfo -> hdc,pDCInfo -> hOldSel);
DeleteObject(pDCInfo -> hBitmap);
DeleteDC(pDCInfo -> hdc);
memset(pDCInfo, 0 , sizeof (MEMORYDCINFO));
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the imaging interfaces whether ready or not.
//
// Parameters:
// NULL
//
// Return Values:
// TRUE - It's ready
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOKImagingInterfaces()
{
if (m_pImage == NULL || m_pImagingFactory == NULL)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Check the memory whether ready or not.
//
// Parameters:
// pMemDC : [in] The memory DC to checked.
//
// Return Values:
// TRUE - It's ready
// FALSE - It's not ready.
//
// ---------------------------------------------------------------------------------------------------------
BOOL CImageMaster::IsOKMemoryDC( const MEMORYDCINFO * pMemDC)
{
if (pMemDC -> hdc == NULL || pMemDC -> hBitmap == NULL || pMemDC -> hOldSel == NULL)
{
return FALSE;
}
return TRUE;
}
// -----------------------------------------------------------------------------------------------
// Description:
// Caculate the draw area
//
// Parameters:
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// pDrawRect : [out] The calculated draw area.
//
// -----------------------------------------------------------------------------------------------
void CImageMaster::CalculateDrawArea(ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, RECT * pDrawRect)
{
RECT rcDraw = { 0 };
if (mode == IMG_FIT || mode == IMG_NATIVE)
{
LONG lDstWidth = (pDstRect -> right > pDstRect -> left) ? (pDstRect -> right - pDstRect -> left) : (pDstRect -> left - pDstRect -> right);
LONG lDstHeight = (pDstRect -> bottom > pDstRect -> top) ? (pDstRect -> bottom - pDstRect -> top) : (pDstRect -> top > pDstRect -> bottom);
LONG lSrcWidth = (pSrcRect == NULL) ? m_ImageInfo.Width : (pSrcRect -> right - pSrcRect -> left);
LONG lSrcHeight = (pSrcRect == NULL) ? m_ImageInfo.Height : (pSrcRect -> bottom - pSrcRect -> top);
LONG lDispLeft,lDispTop,lDispWidth,lDispHeight;
if (mode == IMG_NATIVE && lDstWidth >= lSrcWidth && lDstHeight >= lSrcHeight)
{
lDispLeft = (lDstWidth - lSrcWidth) / 2 + pDstRect -> left;
lDispTop = (lDstHeight - lSrcHeight) / 2 + pDstRect -> top;
lDispWidth = lSrcWidth ;
lDispHeight = lSrcHeight ;
}
else
{
if (lSrcWidth * lDstHeight > lDstWidth * lSrcHeight)
{
lDispWidth = lDstWidth;
lDispHeight = (LONG)(( float )lDispWidth / ( float )lSrcWidth * lSrcHeight);
lDispLeft = pDstRect -> left;
lDispTop = (lDstHeight - lDispHeight) / 2 + pDstRect -> top;
}
else if (lSrcWidth * lDstHeight < lDstWidth * lSrcHeight)
{
lDispHeight = lDstHeight;
lDispWidth = (LONG)(( float )lDispHeight / ( float )lSrcHeight * lSrcWidth);
lDispLeft = (lDstWidth - lDispWidth) / 2 + pDstRect -> left;
lDispTop = pDstRect -> top;
}
else
{
lDispWidth = lDstWidth;
lDispHeight = lDstHeight;
lDispLeft = pDstRect -> left;
lDispTop = pDstRect -> top;
}
}
rcDraw.left = lDispLeft;
rcDraw.top = lDispTop;
rcDraw.right = lDispLeft + lDispWidth;
rcDraw.bottom = lDispTop + lDispHeight;
}
else if (mode == IMG_STRETCH)
{
rcDraw = * pDstRect;
}
* pDrawRect = rcDraw;
}
// ----------------------------------------------------------------------
// Description:
// This method displays the whole image onto the specified area as to the mode value.
// If you call the function first, it may cost a long time because of the initializing, but much quickly next time.
// So you could set the bDraw to FALSE and call the function to intialize before.
//
// Parameters:
// hdc : [in] An HDC value that is the graphics context that receives output from this method.
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// bDraw : [in] If it's true, it will draw to the Dest DC immediately, or it only intializes.
//
// Return Value:
// TRUE -- Succeed
// FALSE -- Failed
// ----------------------------------------------------------------------
BOOL CImageMaster::DrawIntegrity(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw)
{
if (pDstRect == NULL)
{
return FALSE;
}
if (IsOKMemoryDC( & m_IntegrityMemDCInfo) == FALSE)
{
// The imaging interfaces may close before,
// we must open again
if (IsOKImagingInterfaces() == FALSE && Open(m_szFileName) == FALSE)
{
return FALSE;
}
if (CreateMemoryDC(hdc, & m_IntegrityMemDCInfo,m_ImageInfo.Width,m_ImageInfo.Height) == FALSE)
{
return FALSE;
}
RECT rcMemDC = { 0 , 0 ,m_ImageInfo.Width,m_ImageInfo.Height};
HRESULT hr = m_pImage -> Draw(m_IntegrityMemDCInfo.hdc, & rcMemDC,NULL);
if (FAILED(hr))
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_IntegrityMemDCInfo);
return FALSE;
}
}
BOOL bResult = TRUE;
if (bDraw == TRUE)
{
RECT rcDraw = { 0 };
CalculateDrawArea(mode,pDstRect,pSrcRect, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_IntegrityMemDCInfo,pSrcRect);
}
if (IsOKImagingInterfaces() == TRUE)
{
ReleaseImagingInterfaces();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// This method displays the Thumbnail image onto the specified area as to the mode value. If the pDstRect value is larger than the pSrcRect,
// it's the same as the DrawIntegrity() function, or it displayed the thumbnail which is not clarity enough.
// If you call the function first, it may cost a long time because of the initializing, but much quickly next time.
// So you could set the bDraw to FALSE and call the function to intialize before.
//
// Parameters:
// hdc : [in] An HDC value that is the graphics context that receives output from this method.
// mode : [in] The image display mode.
// pDstRect : [in] A pointer to a RECT value defining the portion of the display area within the graphics context that receives the output from this method.
// psrcRect : [in] An optional pointer to a RECT that specifies, in 0.01mm units, the portion of the image to be drawn in dstRect.
// To display the entire image, set this value to NULL.
// bDraw : [in] If it's true, it will draw to the Dest DC immediately, or it only intializes.
//
// Return Value:
// TRUE -- Succeed
// FALSE -- Failed
// ----------------------------------------------------------------------
BOOL CImageMaster::DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT * pDstRect, const RECT * pSrcRect, BOOL bDraw)
{
if (pDstRect == NULL)
{
return FALSE;
}
if (IsOKMemoryDC( & m_ThumbnailMemDCInfo) == FALSE ||
m_rcLastThumbnail.right - m_rcLastThumbnail.left != pDstRect -> right - pDstRect -> left ||
m_rcLastThumbnail.bottom - m_rcLastThumbnail.top != pDstRect -> bottom - pDstRect -> top)
{
m_rcLastThumbnail = * pDstRect;
// The imaging interfaces may close before,
// we must open again
if (IsOKImagingInterfaces() == FALSE && Open(m_szFileName) == FALSE)
{
return FALSE;
}
// Delete the memory DC created before
if (IsOKMemoryDC( & m_ThumbnailMemDCInfo) == TRUE)
{
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
}
// Caculate the minimun thumbnail width and height for creating memory DC.
// The IMG_NATIVE mode is most approximately to the actual image
RECT rcMinImg = { 0 };
CalculateDrawArea(IMG_NATIVE,pDstRect,NULL, & rcMinImg);
int iImgThumWidth = (rcMinImg.right > rcMinImg.left) ? (rcMinImg.right - rcMinImg.left) : (rcMinImg.left - rcMinImg.right);
int iImgThumHeight = (rcMinImg.bottom > rcMinImg.top) ? (rcMinImg.bottom - rcMinImg.top) : (rcMinImg.top - rcMinImg.bottom);
if (CreateMemoryDC(hdc, & m_ThumbnailMemDCInfo,iImgThumWidth,iImgThumHeight) == FALSE)
{
return FALSE;
}
IImage * pImgThumbnail = NULL;
m_pImage -> GetThumbnail(iImgThumWidth,iImgThumHeight, & pImgThumbnail);
RECT rcMem = { 0 , 0 ,iImgThumWidth,iImgThumHeight};
HRESULT hr = pImgThumbnail -> Draw(m_ThumbnailMemDCInfo.hdc, & rcMem,NULL);
if (FAILED(hr))
{
ReleaseImagingInterfaces();
DeleteMemoryDC( & m_ThumbnailMemDCInfo);
memset( & m_rcLastThumbnail, 0 , sizeof (m_rcLastThumbnail));
return FALSE;
}
}
BOOL bResult = TRUE;
if (bDraw == TRUE)
{
RECT rcDraw = { 0 };
RECT rcImg = { 0 };
if (pSrcRect == NULL)
{
CalculateDrawArea(mode,pDstRect,NULL, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_ThumbnailMemDCInfo,NULL);
}
else
{
// Get the width and height with the ratio
rcImg.left = m_ThumbnailMemDCInfo.uiWidth * pSrcRect -> left / m_ImageInfo.Width;
rcImg.top = m_ThumbnailMemDCInfo.uiHeight * pSrcRect -> top / m_ImageInfo.Height;
rcImg.right = m_ThumbnailMemDCInfo.uiWidth * pSrcRect -> right / m_ImageInfo.Width;
rcImg.bottom = m_ThumbnailMemDCInfo.uiHeight * pSrcRect -> bottom / m_ImageInfo.Height;
CalculateDrawArea(mode,pDstRect, & rcImg, & rcDraw);
bResult = Draw(hdc, & rcDraw, & m_ThumbnailMemDCInfo, & rcImg);
}
}
if (IsOKImagingInterfaces() == TRUE)
{
ReleaseImagingInterfaces();
}
return bResult;
}
// ----------------------------------------------------------------------
// Description:
// Draw the source DC to dest DC
//
// Parameters:
// hdcDest : [in] Handle to the destination device context.
// pDstRect : [in] The dest area
// hdcSrc : [in] The source memory DC information
// pSrcRect : [in] The source area to be drawed
//
BOOL CImageMaster::Draw(HDC hdcDest, const RECT * pDstRect, const MEMORYDCINFO * pSrcDCInfo, const RECT * pSrcRect)
{
BOOL bResult = FALSE;
if (pSrcRect == NULL)
{
bResult = StretchBlt(hdcDest,
pDstRect -> left,
pDstRect -> top,
pDstRect -> right - pDstRect -> left,
pDstRect -> bottom - pDstRect -> top,
pSrcDCInfo -> hdc,
0 ,
0 ,
pSrcDCInfo -> uiWidth,
pSrcDCInfo -> uiHeight,
SRCCOPY);
}
else
{
bResult = StretchBlt(hdcDest,
pDstRect -> left,
pDstRect -> top,
pDstRect -> right - pDstRect -> left,
pDstRect -> bottom - pDstRect -> top,
pSrcDCInfo -> hdc,
pSrcRect -> left,
pSrcRect -> top,
pSrcRect -> right - pSrcRect -> left,
pSrcRect -> bottom - pSrcRect -> top,
SRCCOPY);
}
return bResult;
}
打开一个图片文件.如果打开成功,需要调用Close()函数进行资源的释放.
2.Close()
调用Open()成功后需调用该函数进行资源的释放.
3.IsOK()
判断是否已经准备好绘制图档.
4.GetHeight()
获取图片的高度.
5.GetWidth()
获取图片的宽度.
6.DrawIntegrity(HDC hdc, ImageDrawMode mode,const RECT *pDstRect, const RECT *pSrcRect,BOOL bDraw)
绘制原始图档.如果图片过大,可能会绘制失败.
hdc:目标DC
mode:绘制的模式.
IMG_FIT - 按比例拉伸至整个pDstRect区域.
IMG_STRETCH - 填充整个pDstRect区域,而不管其比例.
IMG_NATIVE - 如果pSrcRect区域小于pDstRect,则按pSrcRect的大小在pDstRect居中显示;如果pSrcRect区域大于pDstRect,则效果和IMG_FIT相同.
pDstRect: 目标DC所绘制的区域.
pSrcRect: 源DC所需要绘制的区域.
bDraw: 为TRUE时立刻绘制到hdc;为FALSE不绘制到hdc上.因为在DrawIntegrity()函数中需要从文件中获取文件信息并创建图片DC来保存图片信息,所以第一调用的时候会比较慢,但以后由于是将图片DC直接绘制到hdc中,所以速度会大大加快.
7.DrawThumbnail(HDC hdc, ImageDrawMode mode, const RECT *pDstRect, const RECT *pSrcRect, BOOL bDraw)
绘制缩略图.如果DrawIntegrity()函数失败,调用该函数绘制缩略图可能会成功.
参数的意义和DrawIntegrity()相同.