Home | News | Documentation | Download

SaveAs png and specify printing resolution

I’d like to save my canvases as .png at high resolution but don’t want to adjust the size of the canvas as it displays on my screen. How would one go about saving a non-vector image at higher-than-displayed resolution?

Create a large canvas in batch mode and print.

Well, you could also print your canvas using any vector format (".eps" or “.pdf”) and then use an external utility (provided by your system, e.g. ImageMagick) to “convert” graphics format into a “.png”.
If you get problems with “anti-aliasing”, see: Colored 2D histograms in pdf output

Thanks for the input, couet, but I’m thinking along the lines of I’m interactively playing with data and make a great plot, hand place some labels, etc., and then want to save it as a .png with a recent resolution.

Pepe Le Pew, it would seem based on couet’s solution that your suggestion may be the only work around for interactive plots. I’ll write a custom macro that saves my file as a pdf, makes a system call to convert to a png, then deletes the pdf. If/when I do, I’ll post it back here for others that may want it. Thanks for the suggestions.

The problem I’m encountering is that I’m attempting to save copies of scatter plots with millions of data points. Vector formats are a pain to save and re-render as a .png.

The good news is that some more searching found this post (from last year): Canvas scaling when saving

I took a stab at implementing it. It works. I attempted to implement some marker scaling so they are actually visible in the large scale plot… but it does not affect the marker size. I guess I would need to loop through all of the primitives in the canvas and set them that way. In the mean time setting the marker style/size of the scatter plot before running the function works just fine but be prepared for some serious slow down.

void MSaveBigPNG(TString filename="", double scale=5) {
    TCanvas* old_canv = gPad->GetCanvas();

    gROOT->SetBatch(kTRUE);
    gROOT->ForceStyle(kTRUE);

    Int_t orig_msz = gStyle->GetMarkerSize();
    Int_t orig_mst = gStyle->GetMarkerStyle();
    Int_t orig_lt  = gStyle->GetLineWidth();

    gStyle->SetMarkerSize(1.0+scale/5);
    gStyle->SetMarkerStyle(20);
    gStyle->SetLineWidth(orig_lt*scale);

    if(filename = "") {
        filename = old_canv->GetName();
        filename += ".png";
    }

    Int_t old_width  = old_canv->GetWindowWidth();
    Int_t old_height = old_canv->GetWindowHeight();

    Int_t new_width = old_width * scale;
    Int_t new_height= old_height* scale;

    TCanvas* temp_canvas = new TCanvas("temp", "", new_width, new_height);
    old_canv->DrawClonePad();

    temp_canvas->Draw();
    temp_canvas->SaveAs(filename);
    temp_canvas->Close();

    gStyle->SetMarkerSize(orig_msz);
    gStyle->SetMarkerStyle(orig_mst);
    gStyle->SetLineWidth(orig_lt);

    gROOT->ForceStyle(kFALSE);
    gROOT->SetBatch(kFALSE);

    return;
}

You can make a small macro which: enter the batch mode, open a big canvas, draw the image, print the canvas, close it, and exit batch mode.

:slight_smile: at least i always give the same answer to this question :slight_smile:

Hi,
has there been any change in ROOT concerning this feature? Is it possible to change the PNG quality meanwhile by tweaking some parameter? If not, could this be implemented in a next version of ROOT? It really is a pain to having to loop over all Primitives again, filtering out the values that have to be scaled and then do all changes correctly.

Or is there anyone around who could post a working example?

Cheers,
Ben

Yes there are news:

   gStyle->SetImageScaling(3.);

It is used to generate hight def pictures for the ref guide. See the pictures in the ref-guide. They are now all high def.

2 Likes

Great thanks, this feature works.

However, it also makes lines more thinner. Is there a way to avoid that?

No image scaling:

Image Scaling of 3:

No. You will need to increase the line width before printing. Usually it makes the picture looks cleaner. See the reference guide.

I have not been able to get SetImageScaling to work properly. I don’t know if it’s a strange combination of working in batch mode or not, which version of ROOT, what format I’m saving to, or what.

Can you modify the following code (pad2png.C from the tutorial) to save in a high-resolution format? I can’t save anything better than 72 dpi.

void pad2png()
{
   TCanvas *c = new TCanvas;
   TH1F *h = new TH1F("gaus", "gaus", 100, -5, 5);
   h->FillRandom("gaus", 10000);
   h->Draw();

   gSystem->ProcessEvents();

   TImage *img = TImage::Create();

   img->FromPad(c);

   img->WriteImage("canvas.png");
}

it does not change the dpi. It applies a scale factor to the image which is saved bigger than the canvas size. You can then scale down the image in the web site you want to display it. That’s what we do in the ROOT reference guide.

Hi !

I have tried to use gStyle->SetImageScaling(3.) in a simple macro: it worked only in batch mode. In a normal root session, the png file was as if the scaling factor was still at 1.
Is this the expected behaviour ? I have tried it on root 6.22.06 on macOS 11.1 and Fedora33, with the same result.

Cheers,

Philippe

This is expected. That’s only in batch mode when you want a larger definition for printed canvas. In interactive mode you just need to make a bigger canvas.