Image labels with TImage

I have a question about the TImage class of Root. How can I place labels on data images without changing the image itself? I tried two ways, but neither works right.

  1. The DrawText and DrawCircle methods of TImage work fine, but they change data images into non-data images and the palette bar disappears. I really need to display the palette bar. Also, I do not like to permanently change the image.

  2. If I work with the TText class, I can add labels, but I am not in control of where they appear in the image. It’s important that the label appears at specified image coordinates. Otherwise the position of the label depends on the screen resolution and is not reliable.

The background of my question is that I work with maps and the labels need to appear at the right place.

Any suggestions are greatly appreciated.

Thanks,
Sibylle

Can you send me a small example showing what you already achieved ?

I am working now with option 2, using the TText class, and it looks like this:

 TText* t = new TText(0.67,0.27,"London");
 t->SetTextColor(kWhite);
 t->SetTextSize(0.035);
 t->Draw();

These coordinates, however, are relative coordinates. I would rather like to use the absolute pixel coordinates as they appear in TImage, but I am not aware how to do that. The label options offered in the TImage class always destroy the palette bar, which is crucial for my application.

I have attached a snapshot of how the picture is supposed to look like. In this particular example it’s fine, but when I change computers, it’s not working anymore due to different screen resolutions. The labels don’t appear at the right spot.

Thanks for any suggestions,
Sibylle


Hi Sibylle,
nice gui! :smiley:

TASImage internally can be in three states

  1. in memory compressed array. This is the case when image is loaded first time from
    some image file, e.g. PNG, GIF etc. This is done for minimizing of memory usage.

  2. uncompressed array of ARGB (8bits of Alfa(transparency), Red, Green, Blue) values.
    This is the case when any vector graphics method is applied to the image.
    This is done for fast drawing.

  3. “vectorized” image. A “vectorized” image contains an array of doubles
    presenting image pixel colors as “double values” and
    palette which defines conversion from double value into ARGB value.
    This is the case when palette bar is drawn and palette editor is available.
    To make an image to be “vectorized” the
    root.cern.ch/root/htmldoc/TASIma … :Vectorize
    can be applied.

I would recommend for you:

  1. draw labels with TImage::DrawText method in pixel coordinate system
  2. when apply the TImage::Vectorize method to create palette bar.

Hi Valeriy,

my image is originally vectorized, i.e. it contains an array of doubles. It seems complicated to me that, by adding a label, I first convert the image to a ARGB non-data image, and then I have to convert it back to a vectorized image. Isn’t there a more elegant way dealing with data images? Also who guarantees that I really get the same data values back in my derived image?

Thanks,
Sibylle

Hi Sibylle,
OK, I see.
your solution

is the right way to do.
As far as I understood, your qestion is “how to convert
relative coordinates into pixel coordinates” (correct?).

Regards. Valeriy

Hi Valeriy,

yes, that’s right. TText with relative coordinates is still not the right solution. When I change computers, the labels do not appear at the same position. Is there a way to make TText understand the pixel coordinates of TImage?

Sibylle

from relative coordinates to pixel coordinates
root.cern.ch/root/htmldoc/TPad.h … toAbsPixel
root.cern.ch/root/htmldoc/TPad.h … toAbsPixel

from pixel coordinates to relative coordinates
root.cern.ch/root/htmldoc/TPad.h … bsPixeltoX
root.cern.ch/root/htmldoc/TPad.h … bsPixeltoY

btw, not clear for me the difference between AbsPixeltoX and PixeltoX methods :cry:
(Olivier must know this better)

Hi Valeriy,

how woud I access the TPad? I am working with an embedded canvas. This is the code how I draw my image:

void MainFrame::DrawImage(TRootEmbeddedCanvas *canvas)
{
// Fill and Draw Data Image

TCanvas *c1 = canvas->GetCanvas();
c1->cd();
c1->Clear();

TImage *img = TImage::Create();
img->SetImage(fImageArray, Ncolumns, Nlines, 0);

img->Draw();

How do I access the TPad here?

Sibylle

use gPad

It depends if you want to convert relatively to the pad coordinates or canavs coordinates. (see p 103 of the root manual) in this particular case they should give the same result. Just try them and you will see the difference.

Honestly, I am afraid this won’t really solve my problem. I would really like to work in TImage coordinates, and not in canvas or pad coordinates. Otherwise there is always room for error when changing computers.

Isn’t it possible to upgrade the Draw methods in TImage such that data images remain data images? There could be an option whether or not the user wants to convert to a non-data image. This option would allow the user to specify whether the label is permanent (with conversion) or transient (without conversion). Is it possible to ask for some code improvements here?

Thanks,
Sibylle

Hi Sibylle, it’s discussible.
However, not clear for me, why using gPad->PixeltoX etc. methods

Do you have some problems with it?

Possibly good solution would be to add one more constructor for TText class,
which creates TText object in pixel coordinates.
However, not clear the case of the batch mode.

Regards. Valeriy

No, it does not work. Neither with gPad->PixeltoX nor with gPad->AbsPixeltoX. I am not getting the pixel coordinates of the image as defined in TImage. These are some other pixel coordinates.

Sibylle

it might be, you need to correct coordinates values by TStyle::GetScreenFactor

Hi Sibylle,
what is your display screen resolution (780x640, 1024x768 …)?
Starting from next week I’ll work for ROOT full time (for some period).
Hopefully, Olivier and me will find the best solution for this problem.
This case is very common. So, it’s important to solve it.
Keep in touch. :slight_smile:

Regards. Valeriy