ImageEn, unit iexBitmaps

TIEBitmap.JoinBitmaps

TIEBitmap.JoinBitmaps


Declaration

function JoinBitmaps(Source1, Source2: TIEBitmap; JoinVertically: Boolean; BGColor: TColor = clWhite; StripOverlap: Boolean = False; MinEquality: Double = 0.99;  Exhaustive: Boolean = False; Coverage: Double = 1.0): Integer;


Description

      Replaces the content with two source images drawn side-by-side (or above and below if JoinVertically=True).
Both bitmaps must be ie24RGB.
If StripOverlap = True, then the result is the number of rows/colums that were cropped (if the result is 0 then no overlap could be found).
   
Parameter Description
Source1, Source2 Specifies the two source images (either can be nil to specify this bitmap)
JoinVertically If False, Source1 is drawn on the left and Source 2 on the right. If True, Source1 is drawn on the top and Source 2 on the bottom
BGColor If one image is taller/wider than the other there will be background showing. Specify the color of the background fill, or clNone to fill with alpha
StripOverlap If enabled, a check is performed to see if there is any overlapping pixels on the joining edge of the two images (Using CompareWith), and it is removed
MinEquality If StripOverlap = True, this specifies the level of equality to look for when comparing the overlapping region (from 0.0 to 1.0, where 1.0 looks for an exact match). If you have difficulty finding an accurate value, enable the Exhaustive parameter, and specify a low value for MinEquality
Exhaustive If StripOverlap = True, Exhaustive determines whether it checks every possibilities and returns the best one (Exhaustive=True) or just returns the first match that exceeds the specified MinEquality (Exhaustive=False). Exhaustive gives a much more accurate result, but will be much slower
Coverage If StripOverlap = True, this specifies how extensively we check for overlap matching. This is used to speed up processing of very large images. For example, 1.0 means we check every row, 0.1 means we only check every tenth row, etc.

Note:
You may specify the current bitmap for Source1 or Source2
if StripOverlap = True it looks for overlap at a maximum of 50% of the width/height of the smallest image
If attached to a TImageEnView, it will automatically call Update
Also see TIEVisionStitcher which allows joining of multiple images with overlapped content


TIEBitmap Assignment and Drawing Methods

TIEBitmap Methods
Method Mode Purpose
Assign From TIEBitmap/TBitmap/TGraphic/TIcon Copy whole image
AssignImage From TIEBitmap Like assign, but does not copy the alpha channel
AssignRect From TIEBitmap/TBitmap Copy a specified rect
CopyAndConvertFormat From TIEBitmap Copy whole image
CopyRectTo To TIEBitmap Copy rect to another image (without scaling)
CopyWithMask1 To TIEBitmap Copy image using a mask to specify what is copied from the source
CopyWithMask2 To TIEBitmap Copy image using a mask to specify what is replaced in the destintation
DrawToTIEBitmap To TIEBitmap Copies all or part of the image to a specified position and/or size
JoinBitmaps From two TIEBitmaps Draws two bitmaps to a single bitmap
MergeAlphaRectTo With TIEBitmap Merges the alpha channels of two TIEBitmaps using merge rules
MergeWithAlpha With TIEBitmap Merges all or part of two TIEBitmaps with alpha channels to a specified position
RenderToTIEBitmapEx To TIEBitmap Extended drawing of content to a TIEBitmap
StretchRectTo To TIEBitmap Copy rect to dest rect in another image (with scaling)
SwitchTo To TIEBitmap Move content from one TIEBitmap to another

TBitmap Methods
Method Mode Purpose
Assign From TIEBitmap/TBitmap/TGraphic/TIcon Copy whole image
AssignTo To TIEBitmap/TBitmap Copy whole image with optional scaling
AssignRect From TIEBitmap/TBitmap Copy a specified rect
CopyFromTBitmap From TBitmap Copy whole image
CopyToTBitmap To TBitmap Copy whole image
RenderToTBitmapEx To TBitmap Extended drawing of content to a TBitmap

TCanvas Methods
Method Mode Purpose
DrawToCanvas To TCanvas Copies whole image to canvas at specified position (ignoring the alpha channel)
DrawToCanvasWithAlpha To TCanvas Copies whole image to canvas at specified position (honoring the alpha channel)
RenderToCanvas To TCanvas Extended drawing of content to a TCanvas (ignoring the alpha channel)
RenderToCanvasWithAlpha To TCanvas Extended drawing of content to a TCanvas (honoring the alpha channel)


Comparison

// Joining two bitmaps that are 300px wide with some overlapping content

   


// METHOD 1 - JOIN ONLY

// Join two images horizontally and display them (without checking for overlapping content)
bmpL := TIEBitmap.Create();
bmpR := TIEBitmap.Create();
bmpL.LoadFromFile( 'D:\JoinBitmap_Left.png' );
bmpR.LoadFromFile( 'D:\JoinBitmap_Right.png' );
ImageEnView1.IEBitmap.JoinBitmaps( bmpL, bmpR, False, clNone );
bmpL.Free;
bmpR.Free;

// Result is 600px wide - Overlap remains




// METHOD 2 - NON-EXHAUSTIVE CHECKING FOR OVERLAP

// Join two images horizontally and display them (performing a non-exhaustive search for overlapping content)
bmpL := TIEBitmap.Create();
bmpR := TIEBitmap.Create();
bmpL.LoadFromFile( 'D:\JoinBitmap_Left.png' );
bmpR.LoadFromFile( 'D:\JoinBitmap_Right.png' );
ImageEnView1.IEBitmap.JoinBitmaps( bmpL, bmpR, False, clNone, True, 0.99 );
bmpL.Free;
bmpR.Free;

// Result is 477px wide - Small amount of overlap remains




// METHOD 3 - EXHAUSTIVE CHECKING FOR OVERLAP

// Join two images horizontally and display them (performing an exhaustive search for overlapping content)
bmpL := TIEBitmap.Create();
bmpR := TIEBitmap.Create();
bmpL.LoadFromFile( 'D:\JoinBitmap_Left.png' );
bmpR.LoadFromFile( 'D:\JoinBitmap_Right.png' );
ImageEnView1.IEBitmap.JoinBitmaps( bmpL, bmpR, False, clNone, True, 0.8, True );
bmpL.Free;
bmpR.Free;

// Result is 473px wide - Overlap is correctly removed




Examples

// Draw an image on the right of the current image (blank space will be transparent)
bmp := TIEBitmap.Create();
bmp.LoadFromFile( 'D:\image2.png' );
ImageEnView1.IEBitmap.JoinBitmaps( nil, bmp, False, clNone );
bmp.Free;


// Create a PDF document with two stacked landscape images
bmp1 := TIEBitmap.Create();
bmp2 := TIEBitmap.Create();
destBmp := TIEBitmap.Create();

bmp1.LoadFromFile( 'D:\im1.jpg' );
bmp2.LoadFromFile( 'D:\im2.jpg' );

destBmp.JoinBitmaps( bmp1, bmp2, True, clWhite );

destBmp.RemoveAlphaChannel( True ); // Discard any alpha channel if not needed to reduce file size
destBmp.ParamsEnabled := True;
destBmp.Params.PDF_PaperSize   := iepA4;
destBmp.Params.PDF_Compression := ioPDF_JPEG;
destBmp.Params.JPEG_Quality    := 90;
destBmp.SaveToFile('D:\out.pdf');

bmp1.Free();
bmp2.Free();
destBmp.Free();


// Duplicate the current bitmap vertically
bmp.JoinBitmaps( bmp, bmp, True  );


// Join two images removing any part of the image that is the same at the joining edge
// Exact matches only. Don't use exact matches for lossy formats like JPEG
ImageEnView3.IEBitmap.JoinBitmaps( ImageEnView1.IEBitmap, ImageEnView2.IEBitmap, False, clWhite, True, 1.0 );


// Or perform an exhaustive search which gives the best result, but is much slower (because it checks every possibility)
// (You can specify a low value for MinEquality if Exhaustive is used)
ImageEnView3.IEBitmap.JoinBitmaps( ImageEnView1.IEBitmap, ImageEnView2.IEBitmap, False, clWhite, True, 0.5, True );


// Quick joining of two images removing any part of the image that is the same at the joining edge
// This method only checks every 100th row so overlap detection may not be as accurate, but it is much faster
ImageEnView3.IEBitmap.JoinBitmaps( ImageEnView1.IEBitmap, ImageEnView2.IEBitmap, False, clWhite, True, 0.98, False, 0.01 );


// Horizontally join 5 images that have overlapping joining edges
bmpIn  := TIEBitmap.Create();
bmpOut := TIEBitmap.Create();

for i := 1 to 5 do
begin
  bmpIn.LoadFromFile( 'D:\Join' + i.ToString + '.jpg' );
  if i = 1 then
    bmpOut.Assign( bmpIn )
  else
    bmpOut.JoinBitmaps( nil, bmpIn, False, clWhite, True, 0.997 );
end;

// Show result
ImageEnView1.Assign( bmpOut );

bmpIn .Free;
bmpOut.Free;