This tutorial shows how to use overlays to draw an image over a main image in a Windows C DLL application using the LEADTOOLS SDK.
Overview | |
---|---|
Summary | This tutorial covers how to use image overlays in a Windows C DLL application. |
Completion Time | 20 minutes |
Visual Studio Project | Download tutorial project (33 KB) |
Platform | Windows C DLL Application |
IDE | Visual Studio 2017, 2019, 2022 |
Development License | Download LEADTOOLS |
Get familiar with the basic steps of creating a project and loading/displaying an image by reviewing the Add References and Set a License and Load, Display, and Save Images tutorials, before working on the Add and Display Image Overlays - Windows C DLL tutorial.
Start with a copy of the project created in the Load, Display, and Save Images tutorial. If you do not have that project, create it by following the steps in that tutorial.
To load images as overlays using LEADTOOLS, you do not need any additional libraries than what is used in the Load, Display, and Save Images tutorial, shown below:
// add headers that you want to pre-compile here
#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.
The License unlocks the features needed for the project. It must be set before any toolkit functionality 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 code from the Load, Display, and Save Images tutorial added, coding can begin.
The steps below are for Visual Studio 2019; they could be different for other versions of Visual Studio.
In the Solution Explorer, double-click the resources file (.rc).
Add a new &Overlays drop-down menu next to the File menu and before the Help menu. In the newly added &Overlays menu, add a Load image as Overlay &1 menu item. The new item's ID should be ID_OVERLAYS_LOADIMAGEASOVERLAY1
.
Go to the WndProc
function, and under the switch (wmId)
statement that is below the WM_COMMAND
case, add a new case for ID_OVERLAYS_LOADIMAGEASOVERLAY1
. First, before we can load the overlay, we must check to see if the main image is loaded as we cannot use the overlays without it. Check the LEADBmp
's Flags.Allocated
property to see if it has been loaded yet.
Add the code below to the ID_OVERLAYS_LOADIMAGEASOVERLAY1
case to load the overlay image and add it to the main image.
Create a TCHAR
string to hold the filename being loaded. Copy the GetBitmapLoadingName()
method from the ID_FILE_OPEN
case and pass the string and the size of string to it. This will allow the user to select a file to use as an overlay. Create a BITMAPHANDLE
named OverlayBmp
for the image and loading it with L_LoadBitmap()
.
case ID_OVERLAYS_LOADIMAGEASOVERLAY1:
{
if (LEADBmp.Flags.Allocated == false) {
MessageBox(hWnd, TEXT("You must first load the main image"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
break;
}
TCHAR szFileName[260] = TEXT(""); // file name
if (SUCCESS != GetBitmapLoadingName(hWnd, szFileName, ARRAYSIZE(szFileName)))
break;
BITMAPHANDLE OverlayBmp;
int nret = L_LoadBitmap(szFileName, &OverlayBmp, sizeof(OverlayBmp), 0, ORDER_BGR, NULL, NULL);
if (OverlayBmp.BitsPerPixel != 1) {
MessageBox(hWnd, TEXT("The overlay image must be 1bpp"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
L_FreeBitmap(&OverlayBmp);
break;
}
if (OverlayBmp.Height != LEADBmp.Height || OverlayBmp.Width != LEADBmp.Width) {
MessageBox(hWnd, TEXT("Overlay image must be the same size as the main bitmap"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
L_FreeBitmap(&OverlayBmp);
break;
}
// If the bitmap is the same size as LEADBmp, then it is safe to replace the current OverlayBmp
nret = L_SetOverlayBitmap(&LEADBmp, 0, &OverlayBmp, OVERLAY_MOVE);
// Get the pre-existing Overlay attributes
OVERLAYATTRIBUTES attributes = { 0 };
nret = L_GetOverlayAttributes(&LEADBmp, 0, &attributes, sizeof(OVERLAYATTRIBUTES), 0xFF);
// Change the overlay color to blue
attributes.crColor = 0x00FF0000;
// Set the overlay to update on L_PaintDC and when the main image is manipulated such as scrolling or zoom
attributes.uFlags = OVERLAY_AUTOPAINT | OVERLAY_AUTOPROCESS;
// Set the color and flags attributes back
nret = L_SetOverlayAttributes(&LEADBmp, 0, &attributes, 0x06);
// Update the display immediately
InvalidateRect(hWnd, NULL, TRUE);
// This is necessary since OVERLAY_MOVE creates a copy of OverlayBmp that it disposes of separately
if (OverlayBmp.Flags.Allocated)
L_FreeBitmap(&OverlayBmp);
}
break;
Navigate back to the resources file (.rc). Add another menu item under &Overlays named Load image as Overlay &2. The new item's ID should be ID_OVERLAYS_LOADIMAGEASOVERLAY2
. This will allow us to load a second overlay which we can assign different attributes to.
Go back to the WndProc
function, under the switch (wmId)
statement, add a case for ID_OVERLAYS_LOADIMAGEASOVERLAY2
. Add the code below to the ID_OVERLAYS_LOADIMAGEASOVERLAY2
case to add the second overlay, but this time will assign the color green in the attributes.
case ID_OVERLAYS_LOADIMAGEASOVERLAY2:
{
if (LEADBmp.Flags.Allocated == false) {
MessageBox(hWnd, TEXT("You must first load the main image"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
break;
}
TCHAR szFileName[260] = TEXT(""); // file name
if (SUCCESS != GetBitmapLoadingName(hWnd, szFileName, ARRAYSIZE(szFileName)))
break;
BITMAPHANDLE OverlayBmp;
int nret = L_LoadBitmap(szFileName, &OverlayBmp, sizeof(OverlayBmp), 0, ORDER_BGR, NULL, NULL);
if (OverlayBmp.BitsPerPixel != 1) {
MessageBox(hWnd, TEXT("The overlay image must be 1bpp"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
L_FreeBitmap(&OverlayBmp);
break;
}
if (OverlayBmp.Height != LEADBmp.Height || OverlayBmp.Width != LEADBmp.Width) {
MessageBox(hWnd, TEXT("Overlay image must be the same size as the main bitmap"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
L_FreeBitmap(&OverlayBmp);
break;
}
// If the bitmap is the same size as LEADBmp, then its safe to replace the current OverlayBmp
nret = L_SetOverlayBitmap(&LEADBmp, 1, &OverlayBmp, OVERLAY_MOVE);
// Get the pre-existing Overlay attributes
OVERLAYATTRIBUTES attributes = { 0 };
nret = L_GetOverlayAttributes(&LEADBmp, 1, &attributes, sizeof(OVERLAYATTRIBUTES), 0xFF);
// Change the overlay color to green
attributes.crColor = 0x0000FF00;
// Set the overlay to update on L_PaintDC and when the main image is manipulated such as scrolling or zoom
attributes.uFlags = OVERLAY_AUTOPAINT | OVERLAY_AUTOPROCESS;
// Set the color and flags attributes back
nret = L_SetOverlayAttributes(&LEADBmp, 1, &attributes, 0x06);
// Update the display immediately
InvalidateRect(hWnd, NULL, TRUE);
// This is necessary since OVERLAY_MOVE creates a copy of OverlayBmp that it disposes of separately
if (OverlayBmp.Flags.Allocated)
L_FreeBitmap(&OverlayBmp);
}
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps were followed correctly, the application should run. Follow the below steps to test:
Lastly, click Overlays > Load image as overlay 2, and select another 1BPP image that is the same size as the main image. This image will display green for every pixel with a palette index of 1. These overlays are treated separately by the same bitmap handle internally.
For testing purposes, you can use the sample files here.
This tutorial covered how to set image overlays on a bitmap viewer without altering the image data.