0

I want to export a 2D chart (vtkChartXY) as a high resolution bitmap image (JPG or PNG). I'm able to export an image at screen resolution:

enter image description here

But when I try to increase the resolution using vtkWindowToImageFilter::SetMagnification(10), I obtain the following distorted image:

enter image description here

The text is just fine, but there are undesired spacings between the line segments.

I used the following code to generate the graph:

// Construct a random 2D chart
vtkNew<vtkContextView> pView;
vtkNew<vtkChartXY> pChart;
vtkPlot *pPlot = pChart->AddPlot(vtkChart::LINE);
vtkNew<vtkTable> pTable;
vtkNew<vtkDoubleArray> pX, pY;
pX->SetName("x");
pY->SetName("y");
for (int i = 0; i < 100; ++i)
{
  pX->InsertNextTuple1(i);
  pY->InsertNextTuple1(std::rand());
}
pTable->AddColumn(pX.Get());
pTable->AddColumn(pY.Get());
pPlot->SetInputData(pTable.Get(), "x", "y");
pView->GetScene()->AddItem(pChart.Get());

And the following code to export the graph to JPEG:

// Export the image to JPG
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(pView->GetRenderer());
renderWindow->SetSize(300, 300);
renderWindow->OffScreenRenderingOn();
renderWindow->Render();

vtkNew<vtkWindowToImageFilter> windowToImageFilter;
windowToImageFilter->SetInput(renderWindow.Get());
// windowToImageFilter->SetMagnification(10); // uncomment this line to obtain the distorted image

vtkNew<vtkJPEGWriter> writer;
writer->SetFileName("test.jpg");
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
writer->Write();

If it matters, I'm using VTK 7.1 on Ubuntu 16.04.

Question: How can I export a vtkChartXY as a high resolution image without distorting my graph, i.e. undesired spacings between the line segments?

m7913d
  • 10,244
  • 7
  • 28
  • 56

1 Answers1

0

This is not a clean solution, but rather a trick to overcome the problem.

The trick is to firstly export the chart to SVG and secondly use a third party library to convert it to the desired high resolution bitmap image.

  1. Exporting SVG image

    vtkNew<vtkGL2PSExporter> exp;
    exp->SetRenderWindow(renderWindow.Get());
    exp->SetFileFormatToSVG();
    exp->SetFilePrefix("test");
    exp->Write();
    
  2. Convert SVG to high resolution bitmap image (ex. png)

    Multiple libraries are able to perform this conversion, for example:

    • Inkscape: one can use the following command line method to convert the SVG file to a 300dpi png file:

      inkscape test.svg -e test.png -d 300
      

      Which may be executed from C++ in a cross-platform way using Qt's QProcess class:

      QProcess p;
      p.startDetached("inkscape test.svg -e test.png -d 300");
      
    • Qt's QSvgRenderer

      QSvgRenderer renderer (QLatin1String("test.svg"));
      const QSize imageSize(4*renderer.defaultSize()); // four times screen resolution
      QImage image(imageSize, QImage::Format_ARGB32);
      image.fill(Qt::transparent);
      QPainter painter;
      painter.begin(&image);
      renderer.render(&painter, QRectF(QPointF(), QSizeF(imageSize)));
      painter.end();
      image.save("test.png");
      

      Note that this implementation may lack support for some important attributes such as baseline-shift and dy. Therefore, better results may be obtained by converting text to paths while exporting to SVG as follows:

      exp->TextAsPathOn();
      
    • Magick++ (C++ API of ImageMagick): See this post for more information.

m7913d
  • 10,244
  • 7
  • 28
  • 56