Author |
Topic |
|
JohnnyT
USA
21 Posts |
Posted - Jun 29 2011 : 07:43:04
|
I'm trying to allow the user to "write" usting a stylus, mouse on a transparent layer in an ImageEnView, (posssibly an ImageEnVect).
I'm using code that worked with a TPicture mouse events, but, for some reason does not work with the ImageEnView mouse events. I've tested this with and without adding layers to the underlying BMP that is loaded.
The code, (see below) compiles and does not complain, it simply does not do anything.
I must be missing something simple?
Thanks,
John
procedure TDocEditorForm.ImageEnView1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
with ImageEnView1, canvas do
begin
If checkbox1.checked then
begin
pen.width:=15;
pen.color:=clwhite;//acts as an eraser
end else
begin
pen.width:=3;
pen.color:=clblack;
end;
drawing:=true; //public variable
moveto(x,y);
end;
end;
procedure TDocEditorForm.ImageEnView1MouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
drawing := False;
end;
procedure TDocEditorForm.ImageEnView1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
If drawing
then with imageEnView1 do
begin
cursor:=crNone; {to keep cursor redraw from erasing part of the line}
canvas.lineto(x,y);
cursor:=crdefault;
end;
end; |
|
JohnnyT
USA
21 Posts |
Posted - Jun 29 2011 : 11:24:17
|
Also, I should have mentioned this...For now, I'm just trying to get handwriting working with an ImageEnView.
The ultimate goal is finding the best way to allow handwriting with undo/redo functionality on a transparent layer.
Any hints as to the best approach would be appreciated. Just upgraded to the current version.
John |
|
|
w2m
USA
1990 Posts |
Posted - Jun 29 2011 : 11:38:45
|
You have to do a little more to make it work, plus you have to use the bitmap.canvas for drawing.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ieview, imageenview, ComCtrls, ExtCtrls;
type
TForm1 = class( TForm )
Panel1: TPanel;
StatusBar1: TStatusBar;
ImageEnView1: TImageEnView;
CheckBox1: TCheckBox;
Button1: TButton;
Button2: TButton;
procedure ImageEnView1MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer );
procedure ImageEnView1MouseUp( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer );
procedure ImageEnView1MouseMove( Sender: TObject; Shift: TShiftState; X, Y: integer );
procedure Button1Click( Sender: TObject );
procedure FormCreate( Sender: TObject );
procedure Button2Click( Sender: TObject );
private
{ Private declarations }
Drawing: boolean;
StartX: integer;
StartY: integer;
LastX: integer;
LastY: integer;
APenSize: integer;
procedure MyUndo( ie: TImageEnView );
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses imageenproc;
{$R *.dfm}
procedure TForm1.MyUndo( ie: TImageEnView );
var
x1, y1, x2, y2: integer;
begin
x1 := StartX;
y1 := StartY;
x2 := LastX;
y2 := LastY;
OrdCor( x1, y1, x2, y2 );
ie.Proc.UndoRect( x1 - APenSize, y1 - APenSize, x2 + APenSize, y2 + APenSize );
end;
procedure TForm1.Button1Click( Sender: TObject );
begin
ImageEnView1.LayersAdd;
// render white bitmap on layer x
with ImageEnView1.CurrentLayer do
ImageEnView1.Proc.Fill( clWhite );
ImageEnView1.Update;
end;
procedure TForm1.Button2Click( Sender: TObject );
begin
if ImageEnView1.LayersCount > 1 then
ImageEnView1.LayersRemove( ImageEnView1.LayersCurrent )
else
ShowMessage( 'No Layer To Remove.' );
end;
procedure TForm1.FormCreate( Sender: TObject );
begin
// render white bitmap on layer 0
ImageEnView1.Proc.Fill( clWhite );
ImageEnView1.Update;
end;
procedure TForm1.ImageEnView1MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer );
begin
if ImageEnView1.MouseCapture then
begin
with ImageEnView1 do
begin
// prevent exception by trying to draw outside of the bitmap
if ( XScr2Bmp( X ) >= 0 ) and ( XScr2Bmp( X ) <= Bitmap.Width - 1 ) and ( YScr2Bmp( Y ) >= 0 ) and
( YScr2Bmp( Y ) <= Bitmap.Height - 1 ) then
begin
Proc.SaveUndo( ieuImage );
StartX := XScr2Bmp( X );
StartY := YScr2Bmp( Y );
with Bitmap.Canvas do
begin
if CheckBox1.Checked then
begin
APenSize := 15;
Pen.Width := 15;
Pen.Color := clWhite; // acts as an eraser
Brush.Color := clWhite;
end
else
begin
APenSize := 3;
Pen.Width := 3;
Pen.Color := clBlack;
Brush.Color := clBlack;
end;
Drawing := true; // private variable
end;
end;
end;
end;
end;
procedure TForm1.ImageEnView1MouseMove( Sender: TObject; Shift: TShiftState; X, Y: integer );
begin
if ImageEnView1.MouseCapture then
begin
if Drawing then
begin
with ImageEnView1 do
begin
// prevent exception by trying to draw outside of the bitmap
if ( XScr2Bmp( X ) >= 0 ) and ( XScr2Bmp( X ) <= Bitmap.Width - 1 ) and ( YScr2Bmp( Y ) >= 0 ) and
( YScr2Bmp( Y ) <= Bitmap.Height - 1 ) then
begin
MyUndo( ImageEnView1 );
with ImageEnView1 do
begin
Bitmap.Canvas.MoveTo( StartX, StartY );
Bitmap.Canvas.LineTo( XScr2Bmp( X ), YScr2Bmp( Y ) );
Cursor := crDefault;
end;
// for undo method
LastX := ImageEnView1.XScr2Bmp( X );
LastY := ImageEnView1.YScr2Bmp( Y );
end;
end;
end;
end;
end;
procedure TForm1.ImageEnView1MouseUp( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer );
begin
Drawing := False;
end;
end.
William Miller |
|
|
JohnnyT
USA
21 Posts |
Posted - Jun 29 2011 : 13:27:14
|
William,
Holy Mackeral!
You really did more than just provide hints!
My gosh, I owe you big time!!! This is great.
I'll let you know how it turns out.
THANKS SO MUCH!
John |
|
|
JohnnyT
USA
21 Posts |
Posted - Jun 30 2011 : 06:23:28
|
William,
It sorta/kinda works.
The "writing" however appears only as straight lines. Curvatures are not being rendered.
Also, how do I add a clear, (non opaque) layer?
The total idea is to allow the user to open a BMP in layer zero, scribble on layer 1, and merge the two afterward.
Thanks for any hints.
John
|
|
|
w2m
USA
1990 Posts |
Posted - Jun 30 2011 : 08:25:52
|
MoveTo LineTo only draws straight lines. More code is needed to paint with brushes. Fabrizio's brush drawing examples uses a layer for the brush so I am not sure how this will work with other layers. Let me see what I can comeup with.
William Miller |
|
|
JohnnyT
USA
21 Posts |
Posted - Jun 30 2011 : 09:53:00
|
William,
Yes, not sure how it can be done.
I know that my original TPicture.canvas mouse events seem to work for writing.
The problem of course is layering, and undo functionality.
I REALLY appreciate your help.
John |
|
|
w2m
USA
1990 Posts |
Posted - Jul 01 2011 : 10:35:35
|
We have produced a very nice demo that allows GDI+ brush drawing using a TIECanvas in a transparent layer.
All that remains to be done is to add drawing the brush shape ( ellipse or square ) to the OnDrawBackBuffer event.
The demo allows adding, deleting, hideing and showing layers with undo, redo and zooming.
Hopefully it will be released a a day or so.
William Miller |
|
|
JohnnyT
USA
21 Posts |
Posted - Jul 01 2011 : 10:41:29
|
William,
Oh Man!
That's incredible!!!
I think the ImageEn community will find it very useful. I think many of us are now developing for tablet machines. Being able to handwrite with the features you've mentioned is PERFECT!
This is very much appreciated!
John |
|
|
xequte
38611 Posts |
|
w2m
USA
1990 Posts |
Posted - Jul 12 2011 : 06:29:16
|
Just so everyone knows... it turns out that using TieCanvas (GDIPlus) drawing is not fast enough for handwriting. You can use touch in the demo to draw and to do handwriting, but if you move the mouse or finger too fast, a series of "dots" appears instead of a painted line. The faster you move the mouse or finger the more "dots" are produced.
If you move the mouse or finger below a ceartain threshold the drawing works perfectly. I tried to optimize the painting as much as possible with little success. The demo uses the least amount of code necesary to draw the brush and alphachannel in OnDrawBackBuffer and in OnMouseMove.
One thing that could be tried to speed up the drawing if you do not need an alphchannel is to remove the second call in OnMouseMove to the TIECanvas. You will loose the ability to draw with alpha but it may be faster if you do. I have not tested this yet.
William Miller |
|
|
mark.knight
USA
2 Posts |
Posted - Sep 27 2012 : 13:26:21
|
Has there been any new developments on the speed issue of drawing such as discussed in this thread? We having implemented something similar to the Simple GDI Plus drawing and we are seeing this exact issue. If the mouse moves too fast then your drawing line becomes dots.
attached is an image showing a slowly drawn line and a quick drawn line.
|
|
|
w2m
USA
1990 Posts |
Posted - Sep 27 2012 : 16:14:52
|
Unfortunately, I do not know of a way to increase the speed of alphablended brush drawing with ImageEn. I have been sucessful with high speed brush drawing with a third-party component that works very well with ImageEn. Unfortunately I do not think the component I use has been published.
You could take a look at Paint Engine v. 3.0.4 by NewWest Software. http://www.nwscomps.com/pe.html I have never got around to trying it, but it offers many more features than the component I use.
William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html |
|
|
mark.knight
USA
2 Posts |
Posted - Sep 27 2012 : 16:31:26
|
Have you been successful in non alpha implementations? |
|
|
w2m
USA
1990 Posts |
Posted - Sep 28 2012 : 08:45:13
|
An TIECanvas without alpha and SmoothingMode set to iesmBestPerformance seems to be the fastest I can come up with. When drawing with the mouse at moderately high speed is the best. Very fast mouse speeds produce the series of "dots".
If you want to totally eliminate the dots then a third-party brush component would work the best.
The freeware ImagePainter at http://www.omuller.com/ seems to handle high speed mouse brush painting without the "...dots". The NewWest ImageEnPainter Demo also handles high speed drawing.
William Miller |
|
|
nwscomps
185 Posts |
Posted - Sep 28 2012 : 10:02:40
|
If you need a highly performant and customizable paint engine for the IamgeEn library that will work with any TImageEnView descendant and it is very quick to set-up you can download the demo from our website:
www.nwscomps.com
Thanks
Francesco Savastano Nwscomps.com Add-ons for the ImageEn Library |
|
|
|
Topic |
|