ChooseTextColor
vtk-examples/Cxx/Visualization/ChooseTextColor
Description¶
This example uses a simple algorithm to choose a color that "contrasts" with another color. The ChooseContrastingColor procedure converts the input RGB value to HSV using vtkMath::RGBToHSV. If the value is <= .5, the light color is chosen as the contrasting color. Otherwise, the dark color is chosen. The default light color is white and the default dark color is black. Any color from vtkNamedColors can be specified for the light and dark colors.
To run the example with your own arguments:
ChooseTextColor fontFile [background] [lightColor] [darkColor]
Info
VTKNamedColorPatches shows the available colors.
Info
The ChooseContrastingColor procedure is reusable, Cut and paste the declarations and code into other examples.
Tip
There are many sources of TrueType fonts. Here is one source.
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
ChooseTextColor.cxx
#include <vtkMath.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vtksys/SystemTools.hxx>
namespace {
// Given a color, find a contrasting color. If the given color is "light",
// use the lightColor otherwise use the darkColor.
void ChooseContrastingColor(double* rgbIn, double* rgbOut,
const double threshold = .5,
const std::string& lightColor = "white",
const std::string& darkColor = "black");
} // namespace
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0]
<< " font.ttf [backColor] [lightColor] [darkColor]" << std::endl;
std::cerr << "E.g. Canterbury.ttf Pink MintCream SaddleBrown" << std::endl;
return EXIT_FAILURE;
}
// Defaults
double threshold(.8);
std::string backColor = "SlateGray";
std::string lightColor = "White";
std::string darkColor = "Black";
if (argc > 2)
{
backColor = argv[2];
}
if (argc > 3)
{
lightColor = argv[3];
}
if (argc > 4)
{
darkColor = argv[4];
}
std::string fontFile(argv[1]);
std::stringstream str;
str << "Font: "
<< vtksys::SystemTools::GetFilenameWithoutExtension(std::string(argv[1]))
<< "\n"
<< "Background: " << backColor << "\n"
<< "Light Color: " << lightColor << "\n"
<< "Dark Color: " << darkColor;
int width = 640;
int height = 480;
vtkNew<vtkNamedColors> colors;
vtkNew<vtkTextActor> actor;
actor->GetTextProperty()->SetJustificationToCentered();
actor->GetTextProperty()->SetVerticalJustificationToCentered();
actor->SetTextScaleModeToViewport();
actor->SetInput(str.str().c_str());
actor->SetPosition(width / 2, height / 2);
actor->GetTextProperty()->BoldOff();
actor->GetTextProperty()->SetFontSize(40);
actor->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
actor->GetTextProperty()->SetFontFile(fontFile.c_str());
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(colors->GetColor3d(backColor.c_str()).GetData());
// Compute a good color for text on the renderer background.
double rgb[3];
ChooseContrastingColor(renderer->GetBackground(), rgb, threshold, lightColor,
darkColor);
std::cout << rgb[0] << "," << rgb[1] << "," << rgb[2] << std::endl;
actor->GetTextProperty()->SetColor(rgb);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(width, height);
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("ChooseTextColor");
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderWindow->Render();
interactor->Initialize();
interactor->Start();
return EXIT_SUCCESS;
}
namespace {
void ChooseContrastingColor(double* rgbIn, double* rgbOut,
const double threshold,
const std::string& lightColor,
const std::string& darkColor)
{
vtkNew<vtkNamedColors> colors;
double hsv[3];
// If the value is <= threshold, use a light color, otherwise use a dark
// color.
vtkMath::RGBToHSV(rgbIn, hsv);
if (hsv[2] <= threshold)
{
colors->GetColor(lightColor.c_str(), rgbOut[0], rgbOut[1], rgbOut[2]);
}
else
{
colors->GetColor(darkColor.c_str(), rgbOut[0], rgbOut[1], rgbOut[2]);
}
}
} // namespace
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(ChooseTextColor)
find_package(VTK COMPONENTS
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "ChooseTextColor: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(ChooseTextColor MACOSX_BUNDLE ChooseTextColor.cxx )
target_link_libraries(ChooseTextColor PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS ChooseTextColor
MODULES ${VTK_LIBRARIES}
)
Download and Build ChooseTextColor¶
Click here to download ChooseTextColor and its CMakeLists.txt file. Once the tarball ChooseTextColor.tar has been downloaded and extracted,
cd ChooseTextColor/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./ChooseTextColor
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.