A simple way to display JPEG, GIF format images under VC

zhaozj2021-02-08  258

I. Introduction

The JPEG image compression criterion is a damaged image compression standard, but because the intraocular vision is insensitive, the compressed picture quality has not changed, and it has been widely recognized with a higher compression ratio. Although only 256 color but it has a high compression ratio for less color images, even more than JPEG standards, it also recognizes extensive recognition. However, as an important development tool for many programmers - Microsoft Visual C 6.0's MFC library has good support for the BMP bitmap file without any compressed, can be read, displayed, stored even in memory. Memory bitmap. Since the image in the BMP format does not have any compression, whether as the external file of the program, it is necessary to occupy a large amount of space as the internal resources of the program, especially the latter will greatly increase the length of the executable. It can be seen that if it can be used to replace the application of the BMP file in the VC in the JPEG or GIF format of the BMP file, it is undoubtedly very attractive.

Second, design ideas

Although there are some operations, other format images such as JPEG, GIF, but in general, it is not convenient to use, the author has explored, summed up an OLE method with the COM interface to achieve the above A simple way of function, now introduces the following to readers:

Below we want to use iPicture's COM interface, it is necessary to do some understanding of the image interface: This interface mainly manages image objects and its properties, and image objects provide a bitmap, icon, and primitives, etc., provide an abstraction with language. Like standard font objects, the system also provides standard implementation of image objects. Its main interface is iPicture and iPictureDisp, which are derived from the IDispatch interface to access the properties of the image by automation. Image objects also support external interface iPropertynNotifySink so that users can make decisions when the image properties change. Image object also supports the IPersistStream interface, so it can save yourself from an instance object of an iStream interface, and the iStream interface also supports data reading and writing of convection objects.

We can load images from the stream containing image data using a function OLELOADPICTURE. This function simplifies the creation process of stream-based image objects, you can create a new image object and initialize it in the stream. Its function prototype is:

StDAPI OLELOADPICTURE (ISTREAM * PSTREAM, / / ​​pointing to a pointer LONG LSIZE that contains image data, // The number of bytes read from the stream BOOL Frunmode, // Image attribute corresponds to the initial value RIID, // involves The interface identifier describes the address of the interface pointer to the interface pointer to be returned to the address of the interface pointer variable used in the RRID);

Third, the specific implementation

Before displaying the image, you first get the storage path of the image file. Here, the standard file open dialog box is used to select the image file, and the file name is stored in the CSTRING type variable m_spath:

Cfiledialog DLG (True, "JPG", "*. JPG",

OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,

"JPEG file (* .jpg) | * .jpg | GIF file (* .gif) | * .gif ||", null;

IF (DLG.Domodal () == iDOK)

{

m_spath = dlg.getpathname ();

Invalidate ();

}

For the simple meter, the code displayed by the graphic is written directly in the onDraw in the view class, first open the file and determine the availability of the file, and put the file content into the stream of ISTREAM PSTM:

IStream * PSTM;

CFileStatus FStatus; cfile file;

Long Cb;

......

IF (file.open (m_path, cfile :: MODEREAD && file.getstatus (m_path, fstatus) && ((cb = fstatus.m_size)! = -1))

{

Hglobal Hglobal = GlobalAlloc (GMEM_MOVEABLE, CB);

LPVOID PVDATA = NULL;

IF (hglobal! = null)

{

IF ((pvdata = globalock (hglobal))! = NULL)

{

File.readhuge (PVDATA, CB);

GlobalUnlock (Hglobal);

CreatestReamonhglobal (Hglobal, True, & PSTM);

}

}

}

Then, call the OLELOADPICTURE function directly from the stream:

IPicture * PPIC;

......

OLELOADPICTURE (PSTM, FSTATUS.M_SIZE, TRUE, IID_IPICTURE, (LPVOID *) & PPIC);

Since this function sometimes causes failure, it should be used to make some appropriate protection with successded shadromacrom, and only the following image display work is only available under the premise of data loading success:

IF (Succeeded (PSTM, FSTATUS.M_SIZE, TRUE, IID_IPICTURE, (LPVOID *) & PPIC)))))

{

OLE_XSIZE_HIMETRIC HMWIDTH;

OLE_YSIZE_HIMETRIC HMHEIGHT;

PPIC-> Get_Width (& HMWIDTH);

PPIC-> Get_Height (& hmheight);

Double fx, fy;

......

FX = (double) PDC-> GetDeviceCaps (Horzres) * (Double) HMWIDTH / ((Double) PDC-> getDeviceCaps (Horzsize) * 100.0);

Fy = (double) PDC-> getDeviceCaps (Vertres) * (Double) hmheight / (double) PDC-> getDeviceCaps (Vertsize) * 100.0);

IF (Failed (PPIC-> Render (* PDC, 0, 0, (DWORD) FX, (DWORD) FY, 0, HMHEIGHT, HMWIDTH, -HMHEIGHT, NULL))))

AfxMessageBox ("Rendering Image Failed!");

PPIC-> Release ();

}

Else

AFXMessageBox ("Load Image from the stream!");

The display work is mainly completed by the render function of the iPicture interface object, which is mainly used to draw the specified portion of the image to the specified location of the specified device environment. The prototype is as follows:

HRESULT RENDER (HDC HDC, // Rendering Image Using Image Environment Handle

Long x, // horizontal coordinates on HDC

Long Y, // Vertical coordinates on HDC

Long cx, // image width

Long cyog, // image height

OLE_XPOS_HIMETRIC XSRC, // Level offset on the source image

OLE_YPOS_HIMETRIC YSRC, / / ​​Vertical Offset on the Source Image

OLE_XSIZE_HIMETRIC CXSRC, // The number of levels on the source image

OLE_YSIZE_HIMETRIC CYSRC, / / ​​The number of vertical copies on the source image

LPCRect prcwbounds // points to the pointer of the target chart device environment handle); Summary: To this, the above code has been able to display JPEG, GIF and other standard images in the client area of ​​the program, but for multi-frame pictures (ie There is an animated image of the GIF format, and the first frame can only be displayed. If you want to completely display the entire process of GIF animation, you need support for external Active X controls.

转载请注明原文地址:https://www.9cbs.com/read-2024.html

New Post(0)