Win32程序中显示JPG、GIF

转自:http://dev.csdn.net/article/10/10632.shtm

 

用VB的picture控件我可以轻松的搞定JPG和GIF,可到了VC、MFC下,一切都变得无处适从。怎么办呢?

Follow me~

VB的picture控件基于COM的IPicture接口,IPicture一般面向bitmap,其实Windows提供了一个显示BMP、JPG、GIF的标准方法,你要做的就是实例化IPicture以及它的调用,为此我们不能像通常那样调用CoCreateInstance,在这我们用一个叫OleLoadPicture的函数:


IStream* pstm = // 流
IPicture* pIPicture;
hr = OleLoadPicture(pstm, 0, FALSE, IID_IPicture, (void**)&pIPicture);

OleLoadPicture 函数从流中读取图片,同时创建该图片的IPicture对象.

rc = //显示图片的矩形
// 将矩形结构 rc 转换成 HIMETRIC
spIPicture->Render(pDC, rc);


IPicture 可以显示大部分图片包括BMP/JPG/GIF甚至icon等等!

但在细节部分有些小技巧,所以我写了一个简单的演示程序,叫做ImgView(如图)。

           ImgView

ImgView是一个典型的有文档/视支持的MFC应用程序,其中应用了一个我所写的类---CPicture,CPicture对MFC程序员十分友好,例如:CPicture允许你直接打开图形文件,CFile、CArchive代替了流;同样你可以从资源中打开图片,对于从资源中打开图片,你所需要做的仅仅是:

CPicture pic(ID_MYPIC); // 读取图片
CRect rc(0,0,100,100);  // 构造所要显示的矩形
pic.Render(pDC, rc);    // 显示它

这就完了么?不,你还需要把你的JPG加入资源,这里你要把资源格式定义成"IMAGE", 所以你必须编辑RC文件像下面这样:

ID_MYPIC IMAGE MOVEABLE PURE "res//MyPic.jpg"

OK,CPicture的一般应用就是这样,它有一个CComQIPtr,指向IPicture接口,这个Ptr将通过调用OleLoadPicture做初始化,CPicture提供了IPicture的所有方法,因此你不必自己调用IPicture::get_Handle等等不属于MFC的东西了。

顺便说的是,在我写完CPicture字后我发现MFC也提供了一个叫做CPictureHolder的类做了更多同样的事,你可以在afxctl.h中找到它:)


下面我把CPicture用在典型的文档/视图程序中,更清楚的讲解怎么使用

class CPictureDoc : public CDocument {
protected:
  CPicture m_pict; // CPicture作为成员变量
};

在CPictureDoc::Serialize中读取图片
void CPictureDoc::Serialize(CArchive& ar)
{
  if (ar.IsLoading()) {
    m_pict.Load(ar);
  }
}
在CPictureView::OnDraw中显示图片:
void CPictureView::OnDraw(CDC* pDC)
{
  CPictureDoc* pDoc = GetDocument();
  CPicture* ppic = pDoc->GetPicture();
  CRect rc;
  GetImageRect(rc);
  ppic->Render(pDC,rc);
}
这里rc的尺寸很另你费解的话,你可以调用CPicture::GetImageSize
接下来就是就是处理ImgView的细节问题了,比如把图片在视图中的剩余区域画成黑色...
这里不讨论了。


ImgView

也许你想更方便地在对话框中使用JPG、GIF,为此我准备了CPictureCtrl 类,
用这个类你可以在对话框或其他任何窗口中使用JPG等等。例如:

class CAboutDialog : public CDialog {
protected:
  CPictureCtrl m_wndPict;
  virtual BOOL OnInitDialog();
};
BOOL CAboutDialog::OnInitDialog()
{
  m_wndPict.SubclassDlgItem(IDC_MYIMAGE,this);//IDC_MYIMAGE是静态
  return CDialog::OnInitDialog();
}

 


 

作者Blog: http://blog.csdn.net/111222/
相关文章

对该文的评论
CSDN 网友 ( 2005-07-04)
影射模式为MM_ISOTROPIC(或者说非MM_TEXT),显示不出.wmf文件(.bmp的可以),为什么呀!(痛苦中,恳请那位仁兄指点迷津)
goodboy1881 ( 2004-11-30)
我显示出来的怎么是倒的图像呢?
jiangsheng ( 2002-02-28)
我的贴出来的代码怎么成了这个样子:(
jiangsheng ( 2002-02-28)
//-----------------------------------------------------------------------------
// Picture (Implementations) Version 1.00
//
// Routins 4 Showing Picture Files... (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
//
// Author: Dr. Yovav Gad, EMail: [email protected] ,Web: www.SuperMain.com
//=============================================================================
//Edited by Jiang Sheng,[email protected] Jan 2002

// Full Story:
// ~~~~~~~~~~~
// There R Many Libraries To Handle Image Files, Anyway Most Of Them Do Not
// Include Source Files Or Just Very Complicated To Implement / Understand,
// 
// After Many Days Of Searching (And Not Finding) a Way To Load a JPG From a
// Resource And Show It On a *Dialog Based* Application, I Decided 2 Take Steps
//
// So I Created What I Call a Very *Simple* & Useful Class,
// It Can Easily Implemented By Adding It To a Project, And U Do Not Have To
// Be a Real JPEG Freak - And Invent All Header Reading From The Beginning
// (It Uses The IPicture Interface - Same Way As Internet Explorer Does)
//
// I Would Like To Thank Mr.Peter Hendrix For His Wonderful Work
// That I Found On: http://www.thecodeproject.com/bitmap/cpicture.asp
// Which I Was Inspired And Got The IPicture Interface Idea From...
//
// Guess U Will Find It Useful,
// Appreciate If U Can Mention My Name On Your Final Code,
// Please Feel Free To Send Me Any Improvements Or SaveAsJPG() Functions:
//
// (This Program Has No Bugs - Only Undocumented Solutions)
//
// Author: Dr. Yovav Gad, EMail: [email protected] ,Web: www.SuperMain.com
//
//--------------------------Example & Usage 4 Dummies--------------------------
//
//  U Need 2 Add "CPicture.CPP" and "CPicture.H" Into Your Project (From FileView)
//  So U Will Get Control Over The Functions In This Class,
//  Then U Can Create a Picture Object And Show It On a Device Context
//
//  CPicture m_Picture;  // Create a Picture Object (An Instance Of This Class)
//  #include "Picture.h" // Make Sure U Include This Where U Gonna Create The Object...
//
//  Load Picture Data Into The IPicture Interface (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// m_Picture.Load("Test.JPG"); // Load From a File - Just Load It (Show Later)
// m_Picture.Load(IDR_TEST, "JPG"); // Load From a Resource - Just Load It (Show Later)
//  (U Must Include IDR_TEST In Your Resources Under a Custom Name, 4 Example - "JPG")
///////////////add by jiangsheng
// m_Picture.CreateFromIcon(hIcon);//copy image from handle
// m_Picture.CreateFromBitmap(hBitMap);//copy image from handle
///////////////end add 
//  
//  When Using DC Object On a *Dialog Based* Application (CPaintDC dc(this);)
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// m_Picture.UpdateSizeOnDC(&dc); // Get Picture Dimentions In Pixels
// m_Picture.Show(&dc, CRect(0,0,100,100)); // Change Original Dimentions

////////////////removed by jiangsheng
// m_Picture.ShowBitmapResource(&dc, IDB_TEST, CPoint(0,0)); // Show Bitmap Resource
////////////////end remove

//  OR When Using a Pointer On a "Regular" MFC Application (CDC* pDC)
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// m_Picture.UpdateSizeOnDC(pDC); // Get Picture Dimentions In Pixels
// m_Picture.Show(pDC, CPoint(0,0), CPoint(m_Picture.m_Width, m_Picture.m_Height), 0,0);
// m_Picture.Show(pDC, CRect(0,0,100,100)); // Change Original Dimentions

////////////////removed by jiangsheng
// m_Picture.ShowBitmapResource(pDC, IDB_TEST, CPoint(0,0)); // Show Bitmap Resource
////////////////end remove

//  Show Picture Information
//  ~~~~~~~~~~~~~~~~~~~~~~~~
// CString S;
// S.Format("Size = %4d/nWidth = %4d/nHeight = %4d/nWeight = %4d/n",
// m_Picture.m_Weight, m_Picture.m_Width, m_Picture.m_Height, m_Picture.m_Weight);
// AfxMessageBox(S);
//
//----------------------------Cut The Bullshit Here----------------------------
//Edited by Jiang Sheng,[email protected] Jan 2002
//to add stretch and resource support
#include "stdafx.h"
#include "Picture.h"
#include "Windows.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define HIMETRIC_INCH 2540
#define ERROR_TITLE "CPicture Error" // Error Title (Related To This Class)...
//-----------------------------------------------------------------------------
// Does:   Constructor - Create a New CPicture Object To Hold Picture Data
// ~~~~
//
//-----------------------------------------------------------------------------
CPicture::CPicture()
//=============================================================================
{
m_IPicture = NULL;
m_Height = 0;
m_Weight = 0;
m_Width = 0;
}

//-----------------------------------------------------------------------------
// Does:   Destructor - Free Data And Information From The CPicture Object
// ~~~~
//
//-----------------------------------------------------------------------------
CPicture::~CPicture()
//=============================================================================
{
if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks...
}


//-----------------------------------------------------------------------------
// Does:   Free The Allocated Memory That Holdes The IPicture Interface Data
// ~~~~    And Clear Picture Information
//
// Note:   This Might Also Be Useful If U Only Need To Show The Picture Once
// ~~~~~   Or If U Copy The Picture To The Device Context, So It Can Still
//         Remain On Screen - But IPicture Data Is Not Needed No More
//
//-----------------------------------------------------------------------------
void CPicture::FreePictureData()
//=============================================================================
{
if(m_IPicture != NULL)
{
m_IPicture->Release();
m_IPicture = NULL;
m_Height = 0;
m_Weight = 0;
m_Width = 0;
}
}

//-----------------------------------------------------------------------------
// Does:   Open a Resource And Load It Into IPicture (Interface)
// ~~~~    (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
//
// Note:   When Adding a Bitmap Resource It Would Automatically Show On "Bitmap"
// ~~~~    This NOT Good Coz We Need To Load It From a Custom Resource "BMP"
//         To Add a Custom Rresource: Import Resource -> Open As -> Custom
//         (Both .BMP And .DIB Should Be Found Under "BMP")
//
// InPut:  ResourceName - As a UINT Defined (Example: IDR_PICTURE_RESOURCE)
// ~~~~~   ResourceType - Type Name (Example: "JPG")
//
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
BOOL CPicture::Load(HINSTANCE hInstance,LPCTSTR lpszResourceName, LPCSTR ResourceType)
//=============================================================================
{
HGLOBAL hGlobal = NULL;
HRSRC hSource = NULL;
LPVOID lpVoid  = NULL;
int nSize   = 0;
BOOL bResult=FALSE;
if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks...

hSource = FindResource(hInstance, lpszResourceName, ResourceType);

if(hSource == NULL)
{
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "FindResource() Failed/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
return(FALSE);
}

hGlobal = LoadResource(hInstance, hSource);
if(hGlobal == NULL)
{
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "LoadResource() Failed/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
return(FALSE);
}

lpVoid = LockResource(hGlobal);
if(lpVoid == NULL)
{
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "LockResource() Failed/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
return(FALSE);
}

nSize = (UINT)SizeofResource(hInstance, hSource);
if(LoadPictureData((BYTE*)hGlobal, nSize)) bResult = TRUE;

UnlockResource(hGlobal); // 16Bit Windows Needs This
FreeResource(hGlobal); // 16Bit Windows Needs This (32Bit - Automatic Release)

m_Weight = nSize; // Update Picture Size Info...
GetImageSize();
return(bResult);
}

//-----------------------------------------------------------------------------
// Does:   Open a File And Load It Into IPicture (Interface)
// ~~~~    (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
//
// InPut:  sFilePathName - Path And FileName Target To Save
// ~~~~~   
//
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
BOOL CPicture::Load(CString sFilePathName)
//=============================================================================
{
if(!PathFileExists(sFilePathName))return FALSE;
BOOL bResult = FALSE;
CFile PictureFile;
CFileException e;
int nSize = 0;

if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks...

if(PictureFile.Open(sFilePathName, CFile::modeRead | CFile::typeBinary, &e))
{
nSize = PictureFile.GetLength();
BYTE* pBuffer = new BYTE[nSize];

if(PictureFile.Read(pBuffer, nSize) > 0)
{
if(LoadPictureData(pBuffer, nSize)) bResult = TRUE;
}

PictureFile.Close();
delete [] pBuffer;
}
else // Open Failed...
{
TCHAR szCause[255];
e.GetErrorMessage(szCause, 255, NULL);
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, szCause, ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
bResult = FALSE;
}

m_Weight = nSize; // Update Picture Size Info...
GetImageSize();
return(bResult);
}

//-----------------------------------------------------------------------------
// Does:   Read The Picture Data From a Source (File / Resource)
// ~~~~    And Load It Into The Current IPicture Object In Use
//
// InPut:  Buffer Of Data Source (File / Resource) And Its Size
// ~~~~~   
//
// OutPut: Feed The IPicture Object With The Picture Data
// ~~~~~~  (Use Draw Functions To Show It On a Device Context)
//         TRUE If Succeeded...
//-----------------------------------------------------------------------------
BOOL CPicture::LoadPictureData(BYTE *pBuffer, int nSize)
//=============================================================================
{
BOOL bResult = FALSE;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);

if(hGlobal == NULL)
{
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "Can not allocate enough memory/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
return(FALSE);
}

void* pData = GlobalLock(hGlobal);
memcpy(pData, pBuffer, nSize);
GlobalUnlock(hGlobal);

IStream* pStream = NULL;

if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
{
HRESULT hr;
if((hr = OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&m_IPicture)) == E_NOINTERFACE)
{
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "IPicture interface is not supported/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
return(FALSE);
}
else // S_OK
{
pStream->Release();
pStream = NULL;
bResult = TRUE;

}
}

FreeResource(hGlobal); // 16Bit Windows Needs This (32Bit - Automatic Release)

return(bResult);
}

//-----------------------------------------------------------------------------
// Does:   Draw The Loaded Picture Direct To The Client DC
// ~~~~
//
// Note:   Bigger OR Smaller Dimentions Than The Original Picture Size
// ~~~~    Will Draw The Picture Streached To Its New Given NEW Dimentions...
//
// InPut:  pDC - Given DC To Draw On
// ~~~~~   pSrcRect- Dimentions Of The Picture To Draw From(As a Rectangle)
// DrawRect - Dimentions Of The Picture To Draw To(As a Rectangle)
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
//=============================================================================
#define HIMETRIC_INCH 2540
BOOL CPicture::Show(CDC* pDC, LPRECT pDrawRect, LPRECT pSrcRect/*=NULL*/)
{
    if (pDC == NULL || m_IPicture == NULL) return FALSE;
    
CRect recrDest(pDrawRect);

    long Width  = 0;
    long Height = 0;
    m_IPicture->get_Width(&Width);
    m_IPicture->get_Height(&Height);

CRect SrcRect(0,0,Width,Height);

if(pSrcRect){
SrcRect=*pSrcRect;
// convert pixels to himetric 
SrcRect.bottom =MulDiv(SrcRect.bottom, HIMETRIC_INCH,GetDeviceCaps(pDC->m_hDC, LOGPIXELSX));
SrcRect.left =MulDiv(SrcRect.left, HIMETRIC_INCH,GetDeviceCaps(pDC->m_hDC, LOGPIXELSX));
SrcRect.right =MulDiv(SrcRect.right, HIMETRIC_INCH,GetDeviceCaps(pDC->m_hDC, LOGPIXELSX));
SrcRect.top =MulDiv(SrcRect.top, HIMETRIC_INCH,GetDeviceCaps(pDC->m_hDC, LOGPIXELSX));
}
CRect DrawRect(pDrawRect);
//DrawRect.NormalizeRect();
//SrcRect.NormalizeRect();
    HRESULT hrP = NULL;

    hrP = m_IPicture->Render(pDC->m_hDC,
                      DrawRect.left,                  // Left
                      DrawRect.top,                   // Top
                      DrawRect.Width(), // Right
                      DrawRect.Height(), // Bottom
                      SrcRect.left,
                      SrcRect.top,
                      SrcRect.Width(),
                      SrcRect.Height(),
                      &DrawRect);

    if (SUCCEEDED(hrP)) return(TRUE);
AfxThrowMemoryException();
    return(FALSE);
}
//removed bu jiangsheng
//-----------------------------------------------------------------------------
// Does:   Draw The Loaded Picture Direct To The Client DC
// ~~~~
//
// Note:   Bigger OR Smaller Dimentions Than The Original Picture Size
// ~~~~    Will Draw The Picture Streached To Its New Given Dimentions...
//
// InPut:  pDC - Given DC To Draw On
// ~~~~~   LeftTop - Opening Point To Start Drawing (Left,Top)
//         WidthHeight - Dimentions Of The Picture To Draw (Width,Height)
//         MagnifyX - Magnify Pixel Width, 0 = Default (No Magnify)
//         MagnifyY - Magnify Pixel Height, 0 = Default (No Magnify)
//
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
/*BOOL CPicture::Show(CDC *pDC, CPoint LeftTop, CPoint WidthHeight, int MagnifyX, int MagnifyY)
//=============================================================================
{
    if (pDC == NULL || m_IPicture == NULL) return FALSE;
    
    long Width  = 0;
    long Height = 0;
    m_IPicture->get_Width(&Width);
    m_IPicture->get_Height(&Height);
if(MagnifyX == NULL) MagnifyX = 0;
if(MagnifyY == NULL) MagnifyY = 0;
MagnifyX = int(MulDiv(Width, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH) * MagnifyX);
MagnifyY = int(MulDiv(Height,pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH) * MagnifyY);

CRect DrawRect(LeftTop.x, LeftTop.y, MagnifyX, MagnifyY);

    HRESULT hrP = NULL;

    hrP = m_IPicture->Render(pDC->m_hDC,
                      LeftTop.x,               // Left
                      LeftTop.y,               // Top
                      WidthHeight.x +MagnifyX, // Width
                      WidthHeight.y +MagnifyY, // Height
                      0,
                      Height,
                      Width,
                      -Height,
                      &DrawRect);

    if(SUCCEEDED(hrP)) return(TRUE);

HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "Can not allocate enough memory/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
    return(FALSE);
}
*/
//end removed 
//-----------------------------------------------------------------------------
// Does:   Saves The Picture That Is Stored In The IPicture Object As a Bitmap
// ~~~~    (Converts From Any Known Picture Type To a Bitmap / Icon File)
//
// InPut:  sFilePathName - Path And FileName Target To Save
// ~~~~~
//
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
BOOL CPicture::SaveAsBitmap(CString sFilePathName)
//=============================================================================
{
BOOL bResult = FALSE;
ILockBytes *Buffer = 0;
IStorage   *pStorage = 0;
IStream    *FileStream = 0;
BYTE    *BufferBytes;
STATSTG BytesStatistics;
DWORD OutData;
long OutStream;
CFile BitmapFile; CFileException e;
double SkipFloat = 0;
DWORD ByteSkip = 0;
_ULARGE_INTEGER RealData;

CreateILockBytesOnHGlobal(NULL, TRUE, &Buffer); // Create ILockBytes Buffer

HRESULT hr = ::StgCreateDocfileOnILockBytes(Buffer,
 STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage);

hr = pStorage->CreateStream(L"PICTURE",
 STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, 0, &FileStream);

m_IPicture->SaveAsFile(FileStream, TRUE, &OutStream); // Copy Data Stream
FileStream->Release();
pStorage->Release();
Buffer->Flush(); 

// Get Statistics For Final Size Of Byte Array
Buffer->Stat(&BytesStatistics, STATFLAG_NONAME);

// Cut UnNeeded Data Coming From SaveAsFile() (Leave Only "Pure" Picture Data)
SkipFloat = (double(OutStream) / 512); // Must Be In a 512 Blocks...
if(SkipFloat > DWORD(SkipFloat)) ByteSkip = (DWORD)SkipFloat + 1;
else ByteSkip = (DWORD)SkipFloat;
ByteSkip = ByteSkip * 512; // Must Be In a 512 Blocks...

// Find Difference Between The Two Values
ByteSkip = (DWORD)(BytesStatistics.cbSize.QuadPart - ByteSkip);

// Allocate Only The "Pure" Picture Data
RealData.LowPart = 0;
RealData.HighPart = 0;
RealData.QuadPart = ByteSkip;
BufferBytes = (BYTE*)malloc(OutStream);
if(BufferBytes == NULL)
{
Buffer->Release();
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "Can not allocate enough memory/t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
}

Buffer->ReadAt(RealData, BufferBytes, OutStream, &OutData);

if(BitmapFile.Open(sFilePathName, CFile::typeBinary | CFile::modeCreate | CFile::modeWrite, &e))
{
BitmapFile.Write(BufferBytes, OutData);
BitmapFile.Close();
bResult = TRUE;
}
else // Write File Failed...
{
TCHAR szCause[255];
e.GetErrorMessage(szCause, 255, NULL);
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, szCause, ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
bResult = FALSE;
}

Buffer->Release();
free(BufferBytes);

return(bResult);
}

//-----------------------------------------------------------------------------
// Does:   Get The Original Picture Pixel Size (Ignor What Current DC Is Using)
// ~~~~    Pointer To a Device Context Is Needed For Pixel Calculation,
//
//         Also Updates The Class's Height And Width Properties,
//         (Coz Till Now We Had No Device Context To Work With...96 DPI Assumed)
//
// InPut:  The Client DC (Needed To Check The Size Of The Pixels)
// ~~~~~
//
// OutPut: TRUE If Succeeded...
// ~~~~~~
//-----------------------------------------------------------------------------
BOOL CPicture::UpdateSizeOnDC(CDC *pDC)
//=============================================================================
{
if(pDC == NULL || m_IPicture == NULL) { m_Height = 0; m_Width = 0; return(FALSE); };

    m_IPicture->get_Height(&m_Height);
    m_IPicture->get_Width(&m_Width);

// Get Current DPI - Dot Per Inch
    int CurrentDPI_X = pDC->GetDeviceCaps(LOGPIXELSX);
    int CurrentDPI_Y = pDC->GetDeviceCaps(LOGPIXELSY);

// Use a "Standard" Print (When Printing)
    if(pDC->IsPrinting())
{
CurrentDPI_X = 96;
        CurrentDPI_Y = 96;
}

    m_Height = MulDiv(m_Height, CurrentDPI_Y, HIMETRIC_INCH);
    m_Width  = MulDiv(m_Width,  CurrentDPI_X, HIMETRIC_INCH);

    return(TRUE);
}

BOOL CPicture::CreateFromIcon(HICON hIcon)
{
BOOL bResult=FALSE;
if(hIcon){
PICTDESC desc;
desc.cbSizeofstruct = sizeof(PICTDESC);
desc.picType = PICTYPE_ICON;
desc.icon.hicon= hIcon;
m_Weight = 0;
if(FAILED(::OleCreatePictureIndirect(&desc,IID_IPicture,FALSE,(LPVOID*)&m_IPicture))){
bResult=FALSE;
}
else{
bResult=TRUE;
}
}
GetImageSize();
return bResult;
}

BOOL CPicture::CreateFromBitmap(HBITMAP hBitmap)
{
BOOL bResult=FALSE;
if(hBitmap){
PICTDESC desc;
desc.cbSizeofstruct = sizeof(PICTDESC);
desc.picType = PICTYPE_BITMAP;
desc.bmp.hbitmap = hBitmap;
desc.bmp.hpal = 0;
m_Weight = 0;
if(FAILED(::OleCreatePictureIndirect(&desc,IID_IPicture,FALSE,(LPVOID*)&m_IPicture))){
bResult=FALSE;
}
else
bResult=TRUE;
}
GetImageSize();
return bResult;
}

void CPicture::GetImageSize()
{
if(m_IPicture != NULL){// Do Not Try To Read From Memory That Is Not Exist...
m_IPicture->get_Height(&m_Height);
m_IPicture->get_Width(&m_Width);
// Calculate Its Size On a "Standard" (96 DPI) Device Context
m_Height = MulDiv(m_Height, 96, HIMETRIC_INCH);
m_Width  = MulDiv(m_Width,  96, HIMETRIC_INCH);
}
else{// Picture Data Is Not a Known Picture Type
m_Height = 0;
m_Width = 0;
m_Weight=0;
}
}
void CPicture::UnLoadPicture()
//=============================================================================
{
FreePictureData();
}
jiangsheng ( 2002-02-28)
我用的IPicture封装,添加了拉伸和从句柄读入图像的功能
//-----------------------------------------------------------------------------
// Picture (Prototypes) Version 1.00
//
// Routins 4 Showing Picture Files... (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
//
// Author: Dr. Yovav Gad, EMail: [email protected] ,Web: www.SuperMain.com
//=============================================================================
//Edited by Jiang Sheng,[email protected] Jan 2002
//to add stretch and resource support

#if !defined(AFX_PICTURE_H__COPYFREE_BY_YOVAV_GAD__SOURCES_AT_SUPERMAIN_DOT_COM__INCLUDED_)
#define AFX_PICTURE_H__COPYFREE_BY_YOVAV_GAD__SOURCES_AT_SUPERMAIN_DOT_COM__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "ocidl.h"
class CPicture
{
public:
void FreePictureData();
BOOL Load(CString sFilePathName);
BOOL Load(HINSTANCE hInstance,LPCTSTR lpszResourceName, LPCSTR ResourceType);
BOOL LoadPictureData(BYTE* pBuffer, int nSize);
BOOL SaveAsBitmap(CString sFilePathName);
//add by jiangsheng
//BOOL Show(CDC* pDC, CPoint LeftTop, CPoint WidthHeight, int MagnifyX, int MagnifyY);
BOOL CreateFromIcon(HICON hIcon);//copy image from handle
BOOL CreateFromBitmap(HBITMAP hBitMap);//copy image from handle
//end add
//change by jiangsheng
BOOL Show(CDC* pDC, LPRECT pDrawRect/*in logical units*/, LPRECT pSrcRect=NULL/*in pixels, if is NULL,draw the whole image*/);
//end change
//remove by jiangsheng
//BOOL ShowBitmapResource(CDC* pDC, const int BMPResource, CPoint LeftTop);
//pSrcRect:
//pDrawRect:in device units;
//end remove
BOOL UpdateSizeOnDC(CDC* pDC);
void UnLoadPicture();
void GetImageSize();
CPicture();
virtual ~CPicture();
BOOL IsLoaded()const{return m_IPicture!=NULL;}
protected:
IPicture* m_IPicture; // Same As LPPICTURE (typedef IPicture __RPC_FAR *LPPICTURE)
public:
LONG      m_Height; // Height (In Pixels Ignor What Current Device Context Uses)
LONG      m_Weight; // Size Of The Image Object In Bytes (File OR Resource)
LONG      m_Width;  // Width (In Pixels Ignor What Current Device Context Uses)

};

#endif // !defined(AFX_PICTURE_H__COPYFREE_BY_YOVAV_GAD__SOURCES_AT_SUPERMAIN_DOT_COM__INCLUDED_)

你可能感兴趣的:(Win32程序中显示JPG、GIF)