T O P I C R E V I E W |
quack |
Posted - Feb 06 2015 : 00:23:06 Hi,
I admit to not understanding the ins and outs of ImageEN. I have version 4.1.0 (yes, I know it is old). Hopefully the problem is with my understanding.
I have a TImageENView component on a tabbed notebook page. I can load a bitmap, zoom and move around. The first (bitmap) layer is used to display a map. I want to add another layer on which I will draw a bunch of rectangles, lines, ellipses, text, etc, to annotate the map. The second layer should be transparent except the stuff I have drawn. The map will not be drawn on, as such, I will change visibility of the layers to see what has been drawn.
My code looks like this, in skeleton form.
var tudd_iev_Map: TImageENView;
tudd_tab_Map: TTabSheet;
tudd_Basemap_Layer,
tudd_Basemap_Controls, i: Integer;
r: TRect;
begin
{TImageENView component resized to fill notebook page}
tudd_iev_Map.Left := 0;
tudd_iev_Map.Top := 0;
tudd_iev_Map.Width := tudd_tab_Map.ClientWidth;
tudd_iev_Map.Height := tudd_tab_Map.ClientHeight;
{Enable transparency}
tudd_iev_Map.EnableAlphaChannel := TRUE;
{First layer is a solid bitmap}
tudd_iev_Map.IO.LoadFromFile( 'map.png' );
tudd_Basemap_Layer := tudd_iev_Map.LayersCurrent;
tudd_iev_Map.Layers[tudd_Basemap_Layer].Transparency := (XLayer1);
{Second layer is transparent}
tudd_Controls_Layer := tudd_iev_Map.LayersAdd;
tudd_iev_Map.Layers[tudd_Controls_Layer].Transparency := (XLayer2);
tudd_iev_Map.Proc.Fill( CreateRGB( 255,255,255 ) );
tudd_iev_Map.Proc.SetTransparentColors(
CreateRGB( 255, 255, 255 ),
CreateRGB( 255, 255, 255 ), 0 );
{Draw some sample ellipses on the second layer}
for i := 1 to 20
do begin
r.Left := Random( 500 );
r.Right := Random( 500 );
r.Top := Random( 500 );
r.Bottom := Random( 500 );
tudd_iev_Map.IEBitmap.Canvas.Pen.Style := psSolid;
tudd_iev_Map.IEBitmap.Canvas.Pen.Color := 256*Random( 256 );
tudd_iev_Map.IEBitmap.Canvas.Brush.Style := bsSolid;
tudd_iev_Map.IEBitmap.Canvas.Brush.Color := Random( 255 );
tudd_iev_Map.IEBitmap.Canvas.Ellipse( r );
{ tudd_iev_Map.Update;}
end;
{ tudd_iev_Map.Update;}
tudd_iev_Map.LayersMergeAll;
tudd_iev_Map.IO.SaveToFile( 'map-mod.png' );
end;
(XLayer1) and (XLayer2) are transparencies for the two layers. 'map.png' is a 2479x3508 PNG image.
If the two lines containing (XLayer1) and (XLayer2) are commented out, then the output file contains only the map. Calling tudd_iev_Map.Update after drawing the ellipses has no effect.
(XLayer1)=0, (Xlayer2) commented out: Entire bitmap is filled with notebook page colour. (XLayer2)=0, (XLayer1) commented out: Bitmap contains only map (as for both lines commented out). (XLayer1=0), (XLayer2=0): Entire bitmap is filled with notebook page colour. (XLayer1)=255, (XLayer2) commented out: Bitmap contains only map. (XLayer2)=255, (XLayer1) commented out: Bitmap contains only map. (XLayer1=255), (XLayer2=255): Bitmap contains only map. (XLayer1)=127, (XLayer2) commented out: Bitmap contains only map but it's now semi-transparent. (XLayer2)=127, (XLayer1) commented out: Bitmap contains only map. (XLayer1)=127, (XLayer2=127): Bitmap contains only map but it's now semi-transparent.
From this it appears that I am not writing on the second layer, or that is not merged before writing to disk.
So, what have I done wrong?
Thank you.
Regards, Arnstein |
4 L A T E S T R E P L I E S (Newest First) |
w2m |
Posted - Feb 08 2015 : 08:01:48 Yes you need to draw on the alpha channel and use 32-bit. Here is one way to do it...
Uses iegdiplus (TIECanvas)
{ Draw a pixel color and alpha. }
if (Draw1.Down) and (ImageEnView1.MouseCapture)
then { Paint Point Color and Opacity }
begin
ImageEnView1.Proc.SaveUndoCaptioned
('Draw ' + IntToStr(ImageEnView1.Proc.UndoCount));
iLayerX := ImageEnView1.XScr2Bmp(X);
iLayerY := ImageEnView1.YScr2Bmp(Y);
iPoint.X := iLayerX;
iPoint.Y := iLayerY;
ImageEnView1.HighlightedPixel := iPoint;
iTransparency := PenAlpha1.EditValue;
ImageEnView1.IEBitmap.Canvas.Pixels[iX, iY] := PenColor1.EditValue;
ImageEnView1.IEBitmap.AlphaChannel.Canvas.Pen.Color := $02000000 or
(iTransparency) or (iTransparency shl 8) or (iTransparency shl 16);
ImageEnView1.IEBitmap.AlphaChannel.Canvas.Brush.Color := $02000000 or
(iTransparency) or (iTransparency shl 8) or (iTransparency shl 16);
ImageEnView1.IEBitmap.AlphaChannel.Canvas.Pixels[iX, iY] :=
PenColor1.EditValue;
ImageEnView1.IEBitmap.Alpha[iX, iY] := iTransparency;
ImageEnView1.Update;
UpdateGUI;
{ Update the image in ImageEnMView }
ImageEnMView1.SetIEBitmap(ImageEnMView1.SelectedImage,
ImageEnView1.IEBitmap);
ImageEnMView1.Update;
end
procedure TForm1.MyUndo(ie: TImageEnView);
{ Undo the rect. }
var
ix1, iy1, ix2, iy2: Integer;
iBrushSize: Integer;
begin
ix1 := AStartX;
iy1 := AStartY;
ix2 := ALastX;
iy2 := ALastY;
OrdCor(ix1, iy1, ix2, iy2);
iBrushSize := LineWidth1.EditValue;
ie.Proc.UndoRect(ix1 - (iBrushSize * 10), iy1 - (iBrushSize * 10),
ix2 + (iBrushSize * 10), iy2 + (iBrushSize * 10));
end;
procedure TForm1.DrawLine;
{ Draw a line. }
var
iPenSize: Integer;
iPenColor: TColor;
iPenAlpha: Integer;
iBrushcolor: TColor;
iBrushAlpha: Integer;
iIECanvas1: TIECanvas;
iIECanvas2: TIECanvas;
ix1: Integer;
iy1: Integer;
ix2: Integer;
iy2: Integer;
begin
MyUndo(ImageEnView1);
iPenSize := LineWidth1.EditValue;
iPenColor := PenColor1.EditValue;
iPenAlpha := PenAlpha1.EditValue;
iBrushcolor := PenColor1.EditValue;
iBrushAlpha := PenAlpha1.EditValue;
ix1 := AStartX;
iy1 := AStartY;
ix2 := ALastX;
iy2 := ALastY;
{ Draw on the Non-Alpha Canvas }
iIECanvas1 := TIECanvas.Create(ImageEnView1.Layers[ImageEnView1.LayersCurrent]
.Bitmap.Canvas, Antialias1.Checked, GDIPlus1.Checked);
iIECanvas1.Pen.LineJoin := ieljMiter;
iIECanvas1.Pen.Color := iPenColor;
iIECanvas1.Pen.Style := psSolid;
iIECanvas1.Pen.Width := iPenSize;
iIECanvas1.Brush.Color := iBrushcolor;
iIECanvas1.Brush.BackColor := iBrushcolor;
iIECanvas1.Brush.Style := bsClear;
iIECanvas1.Brush.Transparency := 0;
iIECanvas1.Brush.BackTransparency := 0;
iIECanvas1.MoveTo(ix1, iy1);
iIECanvas1.LineTo(ix2, iy2);
iIECanvas1.Free();
{ Draw on the Alpha Canvas }
OrdCor(ix1, iy1, ix2, iy2);
iIECanvas2 := ImageEnView1.Layers[ImageEnView1.LayersCurrent]
.Bitmap.AlphaChannel.CreateROICanvas(Rect(ix1 - iPenSize * 2,
iy1 - iPenSize * 2, ix2 + iPenSize * 2, iy2 + iPenSize * 2),
Antialias1.Checked, GDIPlus1.Checked);
iIECanvas2.Pen.Width := iPenSize;
iIECanvas2.Pen.Style := psSolid;
iIECanvas2.Pen.LineJoin := ieljMiter;
iIECanvas2.Pen.Color := iPenAlpha or (iPenAlpha shl 8) or (iPenAlpha shl 16);
iIECanvas2.Brush.Style := bsClear;
iIECanvas2.Brush.Color := iBrushAlpha or (iBrushAlpha shl 8) or
(iBrushAlpha shl 16);
iIECanvas2.MoveTo(AStartX, AStartY);
iIECanvas2.LineTo(ALastX, ALastY);
iIECanvas2.Free();
ImageEnView1.Bitmap.Modified := True;
ImageEnView1.IEBitmap.AlphaChannel.Full := False;
end;
procedure TForm1.DrawRectangle;
{ Draw a rectangle. }
var
iIECanvas: TIECanvas;
iPenSize: Integer;
iPenColor: TColor;
iPenAlpha: Integer;
iBrushcolor: TColor;
iBrushAlpha: Integer;
begin
MyUndo(ImageEnView1);
{ Draw on the Non-Alpha Canvas }
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iPenSize := LineWidth1.EditValue;
iPenColor := PenColor1.EditValue;
iPenAlpha := PenAlpha1.EditValue;
iBrushcolor := PenColor1.EditValue;
iBrushAlpha := PenAlpha1.EditValue;
iIECanvas.Pen.LineJoin := ieljMiter;
iIECanvas.Pen.Color := iPenColor;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Brush.Color := iBrushcolor;
iIECanvas.Brush.BackColor := iBrushcolor;
iIECanvas.Brush.Style := bsClear;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.Rectangle(AStartX, AStartY, APX + iPenSize, APY + iPenSize);
iIECanvas.Free();
{ Draw on the Alpha Canvas
Note: do not assign color here... it will overwrite the alphachannel
unless you assign the AlphaChannel.CanvasCurrentAlpha the pen is not
visible with 32-bit bitmaps even though NewCanvas.Pen.Transparency is
set before drawing }
ImageEnView1.IEBitmap.AlphaChannel.CanvasCurrentAlpha := iPenAlpha;
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.AlphaChannel.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iIECanvas.Pen.LineJoin := ieljMiter;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Brush.Style := bsClear;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.Rectangle(AStartX, AStartY, APX + iPenSize, APY + iPenSize);
iIECanvas.Free();
ImageEnView1.Bitmap.Modified := True;
ImageEnView1.Update;
end;
procedure TForm1.DrawFilledRectangle;
{ Draw a filled rectangle. }
var
iIECanvas: TIECanvas;
iPenSize: Integer;
iPenColor: TColor;
iPenAlpha: Integer;
iBrushcolor: TColor;
iBrushAlpha: Integer;
begin
MyUndo(ImageEnView1);
{ Draw on the Non-Alpha Canvas }
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iPenSize := LineWidth1.EditValue;
iPenColor := PenColor1.EditValue;
iPenAlpha := PenAlpha1.EditValue;
iBrushcolor := BrushColor1.EditValue;
iBrushAlpha := BrushAlpha1.EditValue;
iIECanvas.Pen.LineJoin := ieljMiter;
iIECanvas.Pen.Color := iPenColor;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Brush.Color := iBrushcolor;
iIECanvas.Brush.BackColor := iBrushcolor;
iIECanvas.Brush.Style := bsSolid;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.Rectangle(AStartX, AStartY, APX + iPenSize, APY + iPenSize);
iIECanvas.Free();
{ Draw on the Alpha Canvas
Note: do not assign color here... it will overwrite the alphachannel
unless you assign the AlphaChannel.CanvasCurrentAlpha the pen is not
visible with 32-bit bitmaps even though NewCanvas.Pen.Transparency is
set before drawing }
ImageEnView1.IEBitmap.AlphaChannel.CanvasCurrentAlpha := iPenAlpha;
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.AlphaChannel.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iIECanvas.Pen.LineJoin := ieljMiter;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Brush.Style := bsSolid;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.Rectangle(AStartX, AStartY, APX + iPenSize, APY + iPenSize);
iIECanvas.Free();
ImageEnView1.Bitmap.Modified := True;
ImageEnView1.Update;
end;
procedure TForm1.DrawRoundRectangle;
{ Draw a round rectangle. }
var
iIECanvas: TIECanvas;
iPenSize: Integer;
iPenColor: TColor;
iPenAlpha: Integer;
iBrushcolor: TColor;
iBrushAlpha: Integer;
iRoundRectRadius: Integer;
begin
MyUndo(ImageEnView1);
{ Draw on the Non-Alpha Canvas }
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iPenSize := LineWidth1.EditValue;
iPenColor := PenColor1.EditValue;
iPenAlpha := PenAlpha1.EditValue;
iBrushcolor := BrushColor1.EditValue;
iBrushAlpha := BrushAlpha1.EditValue;
iRoundRectRadius := RoundRectangleRadius1.EditValue;
iIECanvas.Pen.Color := iPenColor;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Brush.Color := iBrushcolor;
iIECanvas.Brush.BackColor := iBrushcolor;
iIECanvas.Brush.Style := bsClear;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.RoundRect(AStartX, AStartY, APX + iPenSize, APY + iPenSize,
iRoundRectRadius, iRoundRectRadius);
iIECanvas.Free();
{ Draw on the Alpha Canvas
Note: do not assign color here... it will overwrite the alphachannel
unless you assign the AlphaChannel.CanvasCurrentAlpha the pen is not
visible even though NewCanvas.Pen.Transparency is set before drawing }
ImageEnView1.IEBitmap.AlphaChannel.CanvasCurrentAlpha := iPenAlpha;
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.AlphaChannel.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Brush.Style := bsClear;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.RoundRect(AStartX, AStartY, APX + iPenSize, APY + iPenSize,
iRoundRectRadius, iRoundRectRadius);
iIECanvas.Free();
ImageEnView1.Bitmap.Modified := True;
ImageEnView1.Update;
end;
procedure TForm1.DrawFilledRoundRectangle;
{ Draw a filled round rectangle. }
var
iIECanvas: TIECanvas;
iPenSize: Integer;
iPenColor: TColor;
iPenAlpha: Integer;
iBrushcolor: TColor;
iBrushAlpha: Integer;
iRoundRectRadius: Integer;
begin
MyUndo(ImageEnView1);
{ Draw on the Non-Alpha Canvas }
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iPenSize := LineWidth1.EditValue;
iPenColor := PenColor1.EditValue;
iPenAlpha := PenAlpha1.EditValue;
iBrushcolor := BrushColor1.EditValue;
iBrushAlpha := BrushAlpha1.EditValue;
iRoundRectRadius := RoundRectangleRadius1.EditValue;
iIECanvas.Pen.Color := iPenColor;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Brush.Color := iBrushcolor;
iIECanvas.Brush.BackColor := iBrushcolor;
iIECanvas.Brush.Style := bsSolid;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.RoundRect(AStartX, AStartY, APX + iPenSize, APY + iPenSize,
iRoundRectRadius, iRoundRectRadius);
iIECanvas.Free();
{ Draw on the Alpha Canvas
Note: do not assign color here... it will overwrite the alphachannel
unless you assign the AlphaChannel.CanvasCurrentAlpha the pen is not
visible even though NewCanvas.Pen.Transparency is set before drawing }
ImageEnView1.IEBitmap.AlphaChannel.CanvasCurrentAlpha := iPenAlpha;
iIECanvas := TIECanvas.Create(ImageEnView1.IEBitmap.AlphaChannel.Canvas,
Antialias1.EditValue, GDIPlus1.EditValue);
iIECanvas.Pen.Width := iPenSize;
iIECanvas.Pen.Style := psSolid;
iIECanvas.Pen.Transparency := iPenAlpha;
iIECanvas.Brush.Style := bsSolid;
iIECanvas.Brush.Transparency := iBrushAlpha;
iIECanvas.Brush.BackTransparency := iBrushAlpha;
iIECanvas.RoundRect(AStartX, AStartY, APX + iPenSize, APY + iPenSize,
iRoundRectRadius, iRoundRectRadius);
iIECanvas.Free();
ImageEnView1.Bitmap.Modified := True;
ImageEnView1.Update;
end; Bill Miller Adirondack Software & Graphics Email: w2m@hughes.net EBook: http://www.imageen.com/ebook/ Custom Commercial ImageEn Development |
quack |
Posted - Feb 07 2015 : 20:48:41 I should add that annotations are added interactively so that the changes should be seen with minimum delay. Merging of layers is not done until printing with SaveUndo( ieuLayer ) and Undo bracketing the DoPrintPreviewDialog call.
Regards, Arnstein. |
quack |
Posted - Feb 07 2015 : 20:02:11 Bill,
Thank you for replying. I now understand what you are saying about the Transparency property applying to all operations on a layer. I looked at and played with the samples you linked to and am a little better informed. Unfortunately the mist is still there.
I have a basemap in the bottom layer and this should stay unchanged.
I annotate on the top layer. I want the top layer to be transparent except for where I specifically draw on the canvas. If I call top_layer.Bitmap.AlphaChannel.Fill( 0 ) then I understand that all pixels in the top layer become transparent and nothing drawn on the top layer will be seen in the corresponding TImageENView component which contains the layers.
In order to achieve the effect I am after do I then also need to draw in the alpha channel? Is there an automatic way to update the alpha values to 1.0 (255) when drawing to the top layer's regular bitmap canvas? I have searched the documentation but can find nothing that seems to apply. The Operation property does not have a mode, as far as I can see, which does this. The IsMask property does seem to be relevant but I still need to draw on two separate canvases to get my desired effect.
Thank you.
Regards, Arnstein |
w2m |
Posted - Feb 06 2015 : 16:31:58 You can not set the layers transparency to control opacity this way because everything in the layer including the canvas painting will be set to the level you set it at...
To use transparent layers try this:
ImageEnView1.SelectionOptions := ImageEnView1.SelectionOptions +
[iesoSelectTranspLayers];
{ Render a transparent layer }
iWidth := ImageEnView1.IEBitmap.Width;
iHeight := ImageEnView1.IEBitmap.Height;
ImageEnView1.Layers[iLayer].Bitmap.IEInitialize(iWidth, iHeight,
clBlack, True);
IEInitialize is in the iexHelperFunctions unit.
You can also look at the Glyph Maker Demo and Make New Bitmap Transparent Demo here: http://www.xecute.com/ieforum/topic.asp?TOPIC_ID=1446
Bill Miller Adirondack Software & Graphics Email: w2m@hughes.net EBook: http://www.imageen.com/ebook/ Custom Commercial ImageEn Development |
|
|