L_CompareBitmap (original) (raw)

Summary

Compares two images for additions, deletions, and changes and generates an image with the differences highlighted.

Syntax

#include "l_bitmap.h"

L_LTIMGCOR_API L_INT L_CompareBitmap(pReferenceBitmap, pModifiedBitmap, pOutputBitmap, pAlignment, pOptions)

Parameters

pBITMAPHANDLE pReferenceBitmap

Pointer to the reference (original) bitmap.

pBITMAPHANDLE pModifiedBitmap

Pointer to the modified bitmap.

pBITMAPHANDLE pOutputBitmap

Pointer to a bitmap to be populated with the comparison results. See the comments below for more information.

L_MATRIX *pAlignment

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.

pCOMPAREOPTIONS pOptions

Pointer to the comparison options.

Returns

Value Meaning
SUCCESS The function was successful.
< 1 An error occurred. Refer to Return Codes.

Comments

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

Required DLLs and Libraries

Platforms

Win32, x64, Linux.

Example

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

Reference, Modified, and Output Images

The following images are generated when the example is run: