Solved

Copy TImage Section to another TImage?

Posted on 2000-03-15
27
1,369 Views
Last Modified: 2008-02-26
I setup coordinates, which change to be any size.  I need to be able to take what they mapped out and put into another TImage.

Problem: When I use Copyrect, then it will not resize the TImage, therefore leaving a border or cutting off part of the picture, depending on whether it is smaller or bigger than the TImage.

I need a solution that can update it without a lot of memory usage, because as they drag around the box (the mapped area) then it will change in another window simultaneously.

Note: If the 2nd TImage does not resize to the section I copy it to, then it will not work in the TScrollBox.  I cannot set the TImage to alClient because then it will cut off part of the picture and the scrollbars will not show the entire picture.  I need the Image2 to do AutoResize.
0
Comment
Question by:perkley
[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
  • 14
  • 8
  • 2
  • +3
27 Comments
 

Expert Comment

by:westy100697
ID: 2621887
Hi there,
        Have you thought of saving what you copy to a file. Either .bmp or .wmf and then loading that file in Image2 with the AutoSize property set to true at Design time?? Obviously it has something to do with copying directly to the Canvas. I will look further and see what I can dig up.

WESTY :)
0
 
LVL 1

Expert Comment

by:X_Kalibur
ID: 2621893
perkley,

The solution to your problem is simple...

you have to set the "AutoSize" property on the second TImage object  to "True"..

This will then allow the object to automatically resize itself when it gets data into its canvas.

hth,

-x
0
 

Expert Comment

by:westy100697
ID: 2621903
Hi there,
        Have you thought of saving what you copy to a file. Either .bmp or .wmf and then loading that file in Image2 with the AutoSize property set to true at Design time?? Obviously it has something to do with copying directly to the Canvas. I will look further and see what I can dig up.

WESTY :)
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!

 

Expert Comment

by:westy100697
ID: 2621912
X Kalibur,
          Have you actually tried this. I am using D3 and it doesn't autoresize if you use CopyRect. Try it. Even with that Property set.

WESTY :)
0
 

Author Comment

by:perkley
ID: 2621914
Yes X Kalibur, I have tried setting AutoSize to True, but it is not effected when you use CopyRect.

Yes Westy, I have thought about saving it to a file, but remember that it will be changing simulataneously while you move your box around on the image below Image1.  Writing a file each time would be to much I think.
0
 

Expert Comment

by:westy100697
ID: 2621922
perkley,
        What about creating a TMetafile object to store into and copy out of ?

I am trying this now.

WESTY :)
0
 

Expert Comment

by:westy100697
ID: 2621938
perkley,
        Don't worry about the Autosize leave it as false then do this


Image2.Canvas.CopyRect(Rect(0,0,Round(Abs(X1-X2)),Round(Abs(Y1-Y2))),Image1.Canvas,Rect(X1,Y1,X2,Y2));
  Image2.Width := Round(Abs(X1-X2));
  Image2.Height := Round(Abs(Y1-Y2));

The co-ordinates I have here are X1,Y1
or top left corner of rectangle and
 X2,Y2 bottom left corner of rectangle.

Does that help at all ?

It seems to work for me without much processing for computer.

WESTY :)
0
 

Expert Comment

by:westy100697
ID: 2621944
perkley,
        X2,Y2 should be bottom right corner. Sorry bout that

WESTY :}
0
 

Author Comment

by:perkley
ID: 2621985
You know, that just about worked, but when I resize my top coordinates (width or height) then it will not resize the Image2.  It sizes it correct the first time, but it won't thereafter.  I have been playing around with it, but still cannot get it to work correctly.  When I step through my code, it seems as though it should, but for some reason Image1 will not take on the new Width and Height once set.
0
 

Expert Comment

by:westy100697
ID: 2621992
perkley,
        Hang on I will try it here.
Are you using

 Image2.Canvas.CopyMode := cmSrcCopy ;

??

WESTY :|
0
 

Expert Comment

by:westy100697
ID: 2622007
perkley,
        So how are you selecting your points, using a drag or two seperate mouse clicks ??

I have just been using to seperate clicks to capture both points individually and it works fine.
I will try it the other way now.

WESTY :)
0
 

Author Comment

by:perkley
ID: 2622023
Here is what is happening.  I capture the points and put them in the edit boxes.

I then set these coordinates.

X1 := StrToInt(eLeft.Text);
X2 := StrToInt(eLeft.Text)+StrToInt(eWidth.Text);
Y1 := StrToInt(eTop.Text);
Y2 := StrToInt(eTop.Text)+StrToInt(eHeight.Text);

Then I call the Width and Height:

iPreview.Width := Round(Abs(X1-X2));
iPreview.Height := Round(Abs(Y1-Y2));

And finally the CopyRect:

iPreview.Canvas.CopyRect(Rect(0,0,Round(Abs(X1-X2)),Round(Abs(Y1-Y2))),iDisplay.Canvas,Rect(X1,Y1,X2,Y2));

It doesn't work when the EditBox Values Change and it recalls everything, but it doesn't resize it.  It gets the new picture, but only fills what the size was before.
0
 

Expert Comment

by:westy100697
ID: 2622079
perkley,
        put iPreview.Width and
iPreview.Height after the call to CopRect and see what happens.

WESTY :)
0
 

Expert Comment

by:westy100697
ID: 2622089
perkley,
        Here is the test code I am using

//Global variables
var
  P1,P2,X1,Y1,X2,Y2 : integer ;

implementation


//select the 2 points
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  If P1 = -1 then
  begin
    X1 := X ;
    Y1 := Y ;
    P1 := 1 ;
  end
  else
  If (P1 <> -1) and (P2 = -1) then
  begin
    X2 := X ;
    Y2 := Y ;
  end
  else
   exit ;
end;

//Reset Button Here
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  P1 := -1 ;
  P2 := -1 ;
end;

//Copy the area from image 1 to 2
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  Image2.Canvas.CopyMode := cmSrcCopy ;
  Image2.Width := Round(Abs(X1-X2));
  Image2.Height := Round(Abs(Y1-Y2));
  Image2.Canvas.CopyRect(Rect(0,0,Round(Abs(X1-X2)),Round(Abs(Y1-Y2))),Image1.Canvas,Rect(X1,Y1,X2,Y2));
end;
//initialise the Points to false
procedure TForm1.FormCreate(Sender: TObject);
begin
  P1 := -1 ;
  P2 := -1 ;
end;


I do use global variables too.


WESTY :)

0
 

Author Comment

by:perkley
ID: 2622090
I did, but when I do it after, then it doesn't even do it the first time.  I am using Delphi 5 Professional, in case that makes a difference.
0
 

Expert Comment

by:westy100697
ID: 2622104
perkley,
        See if my code helps. it definitely does copy the area it is supposed to. I have 2 buttons on the form and click my two points into the variables with the OnMouseUp event. Then I click the second button to copy from on image to the other. It can be all put under the OnMouseUp if required.

WESTY :)
0
 

Author Comment

by:perkley
ID: 2622154
Westy,

I tried your code exactly and it still has problems.

Try this yourself.  In design mode, make Image2.Width = 10, and Image2.Height = 10 - Then choose some points on Image1 that are bigger than 10x10.  Notice it will not change Image2 to fit.
0
 

Expert Comment

by:westy100697
ID: 2622197
perkley,
        You were right about that however here is the solution. Put the Width and Height before the cmSrcCopy line. It must make it readonly after setting

 Image2.Canvas.Copymode := cmSrcCopy ;

so just do this

 Image2.Height :=
 Image2.Width :=
 Image2.Canvas.CopyMode :=
 Image2.Canvas.CopyRect();

WESTY :)
0
 

Author Comment

by:perkley
ID: 2622208
Is this what you have?

    Image2.Width := Round(Abs(X1-X2));
    Image2.Height := Round(Abs(Y1-Y2));
    Image2.Canvas.CopyMode := cmSrcCopy ;
    Image2.Canvas.CopyRect(Rect(0,0,Round(Abs(X1-X2)),Round(Abs(Y1-Y2))),Image1.Canvas,Rect(X1,Y1,X2,Y2));

I tried it with making the Width and Height before, and it seems to be getting a smaller than what my Image2 in design mode is, even when selecting bigger.  It is strange.  How about you send me your working demo to douglas@rexburg.com
0
 
LVL 20

Accepted Solution

by:
Madshi earned 50 total points
ID: 2622462
Try using this:

  Image2.Width := newWidth;
  Image2.Height := newHeight;
  Image2.Picture.Bitmap.Width := newWidth;
  Image2.Picture.Bitmap.Height := newHeight;

If that still doesn't work, try using this before the code from above:

  Image2.Picture.Bitmap.Assign(nil);

Regards, Madshi.
0
 

Expert Comment

by:westy100697
ID: 2622761
Madshi,
       Yeh I figured it out and e-mailed perkley what I came up with. Plays up a treat the canvas doen't it. It just needs to be assigned nil or overwritten with an image and it works fine.

WESTY :}
0
 
LVL 1

Expert Comment

by:Asw
ID: 2622998
listening...
0
 

Expert Comment

by:westy100697
ID: 2625411
Madshi,
       You should lock this question as your answer is the best solution.

WESTY :)
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2625421
Set the destination TImage Autosize to True, and then only resize the underlying bitmap.

image1.picture.bitmap.width := x1 - x2;
image1.picture.bitmap.height := y2 - y1;
image1.canvas.CopyRect(image1.clientrect,image2.canvas,rect(x1,y1,x2,y2));

make sure copymode etc are correct also
0
 

Author Comment

by:perkley
ID: 2625571
This is the best solution so far, and it seems to work just great, no more problems.

  X1 := StrToInt(Edit1.Text);
  X2 := StrToInt(Edit2.Text);
  Y1 := StrToInt(Edit3.Text);
  Y2 := StrToInt(Edit4.Text);
  Image2.Width := Y1-X1;
  Image2.Height := Y2-X2;
  Image2.Picture.Bitmap.Width := Y1-X1;
  Image2.Picture.Bitmap.Height := Y2-X2;
  Image2.Canvas.CopyMode := cmSrcCopy ;
  Image2.Canvas.CopyRect(Rect(0,0,Y1-X1,Y2-X2), Image1.Canvas, Rect(X1,X2,Y1,Y2));

I set the Image2.AutoSize = True and assigned both the picture.bitmap and the canvas Width and Height.

Thanks Madshi
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2626521
With AutoSize set to true, the lines
Image2.Width := Y1-X1;
Image2.Height := Y2-X2;
are completely redundant. Also, why use
"Rect(0,0,Y1-X1,Y2-X2)", when
"clientrect" is more readable, and would probably execute faster?
0
 

Author Comment

by:perkley
ID: 2626696
I knew it was simpler than what we were all trying to make it out as.  Thanks for the comment.
0

Featured Post

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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi application Soap connection 5 151
Convert MS Word document to a PDF file 9 131
Dynamically Created Query 3 77
Broadcast a message using ICS 2 48
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
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…

738 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