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
 The drawing of transparent images...
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

bmesser

United Kingdom
234 Posts

Posted - Aug 12 2014 :  06:45:58  Show Profile  Reply
Hi

What I would like to do is to draw a transparent PNG on a ImageEnView component displaying a map (TIESippyMap). I can see in the map demo that this is done in a fairly complex way for the "map pin".

What I have is a lot of weather symbols I would like to overlay on a map, the symbols are small 40x40 PNG images with transparency. I have no problem overlaying BMP with RenderToTBitmapEx, but of course there is no transparency, what I would like to do is the same but with transparent PNG's.

I can see there is a procedure called RenderToCanvasWithAlpha but I can't manage to get the parameters correct, let alone find out how to load the PNG in the first place.

I have a lot of these small images for each weather type, and ideally it would be great if you could assign them straight from an TImagelist, but I suspect that this wouldn't be possible.

Any help would be appreciated

Bruce.

w2m

USA
1990 Posts

Posted - Aug 12 2014 :  09:02:35  Show Profile  Reply
I had a lot of trouble getting the bitmaps from the imagelist to be transparent, but I managed to get this to work. There probably is a better way to do this but for now this works. This draws the weather symbols at the top of the right side screen in the backbuffer so the images do not become part of the map bitmap.

Yes... it would be nice if they wrote an overloaded method of RenderToCanvasWithAlpha that was simpler to use.

What I do not understand is if you remark with TIEBitmap.Create(iBitmap, Rect(0, 0, 32, 32)) do... no bitmaps are drawn at all, even though the TIEBitmap is not used. In this case, iImageEnView.ieBitmap.RenderToTBitmapEx is used instead. Boy... this may be an example of why not to use with construction! Can anyone explain this?


For this test the images in the imagelist are 32x32 transparent png images. For larger bitmaps you would have to adjust this a little.

I used the GeoMaps demo to do this:
procedure TMainForm.ImageEnView1DrawBackBuffer(Sender: TObject);
var
  i: Integer;
  iImageEnView: TImageEnView;
  idx: Integer;
  lat, lon: double;
  X, Y: Integer;
  iBitmap: TBitmap;
  iIEBitmap: TIEBitmap;
  iX: Integer;
  iY: Integer;
  iRGB: TRGB;
begin
  { Draw Weather Symbols }
  Screen.Cursor := crHourGlass;
  try
    iX := 540;
    iY := 32;
    iImageEnView := TImageEnView.Create(nil);
    try
      for i := 0 to ImageList1.Count - 1 do
      begin
        iBitmap := TBitmap.Create;
        try
          iBitmap.Width := 32;
          iBitmap.Height := 32;
          if ImageList1.GetBitmap(i, iBitmap) then
          begin
            with TIEBitmap.Create(iBitmap, Rect(0, 0, 32, 32)) do
            begin
              iBitmap.PixelFormat := pf24bit;
              iImageEnView.Bitmap.Assign(iBitmap);
              iImageEnView.Update;
              iImageEnView.ieBitmap.PixelFormat := ie32RGB;
              iRGB := iImageEnView.ieBitmap.Pixels
                [0, iImageEnView.ieBitmap.Height - 1];
              iImageEnView.Proc.SetTransparentColors(iRGB, iRGB, 0);
              iImageEnView.ieBitmap.RenderToTBitmapEx(ImageEnView1.BackBuffer,
                iX, iY, 32, 32, 0, 0, Width, Height, 255, rfNone);
              iX := iX + 48;
              Free;
            end;
          end;
        finally
          iBitmap.Free;
        end;
      end;
    finally
      iImageEnView.Free;
    end;
  finally
    Screen.Cursor := crdefault;
  end;

  { Draw Map Symbols }
  for i := 0 to ImageEnMView1.MultiSelectedImagesCount - 1 do
  begin
    idx := ImageEnMView1.MultiSelectedImages[i];
    lat := ImageEnMView1.MIO.Params[idx].EXIF_GPSLatitude;
    lon := ImageEnMView1.MIO.Params[idx].EXIF_GPSLongitude;
    X := map.LongitudeToBmpX(lon);
    Y := map.LatitudeToBmpY(lat);
    with TIEBitmap.Create(@marker[0], marker_Size) do
    begin
      RenderToTBitmapEx(ImageEnView1.BackBuffer, X - marker_spot_x,
        Y - marker_spot_y, 64, 64, 0, 0, Width, Height, 255, rfNone);
      Free();
    end;
  end;
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

bmesser

United Kingdom
234 Posts

Posted - Aug 12 2014 :  11:02:56  Show Profile  Reply
Bill

I'm very grateful to you for that, it works fine!

Adding a transparent BMP or PNG from a TImageList to an existing TImageENView component must be a common enough thing to want to do, I just wonder if it could be done a lot more efficiently and less complex with some kind of helper function to wrap all the steps into.

Bruce.


Go to Top of Page

w2m

USA
1990 Posts

Posted - Aug 12 2014 :  13:16:07  Show Profile  Reply
I agree. Maybe Nigel will have some ideas as well.

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

w2m

USA
1990 Posts

Posted - Aug 12 2014 :  14:01:32  Show Profile  Reply
Bruce,

I managed to reduce the complexity somewhat. This is about simple as I can make it:
procedure TForm1.ImageEnView1DrawBackBuffer(Sender: TObject);
var
  i: integer;
  iImageEnView: TImageEnView;
  iBitmap: TBitmap;
  iX: integer;
  iY: integer;
  iRGB: TRGB;
begin
  { Draw Weather Symbols }
  iX := ImageEnView1.Width - 150;
  iY := 32;
  iImageEnView := TImageEnView.Create(nil);
  try
    for i := 0 to ImageList1.Count - 1 do
    begin
      iBitmap := TBitmap.Create;
      try
        iBitmap.Width := 32;
        iBitmap.Height := 32;
        if ImageList1.GetBitmap(i, iBitmap) then
        begin
          iBitmap.PixelFormat := pf24bit;
          iImageEnView.Bitmap.Assign(iBitmap);
          iRGB := iImageEnView.IEBitmap.Pixels
            [0, iImageEnView.IEBitmap.Height - 1];
          iImageEnView.Proc.SetTransparentColors(iRGB, iRGB, 0);
          iImageEnView.IEBitmap.RenderToTBitmapEx(ImageEnView1.BackBuffer, iX,
            iY, 32, 32, 0, 0, iImageEnView.Bitmap.Width,
            iImageEnView.Bitmap.Height, 255, rfNone);
          iX := iX + 48;
        end;
      finally
        iBitmap.Free;
      end;
    end;
  finally
    iImageEnView.Free;
  end;
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

xequte

39053 Posts

Posted - Aug 21 2014 :  00:58:48  Show Profile  Reply
@Bill

FYI, next release will feature TIEBitmap.DrawToCanvasWithAlpha

A simplified version of RenderCanvasWithAlpha.


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

bmesser

United Kingdom
234 Posts

Posted - Aug 21 2014 :  01:52:27  Show Profile  Reply
Great news Nigel, and will help no end when using TIEslippyMap!
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: