Author |
Topic |
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 11 2022 : 12:35:30
|
Hi
I've now moved on I'm happily stretch drawing a transparent PNG over the top of a slippy map.
I would now like to detect the RGB color values the mouse pointer is over on a mouse move event for the pixels of the PNG that I've overlaid.
It looks like I can do that for any colors in the virtual map but the values aren't returned when I take the mouse pointer in the non-transparent color of the PNG.
Is there anyway I can detect the colours of the PNG that I've overlaid using stretch draw?
Bruce. |
|
xequte
38608 Posts |
Posted - Sep 11 2022 : 17:43:36
|
Hi Bruce
I'm sorry, I'd need to see the code you are using. Or send me a very simple demo.
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 12 2022 : 08:26:03
|
This is a shortened form of the code that I'm using.
radar:=TPNGImage.Create;
radar.LoadFromFile(GetPath(dt));
//------------------------------------------------------------------------------------------------------------------------------
procedure TfmMain.ImageDrawCanvas(Sender: TObject; ACanvas: TCanvas; ARect: TRect);
var
x : integer;
y : integer;
x1 : integer;
y1 : integer;
begin
with ACanvas do
begin
y :=map.LatitudeToBmpY(60);
y1 :=map.LatitudeToBmpY(45);
x :=map.LongitudeToBmpX(-10);
x1 :=map.LongitudeToBmpX(10);
ACanvas.StretchDraw(rect(x,y,x1,y1),radar);
end;
end;
//------------------------------------------------------------------------------------------------------------------------------
procedure TfmMain.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
x1 : integer;
y1 : integer;
begin
x1:=Image.Layers[0].ConvXScr2Bmp(X);
y1:=Image.Layers[0].ConvYScr2Bmp(Y);
if ((x1>=0) and (x1<Image.Layers[0].Bitmap.Width)) and ((y1>=0) and (y1<Image.Layers[0].Bitmap.Height)) then
FrainIntensity:=LookUpColor(Image.Layers[0].Bitmap.Pixels_ie24RGB[x1,y1])
else
FRainIntensity:='';
StatusBar.Panels[5].Text:=FrainIntensity;
end;
//------------------------------------------------------------------------------------------------------------------------------
function TfmMain.LookUpColor(col: TRGB): string;
begin
result:='';
if EqualRGB(col,c1) then
result:='0.01-0.5'
else if EqualRGB(col,c2) then
result:='0.5-1.0'
else if EqualRGB(col,c3) then
result:='1-2'
else if EqualRGB(col,c4) then
result:='2-4'
else if EqualRGB(col,c5) then
result:='4-8'
else if EqualRGB(col,c6) then
result:='8-16'
else if EqualRGB(col,c7) then
result:='16-32'
else if EqualRGB(col,c8) then
result:='>32';
if result<>'' then
result:=Format('%s mm/hr',[result]);
end;
//------------------------------------------------------------------------------------------------------------------------------
|
|
|
xequte
38608 Posts |
Posted - Sep 12 2022 : 15:36:54
|
OK, that all looks good. Are you saying that where you have drawn the radar you're not getting the value you want?
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 13 2022 : 06:23:59
|
What I get when I access the pixel from the bitmap using layer[0] is the colors that make up map from the virtual bitmap and not the PNG I have stretched drawn on top of that map. Maybe if I could add an overlay and then shoe horn the PNG into that I could!
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 13 2022 : 06:26:36
|
The term "radar" could be a bit misleading that the name I've given the PNG image I stretch draw. I draw the concentric circles around Strathpeffer on the Canvas Draw event isn't the problem! |
|
|
xequte
38608 Posts |
Posted - Sep 13 2022 : 16:40:08
|
I see. The reasons is that you are only drawing the radar onto the canvas of control, not actually modifying the bitmap, so the calls to Bitmap.Pixels_ie24RGB[] do not return them.
Some options:
1. You know the position of your radar bitmap, so your mouse move could first map the position to the radar bitmap, look up the value there, and fall back to the main bitmap if necessary
2. You could draw the radar to the back buffer (see this method in the GeoMaps demo) and then get your color value from that
3. You could use the AfterDrawLayer() event to draw your radar to the rendered bitmap
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 16 2022 : 02:51:49
|
Thanks Nigel I'll try out your suggestions. Thanks a lot. |
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 16 2022 : 03:41:01
|
I tried the drawing to the back buffer, but to do this I would have to create a TIEBitmap out of the transparent PNG radar image to render it. Is there any way of doing this? |
|
|
xequte
38608 Posts |
Posted - Sep 16 2022 : 05:28:09
|
Sure. How is the PNG stored in the app? As a resource?
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 18 2022 : 04:45:43
|
radar:=TPNGImage.Create;
procedure TfmMain.ImageDrawCanvas(Sender: TObject; ACanvas: TCanvas; ARect: TRect);
var
path : string;
url : string;
x,x1,y,y1 : integer;
begin
path:='C:\Temp\radar.png';
url:='https://maps.ci.consumer-digital.api.metoffice.gov.uk/wms_ob/single/high-res/rainfall_radar/2022-09-18T08:35:00Z.png';
if UrlDownloadToFile(nil,PChar(url),PChar(path),0,nil)=0 then
begin
radar.LoadFromFile(path);
y :=map.LatitudeToBmpY(65);
y1 :=map.LatitudeToBmpY(45);
x :=map.LongitudeToBmpX(-20);
x1 :=map.LongitudeToBmpX(10);
ACanvas.StretchDraw(rect(x,y,x1,y1),radar);
end;
end; Hi Nigel
I download and save the PNG and then reload them into a TPNGImage to display them as required.
I can't use Image.IO.LoadFromURL(url) method to download the PNG because it doesn't work.
Bruce.
|
|
|
xequte
38608 Posts |
|
bmesser
United Kingdom
224 Posts |
|
xequte
38608 Posts |
Posted - Sep 22 2022 : 18:09:51
|
Hi
LoadFromURL() only works by downloading an image file directly. You should use UrlDownloadToFile() to download to a temporary file, and then load using LoadFromFile().
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 23 2022 : 07:57:02
|
Nigel
Yes, I do both the download and the saving in a "one-er" using UrlDownloadToFile.
That's not the problem I'm having.
Once I've downloaded the file I then open it as a PNG and overlay it on top of the slippy map using ACanvas.StretchDraw(rect(x,y,x1,y1),radar) .
The problem is that when I move the mouse over the map with the overlay, I can only access the pixels of the slippy map, and not those of the transparent radar image, which is color coded to display the rainfall intensity which I would like to access.
Bruce. |
|
|
xequte
38608 Posts |
Posted - Sep 23 2022 : 17:49:16
|
Hi Bruce
Yes, because your call to ACanvas.StretchDraw() is only drawing to the control canvas, not the image canvas. Because it's virtual, drawing to the image canvas would not be valid anyway.
I think you should use method #1 above. For position x,y, calculate if it is over your PNG overlay. If it is, read the pixel color from the png. If the pixel is transparent, or not over the png, then fall back to reading the color from the map.
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Sep 27 2022 : 14:16:11
|
Hi Nigel
"For position x,y, calculate if it is over your PNG overlay"
Adding a PNG overlay is the the nub of the problem.
As soon as I add a layer to the canvas of a slippymap TImageEnView component - I lose the map!
Even if I didn't lose the map, is it possible to stretch draw a PNG image to a layer I've added?
I've tried to do it without any luck.
Bruce.
|
|
|
xequte
38608 Posts |
Posted - Sep 27 2022 : 21:58:29
|
Hi Bruce
Have you seen the code in the GeoMaps demo to draw markers (using a transparent PNG resource):
procedure TMainForm.ImageEnView1DrawBackBuffer(Sender: TObject);
var
i: integer;
idx: integer;
lat, lon: double;
x, y: integer;
begin
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;
Nigel Xequte Software www.imageen.com
|
|
|
bmesser
United Kingdom
224 Posts |
Posted - Oct 04 2022 : 10:03:42
|
If I can get this method to work will it allow me to access the pixel values of the PNG though and not just that of the virtual slippymap? |
|
|
xequte
38608 Posts |
Posted - Oct 04 2022 : 15:24:51
|
You might be able to read them from the backbuffer, but there are risks to doing it that way, whereas the method I recommended earlier has no such risks.
Nigel Xequte Software www.imageen.com
|
|
|
|
Topic |
|