How to capture the window of a context view?

(Andrew Wilson) #1

I can’t seem to get vtkContextView to work with vtkWindowToImageFilter or vtkRenderLargeImage? I just get an corrupt png. Can anyone else? I saw something in the past on the forums on this with no solutions. But that was 2016.

I just gave the render window from vtkContextView to vtkWindowToImageFilter and renderer from vtkContextView to vtkRenderLargeImage.

...
contextView->Render();
vtkNew<vtkRenderLargeImage> screenshotFilter;
screenshotFilter->SetMagnification(2.0);
screenshotFilter->SetInput(contextView->GetRenderer());
screenshotFilter->Update();
vtkNew<vtkPNGWriter> writer;
writer->SetInputData(screenshotFilter->GetOutput());
writer->SetFileName(...));
writer->Update();

I threw a system(“pause”) under the render call and checked the render. It looks fine. I also tried one with an interactor setup and this on keypress but that didn’t work either.

Is there another way to do this?

(Embeddedmz) #2

Can we have a full testable example ?

vtkContextView is used to render 2D stuff (using 2D primitives like draw line, polygons etc…), the object to be rendered on it must be added to the view’s scene and inherit from vtkContextItem (bool Paint(vtkContext2D *painter) has to be overriden to create the 2D stuff you want, you can feed the painter a vtkImageData, that you create from a PNG file, to its DrawImage method).

(Andrew Wilson) #3

Here’s a simple example of some code that doesn’t successfully output an image of the graph like I would expect it too. I’ve tried many other variations. Even setting up callback on key press to output the screenshot. But nothing works.

The output, internally it seems fine. I can process it further, throw it into an image viewer, etc. But when giving it to something like vtkPNGWriter or vtkJPEGWriter it writes a corrupt file. I even tried allocating a new image and memcpy the image scalar data just in case it was something with the metadata.

#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkIntArray.h>
#include <vtkPlot.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkTable.h>
#include <vtkWindowToImageFilter.h>
#include <vtkPNGWriter.h>

static int data_2008[] = { 10822, 10941, 9979, 10370, 9460, 11228, 15093, 12231, 10160, 9816, 9384, 7892 };
static int data_2009[] = { 9058, 9474, 9979, 9408, 8900, 11569, 14688, 12231, 10294, 9585, 8957, 8590 };
static int data_2010[] = { 9058, 10941, 9979, 10270, 8900, 11228, 14688, 12231, 10160, 9585, 9384, 8590 };

int main()
{
    vtkNew<vtkContextView> view;

    vtkNew<vtkTable> table;
    vtkNew<vtkIntArray> arrMonth;
    arrMonth->SetName("Month");
    vtkNew<vtkIntArray> arr2008;
    arr2008->SetName("2008");
    vtkNew<vtkIntArray> arr2009;
    arr2009->SetName("2009");
    vtkNew<vtkIntArray> arr2010;
    arr2010->SetName("2010");

    table->AddColumn(arrMonth);
    table->AddColumn(arr2008);
    table->AddColumn(arr2009);
    table->AddColumn(arr2010);

    table->SetNumberOfRows(12);
    for (vtkIdType i = 0; i < 12; i++)
    {
	    table->SetValue(i, 0, i + 1);
	    table->SetValue(i, 1, data_2008[i]);
	    table->SetValue(i, 2, data_2009[i]);
	    table->SetValue(i, 3, data_2010[i]);
    }

    vtkNew<vtkChartXY> chart;

    vtkPlot* line = chart->AddPlot(vtkChart::BAR);
    line->SetInputData(table, 0, 1);
    line->SetColor(0.0, 1.0, 0.0);

    line = chart->AddPlot(vtkChart::BAR);
    line->SetInputData(table, 0, 2);
    line->SetColor(1.0, 0.0, 0.0);

    line = chart->AddPlot(vtkChart::BAR);
    line->SetInputData(table, 0, 3);
    line->SetColor(0.0, 0.0, 1.0);

    view->GetScene()->AddItem(chart);
    view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
    view->GetRenderWindow()->SetSize(1200, 1000);
    view->GetRenderWindow()->Render();

    vtkNew<vtkWindowToImageFilter> winToImageFilter;
    winToImageFilter->SetInput(view->GetRenderWindow());
    winToImageFilter->Update();

    vtkNew<vtkPNGWriter> writer;
    writer->SetFileName("mypathwashere/test.png");
    writer->SetInputData(winToImageFilter->GetOutput());
    writer->Update();

    return 1;
}
(Andras Lasso) #4

What is the scalar type and number of components of winToImageFilter output?
Does vtkMetaImageWriter create a valid image?

(Kenichiro Yoshimi) #5

You would need to substitute the “Update” method of vtkPNGWriter with “Write” method:

writer->Update();
-->
writer->Write();
(Andras Lasso) #6

You are right, we ran into this issue a few weeks ago and we lost an hour or so until we figured it out. I’ve created an issue on the VTK bugtracker to track its resolution.

(Andrew Wilson) #7

Not sure who you were responding to but Yoshimi was correct. It was just because I was using Update instead of Write. Unless these are supposed to be the same by design. I am however on 8.1.2.