Author |
Topic  |
|
bmesser
  
United Kingdom
234 Posts |
Posted - Aug 12 2014 : 06:45:58
|
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
|
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 |
 |
|
bmesser
  
United Kingdom
234 Posts |
Posted - Aug 12 2014 : 11:02:56
|
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.
 |
 |
|
w2m
   
USA
1990 Posts |
Posted - Aug 12 2014 : 13:16:07
|
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 |
 |
|
w2m
   
USA
1990 Posts |
Posted - Aug 12 2014 : 14:01:32
|
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 |
 |
|
xequte
    
39053 Posts |
Posted - Aug 21 2014 : 00:58:48
|
@Bill
FYI, next release will feature TIEBitmap.DrawToCanvasWithAlpha
A simplified version of RenderCanvasWithAlpha.
Nigel Xequte Software www.xequte.com nigel@xequte.com
|
 |
|
bmesser
  
United Kingdom
234 Posts |
Posted - Aug 21 2014 : 01:52:27
|
Great news Nigel, and will help no end when using TIEslippyMap! |
 |
|
|
Topic  |
|
|
|