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

时间:2017-06-10 09:58:41

标签: c++ image qt vtk rasterizing

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

enter image description here

但是当我尝试使用vtkWindowToImageFilter::SetMagnification(10)增加分辨率时,我会获得以下失真图像:

enter image description here

文本很好,但线段之间存在不希望的间距。

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

// 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导出为高分辨率图像,即线段之间不需要的间距?

1 个答案:

答案 0 :(得分:0)

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

诀窍是首先将图表导出到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
      

      可以使用QtQProcess类以跨平台方式从C ++执行:

      QProcess p;
      p.startDetached("inkscape test.svg -e test.png -d 300");
      
    • QtQSvgRenderer

      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++ImageMagick的C ++ API):有关详细信息,请参阅this post