Red de conocimiento informático - Material del sitio web - ¿Cómo leer un archivo de mapa de bits externo y mostrarlo en un control de imagen MFC?

¿Cómo leer un archivo de mapa de bits externo y mostrarlo en un control de imagen MFC?

Déjame decirte el método más sencillo. Debes conocerlo. Recuerda darme puntos cuando lo hayas hecho.

1. Agregue un botón y un control de imagen al cuadro de diálogo.

2. Agrega una clase, no puedo cargarla aquí, solo puedo copiar .h y .cpp, luego puedes copiarla en txt y cambiar la extensión.

Esta es Imagen.h

#if! definido(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 > p >#pragma once

# endif // _MSC_VER > 1000

clase CPicture

{

público:

void FreePictureData();

BOOL Load(CString) sFilePathName );

BOOL Load(UINT ResourceName, LPCSTR ResourceType);

BOOL LoadPictureData(BYTE* pBuffer, int nSize

BOOL SaveAsBitmap( CString sFilePathName);

BOOL Show(CDC* pDC, CPoint LeftTop, CPoint WidthHeight, int MagnifyX, int MagnifyY

BOOL Show(CDC* pDC, CRect DrawRect

BOOL ShowBitmapResource(CDC* pDC, const int BMPResource, CPoint LeftTop);

BOOL UpdateSizeOnDC(CDC* pDC);

CPicture();

virtual ~CPicture();

IPicture* m_IPicture; // Igual que LPPICTURE (typedef IPicture __RPC_FAR *LPPICTURE)

LONG m_IPicture; // Alto (Entrada); Altura (Entrada); // Altura (Entrada); // Altura (Entrada). Altura; // Altura (en píxeles, ignora el contexto actual del dispositivo)

LONG m_Weight; Objeto en bytes (archivo o recurso)

LONG m_Width; // Ancho (en píxeles, ignora lo que utiliza el contexto actual del dispositivo)

};

#endif

Esto es Picture.cpp

#include "stdafx.h"

#include "Picture.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef ESTE_FILE

carácter estático ESTE_FILE[] =

__FILE__;

#endif

#define HIMETRIC_INCH 2540

#define ERROR_TITLE "CPicture Error" // Título del error (relacionado con esta clase)...

//------------------------------------------ --- ----------------------------------

/ Hace: Constructor - Crear un nuevo objeto CPicture para contener datos de imagen

// ~~~~

//

/------------ ------------------------------------------------- - ------------ -

CPicture::CPicture()

//=============== = =================================================== = ============

{

m _IPicture = NULL;

m_Height = 0;

m_Peso = 0;

m_Ancho = 0;

}

//----------------- - ---------------------------- --------------------- ------- ---------

// Hace: Destructor: libera datos e información del objeto CPicture

//~~~~

//

//-------------------------------- ------------- ------------------------------------- ---

Imagen CP:: ~Imagen CP()

//=============== ========= ============= ====================================== ===

{

if(m_IPicture != NULL) FreePictureData() // Importante: evitar fugas...

}

//-------- ------------------------------------- ------------- ------------------

// Función: Liberar la memoria asignada que contiene datos de la interfaz IPicture

// ~~ ~~ y borre la información de la imagen

//

// Nota: Si solo necesita mostrar la imagen una vez,

// ~~~~~ o si copia la imagen al contexto del dispositivo para que aún

// permanezca en la pantalla, pero ya no necesite los datos de IPicture

// permanece en la pantalla, pero ya no requiere datos de IPicture

//

/---------------- ---------------- ---------------------------------- -------------

void CPicture::.FreePictureData()

//============

==================================================== ================

{

if(m_ IPicture ! = NULL)

{

m_IPicture->Release();

m_IPicture = NULL;

m_Height = 0;

m_Weight = 0;

m_Width = 0;

}

}

//-------------------- -------------------------------------------------- -------

// Hace: abrir un recurso y cargarlo en IPicture (interfaz)

// ~~~~ (.BMP .DIB .EMF . GIF .ICO .JPG .WMF)

/ return(bResultado);

}

//------------ -------------------------------------------------- ---------------

// Hace: abrir el archivo y cargarlo en IPicture (interfaz)

// ~~~~ (.BMP .DIB .EMF)BMP .DIB .EMF .GIF .ICO .JPG .WMF)

//

/ Entrada: sFilePathName: ruta guardada y destino del nombre de archivo

// ~~~~~

//

/ Salida: VERDADERO Si tiene éxito...

//~~ ~~ ~~

//--------------------------------- --- ----------------------------------------

BOOL CPicture: :Load( CString sFilePathName)

//================================= ==== ===========================================

{

BOOL bResult = FALSE;

CFile PictureFile;

CFileException e;

int nSize = 0;

if(m_IPicture!

if(m_IPicture ! = NULL) FreePictureData(); // Importante: evitar fugas...

if(PictureFile.Open(sFilePathName, CFile::modeRead | CFile:: typeBinary, &e))

{

nSize = PictureFile.GetLength();

BYTE* pBuffer = new BYTE[nSize];

if (PictureFile.Read(pBuffer, nSize) > 0 )//Leer pBuffer del archivo

{ if(LoadPictu

reData(pBuffer, nSize)) bResult = TRUE }// Asumir la llamada a la función para leer pBuffer

PictureFile.Close();

eliminar [] pBuffer;

}

else // Error al abrir...

{

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; // Actualiza la información del tamaño de la imagen.

..

if(m_IPicture ! = NULL) // No intentes leer datos de una memoria que no existe...

{

m_IPicture- > get_Height(&m_Height);

m_IPicture->get_Width(&m_Width);

// Calcula su tamaño en el contexto del dispositivo "estándar" (96 DPI)

m_Height = MulDiv(m_Height, 96, HIMETRIC_INCH);

m_Width = MulDiv(m_Width, 96, HIMETRIC_INCH);

}

else // Datos de imagen No es un tipo de imagen conocido

{

m_Height = 0;

m_Width = 0;

bResult = FALSE;

}

> return(bResultado);

}

//--------------- ------------------------------------------------- - -----------

// Hace: Leer datos de imagen de una fuente (archivo/recurso)

// ~~~~ y es cargado en el objeto IPicture utilizado actualmente

//

// InPut: el búfer de la fuente de datos (archivo/recurso) y su tamaño

/ / ~~~~~

//

// Salida: proporciona datos de imagen al objeto IPicture

// ~~~~~~ (Usa dibujo La función se muestra en el contexto del dispositivo)

// TRUE si se realiza correctamente...

// ------------------ ------------------------------------------------- - --------

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, "No se puede asignar suficiente memoria\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, "La interfaz IPicture no es compatible\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);

return(FALSE);

}

else // S_OK

{

pStream->Release();

pStream = NULL;

bResult = TRUE;

}

}

FreeResource(hGlobal); // Requerido para Windows de 16 bits ( 32 bits - liberación automática)

return(bResult);

}

//------ ------- -------------------------------------------------- -- ------------

// Si: dibuja la imagen cargada directamente en el DC del cliente

// ~~~~

//

// Nota: El tamaño es mayor o menor que el tamaño de la imagen original

// ~~~~ La imagen se dibujará de acuerdo con la nueva tamaño dado.

..

//

// InPut: pDC - el DC dado que se dibujará

// ~~~~~ DrawRect - el tamaño de la imagen dibujada (como un rectángulo)

//

// Salida: TRUE Si tiene éxito...

// ~~~~~~

//------------------------------------------ ------ ----------------------------------

BOOL CImagen: :Mostrar(CDC * pDC, CRect DrawRect)

//================================ ======= ==========================================

{

if (pDC == NULL || m_IPicture == NULL) devuelve FALSO;

largo Ancho = 0;

largo Alto = 0;

m_IPicture->get_Width(&Width);

m_ IPicture->get_Height(&Height);

HRESULT hrP = NULL;

hrP = m_IPicture- >Render(pDC->m_hDC,

DrawRect.left, // Izquierda

DrawRect.top, // Arriba

DrawRect.right - DrawRect.left , // Derecha

DrawRect.bottom - DrawRect.top, // Abajo

0,

Altura,

Ancho,

-Alto,

&DrawRect);

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

HWND hWnd = AfxGetApp()-> GetMainWnd()->m_hWnd;

MessageBoxEx(hWnd, "No se puede asignar suficiente memoria\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);

retorno(FALSO );

}

//------------------------ ---------- ---------------------------------------- ----------

// Hace: dibujar la imagen cargada directamente en el DC del cliente

// ~~~~

//

// Nota: Un tamaño mayor o menor que el tamaño de la imagen original

// ~~ ~~ La imagen se dibujará en las nuevas dimensiones dadas. ..

//

/ InPut: pDC - el DC dado para dibujar

/ ~~~~~ LeftTop - el que comenzar a dibujar Punto de apertura (izquierda, arriba)

// AnchoAlto: el tamaño de la imagen sobre la que dibujar.

Dimensiones de la imagen a dibujar (ancho, alto)

// MagnifyX - Ampliar el ancho de píxel, 0 = predeterminado (sin ampliación)

// MagnifyY - Ampliar el alto de píxel, 0 = Valor predeterminado (sin amplificación)

//

// Salida: TRUE Si tiene éxito...

// ~~~~~~

//---------------------------------------------------- ---- ----------------------------------

BOOL CImagen::Mostrar (CDC *pDC, CPoint LeftTop, CPoint WidthHeight, int MagnifyX, int MagnifyY)

/========================== ======= =============================== ============ =====

{

if (pDC == NULL || m_IPicture == NULL) devuelve FALSO;

largo Ancho = 0;

altura larga = 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)* 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, // Izquierda

LeftTop.y, /

&DrawRect);

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

HWND hWnd = AfxGetApp ()->GetMainWnd()->m_hWnd;

MessageBoxEx(hWnd, "No se puede asignar suficiente memoria\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);

retorno( FALSO);

}

/ /----------------------- ------- ------------------------------------------- ----

// Hace: Guarda la imagen almacenada en el objeto IPicture como

Mapa de bits

// ~~~~ (convierte de cualquier tipo de imagen conocida a un archivo de mapa de bits/icono)

//

// InPut: sFilePathName - Ruta Y nombre de archivo destino a guardar

// ~~~~~

//

/ Salida: VERDADERO Si tiene éxito...

// ~~~~~~

//-------------------------------- ----------------------------------------

BOOL CImagen: .SaveAsBitmap(CString sFilePathName)

//============================== ====== =============================================

{

BOOL bResult = FALSE;

ILockBytes *Buffer = 0;

IStorage *pStorage = 0;

IStream *FileStream = 0;

BYTE *BufferBytes;<

STATSTG BytesStatistics;

DWORD OutData;

OutStream largo ;

CFile BitmapFile; CFileException e;

doble SkipFloat = 0;

DWORD ByteSkip = 0;

_ULARGE_INTEGER RealData;

p>

CreateILockBytesOnHGlobal(NULL, TRUE, &Buffer); // Crear búfer ILockBytes

HRESULT hr = ::StgCreateDocfileOnILockBytes(Buffer,

STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, & amp;pStorage );

hr = pStorage->CreateStream(L "PICTURE",

STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, 0, & FileStream);

m_IPicture->SaveAsFile(FileStream, TRUE y OutStream); // Copiar flujo de datos

FileStream->Release();

pStorage->Release();

Buffer->Flush();

// Obtener estadísticas para el tamaño final de la matriz de bytes

Buffer->Stat(& BytesStatistics, STATFLAG_NONAME);

/ / Elimina los datos innecesarios de SaveAsFile() (dejando solo datos de imagen "puros")

SkipFloa

t = ( double(OutStream) / 512); // Deben ser 512 bloques. ..

if(SkipFloat > DWORD(SkipFloat)) ByteSkip = (DWORD)SkipFloat + 1;

else ByteSkip = (DWORD)SkipFloat;

ByteSkip = ByteSkip * 512; // Debe estar en 512 bloques...512; // Debe estar en 512 bloques...

// Encuentra la diferencia entre dos valores

p>

ByteSkip = (DWORD)(BytesStatistics.cbSize.QuadPart - ByteSkip);

// Solo asigna datos de imagen "puros"

RealData.LowPart = 0;

RealData.HighPart = 0;

RealData.QuadPart = ByteSkip* 512 // Debe estar dentro de 512 bloques.

QuadPart = ByteSkip;

BufferBytes = ( BYTE*)malloc(OutStream);

if(BufferBytes == NULL)

{

Buffer->Release();

HWND hWnd = AfxGetApp()->GetMainWnd ()->m_hWnd;

MessageBoxEx(hWnd, "No se puede asignar suficiente memoria\t" , ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH);

}

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

if(BitmapFile. modeCreate | CFile::modeWrite, &e))

{

BitmapFile.Write(BufferBytes, OutData);

BitmapFile.Close();

bResult = TRUE;

}

else // Error al escribir el archivo...

{

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();

gratis(BufferBytes);

return(bResult);

}

//--------- ----------------------------------------- --- - ------------------

// Función: Dibujar recursos de mapa de bits al DC del cliente (usando Bitblt())

// ~~~~ Utilizará el tamaño original (ancho y alto) del recurso de mapa de bits

// (.BMP .DIB)

// ~~~~ Se utilizará el tamaño original (ancho y alto) del recurso de mapa de bits

//(.BMP .DIB)

//

// NOTA: Esta función es solo otra forma sencilla de mostrar recursos de mapa de bits.

// ~~~~ No tiene nada que ver con la interfaz IPicture y se puede usar sola (directamente) en cualquier contexto de dispositivo.

/ /

// InPut: BMPResource - el nombre del recurso definido en el recurso

// ~~~~~ pDC - especifica el DC en el que recurrir

// LeftTop - punto de partida para comenzar a dibujar (izquierda, arriba)

//

// Salida: TRUE si tiene éxito...

// ~~~~~~

//--------------------------------- - ----

-------------------------------

BOOL CPicture:.ShowBitmapResource ( CDC *pDC, const int BMPResource, CPoint LeftTop)

//=============================== = =============================== ==================< / p>

{

if (pDC == NULL) return(FALSE);

CBitmap BMP;

if(BMP.LoadBitmap(BMPResource ) )

{

// Obtener detalles del mapa de bits

BITMAP BMPInfo;

BMP.GetBitmap(&BMPInfo);

// Crea un DC de memoria compatible con el DC de visualización que queremos dibujar

CDC DCMemory;

DCMemory. POldBitmap = DCMemory.SelectObject(&BMP);

//Copia bits del DC en la memoria al DC en la pantalla

pDC->BitBlt(LeftTop.x,LeftTop.y, BMPInfo. bmWidth, BMPInfo.bmHeight, &DCMemory, 0, 0, SRCCOPY);

DCMemory.SelectObject(pOldBitmap); // (Como se muestra en el ejemplo de MSDN...)

}

else

{

TRACE0("ERROR: No se puede encontrar el recurso de mapa de bits\n");

return( FALSE) ;

}

return(VERDADERO);

}

//------ -- ------------------------------------------------ -- -------------------

// Sí: obtiene el tamaño en píxeles de la imagen original (ignorando la corriente utilizada por DC)

// ~~~~ El puntero que apunta al contexto del dispositivo es necesario para calcular los píxeles,

//

// También actualiza las propiedades de alto y ancho de la clase. ,

// (Dado que hasta ahora no tenemos un contexto de dispositivo con el que trabajar. Se supone .96DPI).

.96 DPI asumidos)

//

// Entrada: Cliente DC (necesita verificar el tamaño de píxel)

// ~~~~~

//

//////////////////////////////// Salida: VERDADERO si exitoso ..

// ~~~~~~

//--------------------- -. -------------------------------------------------- --

BOOL CPicture:.UpdateSizeOnDC(CDC *pDC)

//======================= ==================================================== ======

{

if(pDC == NULL || m_IPicture == NULL) { m_Height = 0; m_Width = 0;

m_IPicture->get_Height(&m_Height);

m_IPicture-&>get_Width(&m_Height);

m_IPicture-& gt;get_Width(&m_Width); p>

// Obtener DPI actuales - Puntos por pulgada

int CurrentDPI_X = pDC->GetDeviceCaps(LOGPIXELSX);

int CurrentDPI_Y = pDC->GetDeviceCaps( LOGPIXELSY) ;

// Utilice la impresión "estándar" (al imprimir)

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);

}

Defina en el archivo de encabezado del diálogo:

Primero, incluya el archivo de encabezado #include "Picture.h"

Luego defina

CPicture m_Pic;

4. Escriba en la función del botón : (Tenga en cuenta que este IDC_SHOWPIC) es el número de identificación de su control de pantalla.

CRect rect;

GetDlgItem(IDC_SHOWPIC)->GetWindowRect(&rect);

ScreenToClient(&rect);

CFile f;

CString FilePathName;

CFileException e;

CFileDialog dlg(TRUE,NULL,NULL,0,_T("Todos los archivos (*. *)|* .*)|*.*|BMP(*.bmp)|*.bmp|DIB(*.dib)|*.dib|EMF(*.emf)|*.emf|GIF(*.gif)|*. gif|ICO(*.ico)|*.ico|JPG(*.JPG (*.jpg)|*.jpg|WMF (*.wmf)|*.wmf||"),NULL);

if(dlg.DoModal()==IDOK)

{

FilePathName=dlg.GetPathName()