将 vtkChartXY/vtkPlot 导出为高分辨率光栅图像(JPG 或 PNG)

Export vtkChartXY/vtkPlot as a high resolution raster image (JPG or PNG)

我想将二维图表 (vtkChartXY) 导出为高分辨率位图图像(JPGPNG)。我能够以屏幕分辨率导出图像:

但是当我尝试使用 vtkWindowToImageFilter::SetMagnification(10) 增加分辨率时,我得到了以下扭曲的图像:

文本很好,但线段之间有不需要的间距。

我使用以下代码生成图表:

// 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());

以及将图表导出到 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();

如果重要的话,我在 Ubuntu 16.04 上使用 VTK 7.1。

问题:如何将 vtkChartXY 导出为高分辨率图像而不扭曲我的图表,即线段之间不需要的间距?

这不是一个干净的解决方案,而是一个克服问题的技巧。

诀窍是首先将图表导出为 SVG,然后使用第三方库将其转换为所需的高分辨率位图图像。

  1. 正在导出 SVG 图片

    vtkNew<vtkGL2PSExporter> exp;
    exp->SetRenderWindow(renderWindow.Get());
    exp->SetFileFormatToSVG();
    exp->SetFilePrefix("test");
    exp->Write();
    
  2. 将 SVG 转换为高分辨率位图图像(例如 png)

    多个库能够执行此转换,例如:

    • Inkscape:可以使用以下命令行方法将SVG文件转换为300dpi png文件:

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

      可以使用 Qt's QProcess class:

      以跨平台的方式从 C++ 执行
      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");
      

      请注意,此实现可能 lack support for some important attributes such as baseline-shift and dy。因此,在导出为SVG时将文本转为路径可能会获得更好的效果,如下所示:

      exp->TextAsPathOn();
      
    • Magick++ (C++ API of ImageMagick): See this post了解更多信息。