ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Layer transparency
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

quack

3 Posts

Posted - Feb 06 2015 :  00:23:06  Show Profile  Reply
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

w2m

USA
1990 Posts

Posted - Feb 06 2015 :  16:31:58  Show Profile  Reply
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
Go to Top of Page

quack

3 Posts

Posted - Feb 07 2015 :  20:02:11  Show Profile  Reply
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
Go to Top of Page

quack

3 Posts

Posted - Feb 07 2015 :  20:48:41  Show Profile  Reply
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.
Go to Top of Page

w2m

USA
1990 Posts

Posted - Feb 08 2015 :  08:01:48  Show Profile  Reply
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
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: