Compares two images for additions, deletions, and changes and generates an image with the differences highlighted.
#include "l_bitmap.h"
L_LTIMGCOR_API L_INT L_CompareBitmap(pReferenceBitmap, pModifiedBitmap, pOutputBitmap, pAlignment, pOptions)
Pointer to the reference
(original) bitmap
.
Pointer to the modified bitmap
.
Pointer to a bitmap to be populated with the comparison results. See the comments below for more information.
Optional pointer to a transformation matrix used to overlay the modified bitmap onto the reference bitmap. If NULL
is passed, no transformation will be performed and the images will be aligned to the top-left.
Pointer to the comparison options.
Value | Meaning |
---|---|
SUCCESS | The function was successful. |
< 1 | An error occurred. Refer to Return Codes. |
The output image (pOutputBitmap
) will be 3 bits-per-pixel. The first six entries of its palette are populated from the COMPAREOPTIONS structure (pOptions
):
Index | Value |
---|---|
0 | pOptions->crOutputExternal |
1 | pOptions->crOutputBackground |
2 | pOptions->crOutputMatch |
3 | pOptions->crOutputAddition |
4 | pOptions->crOutputDeletion |
5 | pOptions->crOutputChange |
Win32, x64, Linux.
This example shows how to compare an image to its modified and rotated version.
L_INT CompareBitmapExample(L_VOID)
{
L_INT nRet = SUCCESS;
BITMAPHANDLE ReferenceBitmap = { 0 }; // The original image
BITMAPHANDLE ModifiedBitmap = { 0 }; // The modified image
BITMAPHANDLE OutputBitmap = { 0 }; // The generated image
COMPAREOPTIONS Options = { 0 }; // The comparison options
L_MATRIX Alignment = { 0 }; // The alignment transformation for the modified image
L_RECT RemoveRect = { 0 }; // The region to remove from an image
// Load the original image
nRet = L_LoadBitmap(MAKE_IMAGE_PATH(TEXT("ocr1.tif")), &ReferenceBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, NULL, NULL);
if (nRet != SUCCESS)
goto cleanup;
// Use the same image for the "modified" image
nRet = L_CopyBitmap(&ModifiedBitmap, &ReferenceBitmap, sizeof(BITMAPHANDLE));
if (nRet != SUCCESS)
goto cleanup;
// Remove the last paragraph of the reference image
L_Rect_Make(&RemoveRect, 290, 2470, 1930, 360);
nRet = L_SetBitmapRgnRect(&ReferenceBitmap, NULL, &RemoveRect, L_RGN_SET);
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FillBitmap(&ReferenceBitmap, RGB(255, 255, 255));
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FreeBitmapRgn(&ReferenceBitmap);
if (nRet != SUCCESS)
goto cleanup;
// Remove the title from the modified image
L_Rect_Make(&RemoveRect, 290, 300, 810, 110);
nRet = L_SetBitmapRgnRect(&ModifiedBitmap, NULL, &RemoveRect, L_RGN_SET);
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FillBitmap(&ModifiedBitmap, RGB(255, 255, 255));
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FreeBitmapRgn(&ModifiedBitmap);
if (nRet != SUCCESS)
goto cleanup;
// Rotate the modified image for demonstration (angle measured in hundredths of a degree)
nRet = L_RotateBitmap(&ModifiedBitmap, 340 * 100, ROTATE_RESIZE, RGB(0, 0, 0));
if (nRet != SUCCESS)
goto cleanup;
// Update the transformation to align/reverse the above rotation
L_Matrix_Identity(&Alignment);
L_Matrix_Translate(&Alignment, -ModifiedBitmap.Width * 0.5, -ModifiedBitmap.Height * 0.5);
L_Matrix_Rotate(&Alignment, 20.0);
L_Matrix_Translate(&Alignment, ReferenceBitmap.Width * 0.5, ReferenceBitmap.Height * 0.5);
// Setup the comparison options
Options.uStructSize = sizeof(COMPAREOPTIONS);
Options.uThreshold = 0; // The images are bitonal, no need for measuring color distance
Options.crReferenceBackground = RGB(255, 255, 255); // White
Options.crReferenceForeground = RGB(0, 0, 0); // Black
Options.crModifiedBackground = RGB(255, 255, 255); // White
Options.crModifiedForeground = RGB(0, 0, 0); // Black
Options.crOutputExternal = RGB(128, 128, 255); // Light blue
Options.crOutputBackground = RGB(255, 255, 255); // White
Options.crOutputMatch = RGB(64, 64, 64); // Dark gray
Options.crOutputAddition = RGB(0, 255, 0); // Green
Options.crOutputDeletion = RGB(255, 0, 0); // Red
Options.crOutputChange = RGB(255, 255, 0); // Yellow
// Compare the images
nRet = L_CompareBitmap(&ReferenceBitmap, &ModifiedBitmap, &OutputBitmap, &Alignment, &Options);
if (nRet != SUCCESS)
goto cleanup;
// Save the results
nRet = L_SaveBitmap(MAKE_IMAGE_PATH(TEXT("CompareBitmap_Output.png")), &OutputBitmap, FILE_PNG, 0, 0, NULL);
if (nRet != SUCCESS)
goto cleanup;
// Save the two input images, for reference
nRet = L_SaveBitmap(MAKE_IMAGE_PATH(TEXT("CompareBitmap_Reference.png")), &ReferenceBitmap, FILE_PNG, 0, 0, NULL);
if (nRet != SUCCESS)
goto cleanup;
nRet = L_SaveBitmap(MAKE_IMAGE_PATH(TEXT("CompareBitmap_Modified.png")), &ModifiedBitmap, FILE_PNG, 0, 0, NULL);
if (nRet != SUCCESS)
goto cleanup;
cleanup:
// Free the loaded images
if (ReferenceBitmap.Flags.Allocated)
L_FreeBitmap(&ReferenceBitmap);
if (ModifiedBitmap.Flags.Allocated)
L_FreeBitmap(&ModifiedBitmap);
if (OutputBitmap.Flags.Allocated)
L_FreeBitmap(&OutputBitmap);
return nRet;
}
The following images are generated when the example is run:
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document