This tutorial shows how to create a C/C++ Windows API application that loads an image from a buffer.
Overview | |
---|---|
Summary | This tutorial covers how to load an image from a buffer in a Windows C DLL Application. |
Completion Time | 30 minutes |
Visual Studio Project | Download tutorial project (18 KB) |
Platform | Windows C DLL Application |
IDE | Visual Studio 2017, 2019 |
Development License | Download LEADTOOLS |
Try it in another language |
|
Before working on the Load Image from a Buffer - Windows C DLL tutorial, get familiar with the basic steps of creating a project and loading images by reviewing the Add References and Set a License and Load, Display, and Save Images tutorials.
Start with a copy of the 64-bit Windows API project created in the Load, Display, and Save Images tutorial. If the project is not available, create it by following the steps in that tutorial.
The LEADTOOLS Library files required for the Load Image from a Buffer tutorial are similar to those already present in the Load, Display, and Save Images tutorial. Verify that the pre-compiled header file (either pch.h
or stdafx.h
) contains the following lines:
#define LTV23_CONFIG
#include "C:\LEADTOOLS23\Include\L_Bitmap.h" // use actual path where you installed LEADTOOLS
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltkrn_x.lib")
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltfil_x.lib") // file loading and saving
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltdis_x.lib") // image display
Note: For a complete list of which DLL files are required for your application, refer to Files to be Included with your Application.
This tutorial uses the Microsoft CryptoAPI to decode a Base64 buffer that contain an image, so add the following line to the pre-compiled header file:
#pragma comment (lib, "Crypt32.lib") // link the CryptoAPI DLL
The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.
There are two types of runtime licenses:
Note: Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License tutorial.
With the project created, the references added, the license set, and the load image code added, coding can begin.
The steps below are for Visual Studio 2019; they could be different for other versions of Visual Studio.
Go to the Solution Explorer and double-click the resources file (.rc).
Add two new menu items to the File menu below the Open menu item as follows.
Item text | Item ID |
---|---|
&Load from buffer | ID_FILE_LOADFROMBUFFER |
Load &Base64 encoded | ID_FILE_LOADBASE64ENCODED |
Go to the WndProc
function, and under the switch (wmId)
statement that is below the WM_COMMAND
case, add two new cases:
switch (wmId)
{
case ID_FILE_LOADFROMBUFFER: // Load image from memory buffer
LoadFromBuffer(hWnd, L_FALSE);
break;
case ID_FILE_LOADBASE64ENCODED: // Decode memory buffer then load image
LoadFromBuffer(hWnd, L_TRUE);
break;
// keep rest of the code as is
Below is the code for the LoadFromBuffer()
function.
If the boolean parameter bEncodedBase64 is TRUE, the function treats the buffer as Base64-encoded and decodes it before loading the image.
L_INT LoadFromBuffer(HWND hWnd, L_BOOL bEncodedBase64)
{
TCHAR szFileName[260] = TEXT(""); // file name
if (SUCCESS != GetBitmapLoadingName(hWnd, szFileName, ARRAYSIZE szFileName))
return ERROR_NORMAL_ABORT;
FILE* fp = NULL;
_tfopen_s(&fp, szFileName, TEXT("rb"));
if (!fp)
return ERROR_FILENOTFOUND;
fseek(fp, 0L, SEEK_END);
long nFileSize = ftell(fp);
fseek(fp, 0L, SEEK_SET);
L_UCHAR* pBufferFile = new L_UCHAR[nFileSize];
if (nFileSize != fread_s(pBufferFile, nFileSize, 1, nFileSize, fp))
{
if (fp)
fclose(fp);
if (pBufferFile)
delete[] pBufferFile;
return ERROR_FILE_READ;
}
L_UCHAR* pBufferImage = NULL;
L_UCHAR* pBufferDecoded = NULL;
if (bEncodedBase64) // must decode file to obtain image
{
DWORD dwDecodedSize = 0;
CryptStringToBinaryA((LPCSTR)pBufferFile, nFileSize, CRYPT_STRING_BASE64_ANY, NULL, &dwDecodedSize, NULL, NULL);
pBufferDecoded = new L_UCHAR[dwDecodedSize];
CryptStringToBinaryA((LPCSTR)pBufferFile, nFileSize, CRYPT_STRING_BASE64_ANY, pBufferDecoded, &dwDecodedSize, NULL, NULL);
pBufferImage = pBufferDecoded;
}
else //no decoding needed
pBufferImage = pBufferFile;
MessageBox(hWnd, TEXT("File loaded into memory buffer. Attempting to load image from buffer.."), TEXT("LEADTOOLS Demo"), MB_ICONINFORMATION);
if (LEADBmp.Flags.Allocated)
L_FreeBitmap(&LEADBmp);
L_INT nRet = L_LoadBitmapMemory(pBufferImage, &LEADBmp, sizeof LEADBmp, 24, ORDER_BGR, nFileSize, NULL, NULL);
InvalidateRect(hWnd, NULL, TRUE);
if (fp)
fclose(fp);
if (pBufferFile)
delete[] pBufferFile;
if (pBufferDecoded)
delete[] pBufferDecoded;
return nRet;
}
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps are followed correctly, the application should run and enable the user to select a file for loading into a memory buffer. If the image in the file is coded with Base64 encoding, an option is provided to decode the data to obtain the image from it. To test this option, this Base64-encoded image file can be used.
This tutorial covered how to use the L_LoadBitmapMemory
function to load images from memory buffers, either directly or after decoding them when needed.