GUI: statusbar TImage drawobjects

Hi,

I have a problem with getting the right information on the statusbar while at the same time accessing some useful canvas commands by right-click on it.

I have attached a modified version of the statusBar.C tutorial
http://root.cern.ch/root/html/tutorials/gui/statusBar.C.html
to illustrate my question.

If you click the added “Draw Image” button and move the mouse pointer over the image, the pixel coordinates will be displayed in the status bar at the far right. Nice. In my actual application I even get the pixel value which I really do like to have an eye on.

Now, if you click “Draw line” a TLine will be added (could be any other draw object) and now you get the canvas coordinates in that far right status bar and not the pixel values anymore. Not so nice.

I’ve tried many things to get them back, the only thing that works, is to draw the image another time after the line has been drawn (commented out in the example). But then the image is in the foreground and I can not access the canvas by right-clicking and, e.g. can’t save the canvas including image and line. It is important for me to have no margins around the image.

So how can I achieve seeing the canvas with image and line and all, see all the pixel values on the statusbar and yet still do a nice right-click “Save as” for the whole thing?

Cheers
statusBar_mod.C (5.37 KB)

Hi,

I think there is no solution to this issue, but maybe our graphics specialist will have a solution I’m not aware of. But he’s on holidays right now, so I’ll remind him to take a look at this issue when back.

Cheers, Bertrand.

I am back. I’ll check this asap.

I think that when you draw a TLine the user’s coordinates are defined and they are the preferred ones to be shown in the status bar. A picture is drawn alone in the Pad there is no user’s coordinates defined and only the pixels are available. May be if you draw your line using img->DrawLine(…) like in $ROOTSYS/tutorials/image/rose_image.C it will work as expected. But may be that’s not a great help for you if the object you want to draw is an histogram or something like that.

When I do that, the pixel coordinates are indeed displayed correctly. In fact, it also solves another issue I had wrt to zooming the objects together with the image. Very nice.

Now, however, more questions are being raised:

  1. First of all, the pixel value is only being displayed on the statusbar for the image without additional objects (see attached image pixval.png). As soon as I add them to the image I only get the coordinates on the statusbar, but no pixel value (see attached image nopixval.png). I’m using a custom grey palette - maybe the green cirlce conflicts with that somehow???

  2. The y-coordinate for the img->DrawCircle(…) is exactly opposite to the image y-coordinate. Easy to fix but surprising.

  3. If I use img->DrawCircle(…) on its own I get a segmentation violation, if I use img->DrawLine(…) beforehand, everything works fine. You can see what I mean by using the attached modified statusbar example and commenting out line 99. (In my gui I’m secretly drawing a black 1-pixel line on the upper left corner that nobody will notice, see nopixval.png. Works, but why is it necessary in the first place?)
    statusBar_mod.C (5.54 KB)




The image Drawing primitives are a kind of separated package and have their own logic.

TImageDump::DrawPolyMarker use DrawCircle to draw markers. See the code. It needs a
fImage->BeginPaint();
have you done that ?

Ok, almost there.

“fImage->BeginPaint();” helped, but now something is missing to make the stretching out of the image (“fImage->SetConstRatio(kFALSE);”) and “fImage->DrawCircle(…);” work together.
The following code is from the attached example file.

1    TImage *fImg2 = (TImage*)fImg->Clone("fImg2");
2    fImg2->BeginPaint();
3    fImg2->DrawCircle(50, 50, 10, "#00FF00", 1);
4    fImg2->SetConstRatio(kFALSE);
5    fImg2->Draw();
6    fEcan->GetCanvas()->Update();
7
8    //fImg2->SetConstRatio(kFALSE);
9    //fImg2->Draw();
10  //fEcan->GetCanvas()->Update();

If you run it like that, the circle won’t be displayed, but if you right-click on the image and click “SetConstRatio” it will appear, so somehow in the background the commands must have been executed.

If you comment out either line 3 or 4, the other command will work fine on its own.
Commenting out line 4 and uncommenting lines 8-10 will in the end produce a stretched out image with circle but you get an ugly wobble (try clicking the button several times). In my application I do replace the images a lot, so the wobble is quite annoying.

Is there a way to get there without the wobble?
statusBar_mod.C (5.41 KB)

Hi,

editing my last post went unnoticed. I still can’t figure out how to get the drawing and stretching out of the image processed properly. Any ideas?

Thanks,
Greg

PS: I suggest that the date of a post is changed according to when it’s been last edited, so that the thread moves up in the list again…

editing my last post went unnoticed. I still can't figure out how to get the drawing and stretching out of the image processed properly. Any ideas?

Yes, always make new posts … I am looking now

May be I am missing something but I do not see the “wobble” …

When you click “DrawCircle” - you do get the image fit to the whole canvas WITH a green circle on the upper right corner ???

If I run the code as uploaded a couple of post earlier, I only get the image without circle.

If I comment out line 4 ( fImg2->SetConstRatio(kFALSE) ) I get the image incl. circle but not fit to canvas.

If I then uncomment lines 8-10 I get image + circle fit to canvas, but the multiple call of fEcan->GetCanvas()->Update() causes the wobble, particularly, if you click “DrawCircle” several times or, like in my case, browse a whole series of images. So, none of the three solutions is satisfactory.

But if it works on your machine straightaway without wobble, that’s even more puzzling to me.

Btw, if I place

fImg->BeginPaint();
fImg->DrawCircle(50, 50, 10, "#00FF00", 1);

for the original image in function DoDrawImage(), it works fine. So, maybe the problem is with the creation of a clone image ( fImg->Clone(“fImg2”) ) in function DoDrawCirlce(). The point of the two buttons is, of course, to be able to swap the original and the modified image as you wish.

Ah ok… I Have now:

void MyMainFrame::DoDrawCircle()
{
  DoDrawImage();
 
  TImage *fImg2 = (TImage*)fImg->Clone("fImg2");
  fImg2->BeginPaint();
  fImg2->DrawCircle(50, 50, 10, "#00FF00", 1);
//  fImg2->SetConstRatio(kFALSE);
  fImg2->Draw();
  fEcan->GetCanvas()->Update();
 
  fImg2->SetConstRatio(kFALSE);
  fImg2->Draw();
  fEcan->GetCanvas()->Update();
}

And the image “jumps” each time you click on the button… that what you call wobble ?
Is the final image correct ?

Exactly. The jumping is what I’m talking about. Sorry, I tried not to be too confusing…

And… is the final image correct ?

Yes.

Ok … trying to find a solution … yet nothing … :frowning:

I tried tu put a text but still it appears only when I rescale the canavs.
I do not understand because it is working in:
tutorials/image/rose_image.C
:frowning: still checking

Based on the tutorial example I made this small example which is working for me:

{
   TImage *img = TImage::Open("rose512.jpg");

   if (!img) {
      printf("Could not create an image... exit\n");
      return;
   }

   img->SetConstRatio(0);
   img->SetImageQuality(TAttImage::kImgBest);

   TString fp = gEnv->GetValue("Root.TTFontPath", "");
   TString bc = fp + "/BlackChancery.ttf";
   TString ar = fp + "/arial.ttf";

   // draw text over image with funny font
   img->DrawText(120, 160, "Hello World!", 32, 
                 gROOT->GetColor(4)->AsHexString(), 
                 bc, TImage::kShadeBelow);
   img->BeginPaint();
   img->DrawCircle(50, 50, 10, "#00FF00", 1);

   c1 = new TCanvas("c1", "c1", 500, 500);

   img->Draw("xxx");
}

Ok, I have implemented your code snippet in the statusBar_mod.C example and simply made the text an empty string as I don’t want any text. That works. Thanks!

Just one more question out of curiosity, why do I need the text after all? Try commenting out the “fImg2->DrawText…” line below and the circle will disappear again into the nothingness from whence it came. So, I apparently I need some funny empty text field if I actually want a cirlce?!? :confused:

void MyMainFrame::DoDrawCircle()
{
  DoDrawImage();

  TImage *fImg2 = (TImage*)fImg->Clone("fImg2");

  fImg2->SetConstRatio(kFALSE);
  fImg2->SetImageQuality(TAttImage::kImgBest);

  TString fp = gEnv->GetValue("Root.TTFontPath", "");
  TString bc = fp + "/BlackChancery.ttf";
  fImg2->DrawText(120, 160, "", 32, gROOT->GetColor(4)->AsHexString(), bc, TImage::kShadeBelow);
  fImg2->BeginPaint();
  fImg2->DrawCircle(50, 50, 10, "#00FF00", 1);

  fImg2->Draw();
  fEcan->GetCanvas()->Update();
}

You do not need the text. This one also works:

[code]{
TImage *img = TImage::Open(“rose512.jpg”);

if (!img) {
printf(“Could not create an image… exit\n”);
return;
}

img->SetConstRatio(0);
img->SetImageQuality(TAttImage::kImgBest);

img->BeginPaint();
img->DrawCircle(50, 50, 10, “#00FF00”, 1);

c1 = new TCanvas(“c1”, “c1”, 500, 500);

img->Draw(“xxx”);
}
[/code]