Author |
Topic  |
|
Edelcom

Belgium
12 Posts |
Posted - May 20 2012 : 21:20:52
|
Hi,
I use the ImageEnView1.Proc.Rotate(..., True); routine to give my users a way to rotate an image in small or larger steps.
They use it to straighten images of jewelry.
It would be very helpful for them to be able to have an overlay of a horizontal or vertical line, movable by them (dragging it left-right or up-down).
Any help as how to best achieve this ?
Thanks for any help you might provide.
Programmer by choice and profession. |
|
fab
   
1310 Posts |
Posted - May 21 2012 : 08:42:19
|
Hi, you should implement it by handling mouse events (MouseDown/Move/Up). You can draw an overlay in OnDrawBackBuffer event. |
 |
|
Edelcom

Belgium
12 Posts |
Posted - May 21 2012 : 09:13:22
|
Thanks for replying Fabrizio.
Do you happen to have an example of this ?
I did not find anything in the demo folder and the event does not receive any additional parameters.
Programmer by choice and profession. |
 |
|
fab
   
1310 Posts |
Posted - May 21 2012 : 09:27:19
|
There isn't an example, what you need is a bit specific. Inside OnDrawBackBuffer you can draw on BackBuffer bitmap. For example:
Procedure Form1OnDrawBackBuffer(Sender:TObject); Begin With ImageEnView1.BackBuffer.Canvas do begin Pen.Color:=clRed; MoveTo( 0,0 ); LineTo( 100,100 ); End; End; |
 |
|
Edelcom

Belgium
12 Posts |
Posted - May 21 2012 : 09:34:51
|
Thanks, I had done something like that but used the ImageEnView1.Bitmap.Canvas instead of the ...Backbuffer...
Just have to take into account the zoom factor cause the back buffer seems to use the canvas of the component regardless of the loaded picture and regardless how it is zoomed.
Programmer by choice and profession. |
 |
|
w2m
   
USA
1990 Posts |
Posted - May 21 2012 : 10:03:12
|
Try this:
private
{ Private declarations }
fmx, fmy: integer;
flx, fly: integer;
// helper function
function ContrastingColor(AColor: TColor): TColor;
// Return s contracting color of the passed color
begin
if ((AColor and $FF) * 77 + ((AColor shr 8) and $FF) * 150 + ((AColor shr 16) and $FF) * 29)
> 127 * 256 then
Result := clBlack
else
Result := clWhite;
end;
procedure TForm1.ImageEnView1DrawBackBuffer(Sender: TObject);
var
bx, by: Integer;
begin
bx := ImageEnView1.XScr2Bmp ( fmx );
by := ImageEnView1.YScr2Bmp ( fmy );
if (bx >= 0) and (bx <= ImageEnView1.IEBitmap.Width - 1) and (by >= 0) and
(by <= ImageEnView1.IEBitmap.Height - 1) then
begin
with ImageEnView1.BackBuffer.Canvas do
begin
Pen.Mode := pmCopy;
Pen.Width := 3;
{ Make sure brush is visible regardless of the color under the cursor by setting pen color to a contrasting with the color under the cursor }
Pen.Color := ContrastingColor(ImageEnView1.IEBitmap.Canvas.Pixels[bx, by]);
Brush.Style := bsClear;
MoveTo(0, by);
LineTo(ImageEnView1.IEBitmap.Width, by);
MoveTo(bx, 0);
LineTo(bx, ImageEnView1.IEBitmap.Height);
end;
end;
end;
procedure TForm1.ImageEnView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
fmx := X;
fmy := Y;
flx := X;
fly := Y;
ImageEnView1.Update;
end;
William Miller |
 |
|
w2m
   
USA
1990 Posts |
Posted - May 21 2012 : 11:06:33
|
This is not adjusted for zoom. I can not seem to get the math correct when adjusting for zoom. Fabrizio, can you adjust this for zoom?
William Miller |
 |
|
Edelcom

Belgium
12 Posts |
Posted - May 22 2012 : 01:12:05
|
Thanks for the code, but this only works if the loaded image is bigger than the available canvas. If it is smaller the cross is drawn outside the bitmap ( and you cannot get it into the bitmap either ).
I will try further and let you know the result.
Programmer by choice and profession. |
 |
|
w2m
   
USA
1990 Posts |
Posted - May 22 2012 : 14:13:47
|
This works at all zoom levels. The lines are drawn over the entire component:
procedure TForm1.ImageEnView1DrawBackBuffer(Sender: TObject);
begin
with ImageEnView1.BackBuffer.Canvas do
begin
Pen.Mode := pmCopy;
Pen.Width := 3;
Pen.Color := clRed;
Brush.Style := bsClear;
MoveTo(0, fmy);
LineTo(ImageEnView1.Width, fmy);
MoveTo(fmx, 0);
LineTo(fmx, ImageEnView1.Height);
end;
end;
William Miller |
 |
|
Uwe
  
284 Posts |
Posted - May 24 2012 : 08:30:16
|
William,
the above seems to be very slow when you have loaded a large image into the component and have set a resampling filter.
Uwe |
 |
|
w2m
   
USA
1990 Posts |
Posted - May 24 2012 : 10:20:49
|
Uwe,
I tested with images from 2048x1536 to 29701x1974 with various layer filters and found that up to 2048x1536 I did not detect slowness. With images larger than that I saw the slowdown. I have no idea how to speed this up so my advise is do not use layer filters with large images if you want to paint to the backbuffer. I do not know the image size limit when speed becomes an issue.
William Miller |
 |
|
Uwe
  
284 Posts |
Posted - May 24 2012 : 11:03:01
|
William,
I only tested with CR2 files (coming from a Canon 7D) which are approx. 30 MB in size. The slowdown is significant if you use the OnMouseMove event and perform an update; it's looking much better once you've moved the code** to the OnMouseDown event.
Uwe
**
procedure TForm1.ImageEnView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin fmx := X; fmy := Y; flx := X; fly := Y; ImageEnView1.Update; end; |
 |
|
|
Topic  |
|