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
 Accessing Pixel values
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

bmesser

United Kingdom
221 Posts

Posted - Sep 11 2022 :  12:35:30  Show Profile  Reply
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

7215 Posts

Posted - Sep 11 2022 :  17:43:36  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 12 2022 :  08:26:03  Show Profile  Reply
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;
//------------------------------------------------------------------------------------------------------------------------------



Go to Top of Page

xequte

7215 Posts

Posted - Sep 12 2022 :  15:36:54  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 13 2022 :  06:23:59  Show Profile  Reply
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!
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 13 2022 :  06:26:36  Show Profile  Reply
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!
Go to Top of Page

xequte

7215 Posts

Posted - Sep 13 2022 :  16:40:08  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 16 2022 :  02:51:49  Show Profile  Reply
Thanks Nigel
I'll try out your suggestions.
Thanks a lot.
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 16 2022 :  03:41:01  Show Profile  Reply
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?
Go to Top of Page

xequte

7215 Posts

Posted - Sep 16 2022 :  05:28:09  Show Profile  Reply
Sure. How is the PNG stored in the app? As a resource?

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 18 2022 :  04:45:43  Show Profile  Reply
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.
Go to Top of Page

xequte

7215 Posts

Posted - Sep 20 2022 :  21:18:40  Show Profile  Reply
Hi Bruce

I just opened this link in a browser. It does not point to a PNG file:

https://maps.ci.consumer-digital.api.metoffice.gov.uk/wms_ob/single/high-res/rainfall_radar/2022-09-18T08:35:00Z.png

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 22 2022 :  11:17:09  Show Profile  Reply
It won't.

You have to grab it using the Windows function:-

UrlDownloadToFile(nil,PChar(url),PChar(path),0,nil).


Here's one I've downloaded.

attach/bmesser/2022922111614_2022-09-18-0925.png
Go to Top of Page

xequte

7215 Posts

Posted - Sep 22 2022 :  18:09:51  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 23 2022 :  07:57:02  Show Profile  Reply
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.
Go to Top of Page

xequte

7215 Posts

Posted - Sep 23 2022 :  17:49:16  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Sep 27 2022 :  14:16:11  Show Profile  Reply
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.
Go to Top of Page

xequte

7215 Posts

Posted - Sep 27 2022 :  21:58:29  Show Profile  Reply
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
Go to Top of Page

bmesser

United Kingdom
221 Posts

Posted - Oct 04 2022 :  10:03:42  Show Profile  Reply
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?
Go to Top of Page

xequte

7215 Posts

Posted - Oct 04 2022 :  15:24:51  Show Profile  Reply
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
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: