# ImageAlgorithmFilter

VTKExamples/Cxx/Developers/ImageAlgorithmFilter

### Description

This example demonstrates how to setup the pipeline for a {{class vtkImageAlgorithm}} filter that takes a {{class vtkImageData}} as input and produces another vtkImageData as output. This particular example creates a 2x2 image and fills it with "2"s. The filter changes the (0,0) element to a 5.

### Code

ImageAlgorithmFilter.cxx

    #include <vtkSmartPointer.h>

    #include "vtkImageAlgorithmFilter.h"
    #include <vtkImageData.h>

    void PrintImage(vtkImageData* image);

    int main (int /* argc */, char * /* argv */ [])
    {
      vtkSmartPointer<vtkImageData> input =
        vtkSmartPointer<vtkImageData>::New();
      // Setup the image
      input->SetDimensions(2,2,1);
      input->AllocateScalars(VTK_DOUBLE,1);

      // Fill every entry of the image data with "2.0"
      int* dims = input->GetDimensions();

      for (int y=0; y<dims[1]; y++)
      {
        for (int x=0; x<dims[0]; x++)
        {
          input->SetScalarComponentFromDouble(x,y,0,0,2.0);
        }
      }

      std::cout << "Input image: " << std::endl;
      PrintImage(input);

      vtkSmartPointer<vtkImageAlgorithmFilter> filter =
        vtkSmartPointer<vtkImageAlgorithmFilter>::New();
      filter->SetInputData(input);
      filter->Update();

      vtkImageData* output = filter->GetOutput();

      std::cout << "Output image: " << std::endl;
      PrintImage(output);

      return 0;
    }

    void PrintImage(vtkImageData* image)
    {
      int* dims = image->GetDimensions();

      for (int y=0; y<dims[1]; y++)
      {
        for (int x=0; x<dims[0]; x++)
        {
          double v = image->GetScalarComponentAsDouble(x,y,0,0);
          std::cout << v << " ";
        }
        std::cout << std::endl;
      }
    }

vtkImageAlgorithmFilter.h

    #ifndef __vtkImageAlgorithmFilter_h
    #define __vtkImageAlgorithmFilter_h

    #include <vtkImageAlgorithm.h>

    class vtkImageAlgorithmFilter : public vtkImageAlgorithm
    {
    public:
      static vtkImageAlgorithmFilter *New();
      vtkTypeMacro(vtkImageAlgorithmFilter,vtkImageAlgorithm);

      vtkImageAlgorithmFilter(){}

    protected:

      int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);

    private:
      vtkImageAlgorithmFilter(const vtkImageAlgorithmFilter&);  // Not implemented.
      void operator=(const vtkImageAlgorithmFilter&);  // Not implemented.
    };

    #endif

vtkImageAlgorithmFilter.cxx

    #include "vtkImageAlgorithmFilter.h"

    #include <vtkImageData.h>
    #include <vtkObjectFactory.h>
    #include <vtkStreamingDemandDrivenPipeline.h>
    #include <vtkInformationVector.h>
    #include <vtkInformation.h>
    #include <vtkDataObject.h>
    #include <vtkSmartPointer.h>

    vtkStandardNewMacro(vtkImageAlgorithmFilter);

    int vtkImageAlgorithmFilter::RequestData(vtkInformation *vtkNotUsed(request),
                                                 vtkInformationVector **inputVector,
                                                 vtkInformationVector *outputVector)
    {
      // Get the info objects
      vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
      vtkInformation *outInfo = outputVector->GetInformationObject(0);

      // Get the input and ouptut
      vtkImageData *input = vtkImageData::SafeDownCast(
          inInfo->Get(vtkDataObject::DATA_OBJECT()));

      vtkImageData *output = vtkImageData::SafeDownCast(
          outInfo->Get(vtkDataObject::DATA_OBJECT()));

      vtkSmartPointer<vtkImageData> image =
        vtkSmartPointer<vtkImageData>::New();
      image->ShallowCopy(input);

      image->SetScalarComponentFromDouble(0,0,0,0, 5.0);

      output->ShallowCopy(image);

      // Without these lines, the output will appear real but will not work as the input to any other filters
      int extent[6];
      input->GetExtent(extent);
      output->SetExtent(extent);
      outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
                   extent,
                   6);
      outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                   extent,
                   6);
      return 1;
    }

### CMakeLists.txt

    cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

    project(ImageAlgorithmFilter)

    find_package(VTK COMPONENTS
      vtkCommonCore
      vtkCommonDataModel QUIET)
    if (NOT VTK_FOUND)
      message("Skipping ImageAlgorithmFilter: ${VTK_NOT_FOUND_MESSAGE}")
      return ()
    endif()
    message (STATUS "VTK_VERSION: ${VTK_VERSION}")
    if (VTK_VERSION VERSION_LESS "8.90.0")
      # old system
      include(${VTK_USE_FILE})
      add_executable(ImageAlgorithmFilter MACOSX_BUNDLE ImageAlgorithmFilter.cxx )
      target_link_libraries(ImageAlgorithmFilter PRIVATE ${VTK_LIBRARIES})
    else ()
      # include all components
      add_executable(ImageAlgorithmFilter MACOSX_BUNDLE ImageAlgorithmFilter.cxx )
      target_link_libraries(ImageAlgorithmFilter PRIVATE ${VTK_LIBRARIES})
      # vtk_module_autoinit is needed
      vtk_module_autoinit(
        TARGETS ImageAlgorithmFilter
        MODULES ${VTK_LIBRARIES}
        )
    endif ()

### Download and Build ImageAlgorithmFilter

Click here to download ImageAlgorithmFilter and its CMakeLists.txt file. Once the tarball ImageAlgorithmFilter.tar has been downloaded and extracted,

    cd ImageAlgorithmFilter/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:

    ./ImageAlgorithmFilter

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.