using vtkActor2D along with vtkImageCanvasSource2D results in wrong color

Hi,
I want to draw a circle on screen, and I don’t want the circle to get rescaled when mouse scrolls(much like a log on screen). I thought I’ll use vtkImageCanvasSource2D to draw the circle, and then use vtkActor2D to hold the output the canvas.
Everything works fine except that the color of the circle is not what I set in canvas.
Here’s the minimal example to illustrate this problem:

#include <vtkImageActor.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkInteractorStyleImage.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageMapper.h>
#include <vtkActor2D.h>
#include <vtkCamera.h>
#include <vtkProperty2D.h>


int main(int, char* [])
{
    vtkNew<vtkNamedColors> colors;

    int extent[6]{0, 500, 0, 250, 0, 0};

    // Create an image of a rectangle.
    vtkNew<vtkImageCanvasSource2D> source;
    source->SetScalarTypeToUnsignedChar();
    source->SetExtent(extent);
    source->SetNumberOfScalarComponents(4); // Ensure 4 components for RGBA
    source->SetDrawColor(0, 0, 0, 0); // Transparent background
    source->FillBox(extent[0], extent[1], extent[2], extent[3]);
    source->SetDrawColor(255, 255, 0, 255); // Yellow color with full opacity
    source->DrawCircle(200, 100, 30);
    source->Update();

    // Create an image mapper and actor
    auto imageMapper = vtkSmartPointer<vtkImageMapper>::New();
    imageMapper->SetInputData(source->GetOutput());
    auto originalActor = vtkSmartPointer<vtkActor2D>::New();
    originalActor->SetMapper(imageMapper);
    originalActor->SetPosition(0, 0); // The circle's pos is setup already so just place the canvas at the origin

    // Setup renderer
    vtkNew<vtkRenderer> originalRenderer;
    originalRenderer->AddActor(originalActor);
    originalRenderer->GetActiveCamera()->SetParallelProjection(true);
    originalRenderer->ResetCamera();
    originalRenderer->SetBackground(colors->GetColor3d("SandyBrown").GetData());
    double imageHeight = extent[3] - extent[2] + 1;
    originalRenderer->GetActiveCamera()->SetParallelScale(imageHeight / 2.0);

    // Setup render window
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->SetSize(extent[1], extent[3]);
    renderWindow->AddRenderer(originalRenderer);
    renderWindow->SetWindowName("ImageMask");

    // Setup render window interactor
    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
    vtkNew<vtkInteractorStyleImage> style;
    renderWindowInteractor->SetInteractorStyle(style);
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderWindow->Render();
    renderWindowInteractor->Initialize();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

I set the color of the circle as yellow, but what’s actually shown is a grey-ish color. And no matter what RGB value I change for SetDrawColor(), the result shown all looks the same.
If I use vtkImageActor to visualize the canvas output, the color is correct. But since I don’t want the image get rescaled during mouse wheel events, I need to use vtkActor2D.
How can I show the right color for the circle?

Thanks.

Hello,

Why do you call SetDrawColor twice on the same object?

best,

PC

Hi Paulo,
The SetDrawColor() sets the color of the subsequent shape color. So the first call

   source->SetDrawColor(0, 0, 0, 0); // Transparent background
   source->FillBox(extent[0], extent[1], extent[2], extent[3]);

sets the pixels of canvas to transparent color, effectively setting the background to transparent.
Then the second call

    source->SetDrawColor(255, 255, 0, 255); // Yellow color with full opacity
    source->DrawCircle(200, 100, 30);

sets the specified circle pixels to yellow.

regards

Hello,

Documentation is not very helpful with respect to color component value range. So, given that SetDrawColor() accepts four doubles instead of integers, I wager

should be

It wouldn’t make sense to use doubles if the argument values are expected to be 0-255 integers.

best,

PC

Hi Paulo,
Thanks for reply. In several examples(eg. this and this) they all used unsigned char as scalar types for vtkImageCanvasSource2D class. If I change my code to using double, ie.

  vtkNew<vtkImageCanvasSource2D> source;
    source->SetScalarTypeToDouble();
    source->SetExtent(extent);
    source->SetNumberOfScalarComponents(4); // Ensure 4 components for RGBA
    source->SetDrawColor(0, 0, 0, 0); // Transparent background
    source->FillBox(extent[0], extent[1], extent[2], extent[3]);
    source->SetDrawColor(1.0, 1.0, 0, 1.0); // Yellow color with full opacity
    source->DrawCircle(200, 100, 30);
    source->Update();

nothing will be shown.

Regards