Solved

Concatenating multiple Images

Posted on 2008-06-24
16
1,018 Views
Last Modified: 2012-06-21
Dear experts

I want to concatenate two images that have are overlapped with each other. Sample of two such images are attched. Images 1.png, 2.png, 3.png, 4.png and 5.png are overlapped and I want to create a concatenated version of these images. Overlapped sections of the images should not copied. The overlapped sections didn't have fixed height.

I need a very very fast (As fast as possible) and accurate function for concatenation.

1.png
2.png
3.png
4.png
5.png
0
Comment
Question by:JustScreenShot
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 3
  • +3
16 Comments
 
LVL 13

Expert Comment

by:rfwoolf
ID: 21856933
Attached is a procedure that you can play around with to get the results you need... What the procedure below does is it places a bitmap in the centre of another bitmap on a Timage- you will use the same idea.

Also, In this attached demo you use 2 Opendialogs to point to the images you want to use - you can instead just replace these parts with the path to the images you need - or if you somehow have them in memory.

Basically what you'll need to do is have a TImage and 2 TBitmaps.
You will need to size the Timage big enough to fit the two concatenated images - in other words Timage will be your canvas for laying out of the images.
Then you simply draw the bitmaps onto the canvas:
image1.Picture.Bitmap.Canvas.draw(X,Y,bitmap);//place the bitmap onto the image //where X and Y is the top and left of the image
image1.Picture.Bitmap.Canvas.draw(X,Y,bitmap2);//place the bitmap2 onto the image
For this you will need a TImage component on your form,
as well as a button
as well as an OpenDialogue.
It is recommended (but not essential) that you set your TImage component's Autosize to True;
 
Here is the sourcecode for the button...
 
procedure TForm1.Button1Click(Sender: TObject);
var
  bitmap1   : TBitMap;      //declare bitmap container 1
  bitmap2   : TBitMap;      //declare  bitmap container 2
  daLeft, daTop : Integer;  //declare two integer units for positioning of the second bitmap
begin
  if opendialog1.Execute then //opens a dialogue asking for the first image
  begin
    bitmap1 := TBitmap.Create;  //create the bitmap container 1
    try
      bitmap1.LoadFromFile(opendialog1.FileName);  //load the file the user chose into the bitmap 1
      image1.Picture.Bitmap.Assign(bitmap1);  //load bitmap1 into your form's image component
      //MOVING ON TO NEXT BITMAP
      if opendialog1.Execute then //opens a dialogue asking for the first image
      begin
        bitmap2 := TBitMap.Create; //create the bitmap container 2
        bitmap2.LoadFromFile(opendialog1.FileName);  //load the file the user chose into the bitmap 2
         try
          daLeft := round((bitmap1.width - bitmap2.width) / 2); //calculate left position of 2nd bitmap
          daTop := round((bitmap1.Height - bitmap2.Height) / 2); //calculate top position of 2nd bitmap
          image1.Picture.Bitmap.Canvas.draw(daLeft,daTop,bitmap2);//place the bitmap 2 onto the bitmap 1 on the image
        finally
          bitmap2.Free;  //free the 2nd bitmap container in memory
        end;
      end;
    finally
      bitmap1.Free;   //free the 2nd bitmap container in memory
    end;
  end;
end;

Open in new window

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 21856952
I then forgot a very important part - the output!
You will then say
  Image1.picture.SaveToFile('MyImage.BMP'); -- if you want to save it to a file
or else you can copy it to the clipboard or do what you want.

If you have a problem with the format (BMP) see if you can use PNG instead - I think you can. Alternatively in the JVCL suite there is a TImage type component that works with a variety of formats including GIF, jpeg, BMP etc - so instead of using a TImage you will use TJvImage or something
0
 

Author Comment

by:JustScreenShot
ID: 21858040
Dear rfwoolf

Thank for the answer. May be I was not clear enough. I actually need an algorithm for finding overlapped sections of the image and delete the overlapped parts and concatenate 3 images or more together.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Expert Comment

by:rfwoolf
ID: 21858080
Yes I'm afraid you didn't explain yourself very well - I still don't understand because the 5 example images don't make sense - there doesn't seem to be a discernable pattern. The images are 'cut' in unexpected places - you need to explain exactly how you'd want it to do it. If you can't explain it to a human, you might have some trouble explaining it to a PC :)
0
 
LVL 21

Expert Comment

by:developmentguru
ID: 21858358
 I think I can see what you are looking for... if I am right then my explanation should help.  The first 4 images, in the area that is text, appear to be the same.  The fifth image has a little more text.  On the right side however the images are different.  So, from what I can see, you want to reconstruct the image on the right by stripping out all of what is in the image on each one, and correctly overlap them to produce a larger, complete, image.

simplified...

image 1
----
        A
        B
----

image 2
----
        B
        C
        D
----

produces...
----
        A
        B
        C
        D
----


  Let me know if I am correct on this.
0
 
LVL 21

Expert Comment

by:developmentguru
ID: 21858369
or, perhaps you want the whole screen?
0
 

Author Comment

by:JustScreenShot
ID: 21864717
Dear developmentguru, neither of 5 images ARE NOT the same. Each of them has more text than the previous. Actually I want to create a screenshot from the page wholly.

Assume this page that you are reading my comment. take a capture from the the internal browser window. Now press down key and take a new capture. repeat these steps until you reached to the end of the page. Now I want to concatenate these pictures with each other. At the first step should overlapped sections of images recognized and then the images could stick to each other without overlapped section to make the finall image. this is a feature named "Automatic Scrolling" could be found at screen capture program like SnagIt.
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 21864764
I think one important technical consideration is whether it's possible to calculate which portions of the images can be 'cut off' - for example if you know that the screen scrolls 50 pixels down then you know to cut off 50 pixels. But if that's not possible becomes much harder and you have to start with image algorithms to get the program to 'visually' compare the images for similar pixels .

So JustScreenShot - *HOW* you are getting these images is important - because you might be able to collect how many pixels the screen has scrolled.
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 21865235
http://www.scootersoftware.com

the program is called BeyondCompare and it has a picture compare tool.
You can compare 2 pictures in several modes.

with this you can find the matching blocks manually

next step would be to add the non matching blocks to a total image

repeat the process for each subsequent image

problem is there is no automatic matching block algorithm

VNC also has a way of only sending the blocks of the screenshot that have changed...

Am i getting anywhere close ?
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 21865940
JustScreenShot,

I would agree with the others that the *how* (regarding image collection) is important, as knowing this may allow for alternative suggestions. For example, if you are only dealing with browser window capturing, I do have code that will allow you to capture the "whole" browser window image, regardless of scroll bars.

Russell

0
 
LVL 21

Expert Comment

by:developmentguru
ID: 21874103
 The problem is more complex than you know.  If you scan image 1 and find an exact matching line of pixels in image 2, is that a match?  I personally have seen the same line of text inserted twice for emphasis.  This means that if you scan the same 12 pixels of the line in image one you can find it in more then one location in image 2.  If you do a line by line search and show all matches for each line then you would be able to find the longest consecutive match and use that as your starting block.  This is oversimplified as it only matches vertically.  I would not consider such an algorythm to be complete without taking into account the possibility of horizontal changes.

  You may be able to take an easier approach to this though.  The approach would likely be limited by Windows.  If you were to resize the window to the needed size for a full capture, then capture it.  I am really just thinking out loud here, so bear with me.  In Delphi you can request a window paint itself to a bitmap.  I would expect that this is a function of Delphi more than of windows. You can use Windows messages to figure out the needed extents by finding and sendig messages to the windows scroll bars.  This will get you the needed scroll values that will let you determine the size.  Once you have the size you could create a Delphi window (invisible or off screen) containing a web browser component) of the correct size and go to the web address (also determined using windows messages if needed).  Of course if you are using a Delphi window you could just resize until the scroll bars are off... Once this is done, just request that the window paint to a bitmap and you are done.  Save it, copy to the clipboard, whatever.  One downside to this approach is that many sites have advertising that changes with each visit.  This would likely be different.

  I hope that this helps to clarify the original approach and, perhaps, helps you think outside the box for other possibilities.
0
 

Author Comment

by:JustScreenShot
ID: 21893671
Thank for the comments

rfwoolf:
I'm sure this is something possible because programs like SnagIt and CaptureWizPro accomplish that, successfully.

I got images by captureing current window content, pressing down arrow key, capturing window content, pressing down arrow key, captureing window content, .....

Geert_Gruwez:
Thank for the pointing me forward to VNC. I will take a look over it.


rllibby:

I want to use a generic way for all or most of windows and not only Browsers. As I said it's something that SnagIt accomplished it very quick and well.

developmentguru:
Yes. I agree with you that it's almost seems impossible to design an algorithm that could be found overlapped sections of two images. I wrote a very simple function to do this comparision But the result is not good and sometimes the algorithm found inaccurate positions.

Your solution to repaint the content window to a TBitmap is theorically seems to work but practically there are lot's of problem with various windows with this method. I have a very good code samle that accomplish this. I will send the link, in the next hours.

I'm very courious to know how a program likes SnagIt accomplished this task very quickly and accurately.
0
 

Author Comment

by:JustScreenShot
ID: 21893679
I'm not sure but may be program like SnagIt is not comparing two images. Maybe it use a completely different approach and it is able to get the current position of the scrolled window. I found an interesting similar question without any answer, here:
http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_23496918.html?cid=239
0
 

Author Comment

by:JustScreenShot
ID: 21894526
Here is a code that I wrote for finding overlapped sections of two images. As I already said it's inaccurate.
procedure FindOverlap(B1, B2: TBitmap; var FoundR1,
  FoundR2: Integer; MatchesRowsMinimum: Integer);
var
  R1, R2, X, RX: Integer;
  MatchesRow: Integer;
  C1, C2: PRGBTripleArr;
begin
  FoundR1 := 0;
  FoundR2 := 0;
 
  for R1 := B1.Height - 1 downto 0 do begin
    C1 := B1.ScanLine[R1];
    for R2 := 0 to B1.Height - 1 do begin
      C2 := B2.ScanLine[R2];
      RX := R2;
      if IsRowEqual(C1, C2, B1.Width) then begin
        MatchesRow := 0;
        for X := R1 to B1.Height - 1 do begin
          C1 := B1.ScanLine[X];
          C2 := B2.ScanLine[RX];
          if IsRowEqual(C1, C2, B1.Width) then
            Inc(MatchesRow)
          else
          begin
            MatchesRow := 0;
            Break;
          end;
 
          if (MatchesRow > MatchesRowsMinimum) then begin
            FoundR1 := R1;
            FoundR2 := R2 + 20;
          end; // if
 
          if RX < B1.Height - 1 then Inc(RX);
          if (FoundR1 <> 0) or (FoundR2 <> 0) then Break;
        end; // for X
      end; // if IsRowEqual
 
      if (FoundR1 <> 0) or (FoundR2 <> 0) then Break;
      Application.ProcessMessages;
    end; // for R2
 
    if (FoundR1 <> 0) or (FoundR2 <> 0) then Break;
    Application.ProcessMessages;
  end; // for R1
end;

Open in new window

0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
ID: 22506710
PAQed with points refunded (500)

Computer101
EE Admin
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi Form ownership 4 125
Delphi IDE crash without error message ... 7 117
Create a path if not exists 7 108
Firemonkey allowing RTL on android 6 56
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question