Solved

Copy TImage Section to another TImage?

Posted on 2000-03-15
27
1,296 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
  • 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
 

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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

706 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now