1 #include "vvAnimatedGIFWriter.h"
4 #include <vtkVersion.h>
5 #include <vtkStreamingDemandDrivenPipeline.h>
6 #include <vtkInformation.h>
7 #include <vtkImageData.h>
8 #include <vtkImageQuantizeRGBToIndex.h>
9 #include <vtkImageAppend.h>
10 #include <vtkImageCast.h>
11 #include <vtkObjectFactory.h>
12 #include <vtkLookupTable.h>
16 //---------------------------------------------------------------------------
17 vtkStandardNewMacro(vvAnimatedGIFWriter);
19 //---------------------------------------------------------------------------
20 vvAnimatedGIFWriter::vvAnimatedGIFWriter()
27 //---------------------------------------------------------------------------
28 vvAnimatedGIFWriter::~vvAnimatedGIFWriter()
32 //---------------------------------------------------------------------------
33 void vvAnimatedGIFWriter::Start()
35 // Create one volume with all slices
36 RGBvolume = vtkSmartPointer<vtkImageAppend>::New();
37 RGBvolume->SetAppendAxis(2);
41 //---------------------------------------------------------------------------
42 void vvAnimatedGIFWriter::Write()
45 #if VTK_MAJOR_VERSION <= 5
46 this->GetInput()->UpdateInformation();
47 int *wExtent = this->GetInput()->GetWholeExtent();
48 this->GetInput()->SetUpdateExtent(wExtent);
49 this->GetInput()->Update();
50 #elif VTK_MAJOR_VERSION >= 7 && VTK_MINOR_VERSION >= 1
51 this->UpdateInformation();
52 int *wExtent = this->GetInput()->GetInformation()->Get(vtkDataObject::DATA_EXTENT());
53 this->UpdateExtent(wExtent);
56 this->UpdateInformation();
57 int *wExtent = this->GetInput()->GetInformation()->Get(vtkDataObject::DATA_EXTENT());
58 this->SetUpdateExtent(wExtent);
62 RGBslices.push_back( vtkSmartPointer<vtkImageData>::New() );
63 RGBslices.back()->ShallowCopy(this->GetInput());
64 #if VTK_MAJOR_VERSION <= 5
65 RGBvolume->AddInput(RGBslices.back());
67 RGBvolume->AddInputData(RGBslices.back());
71 //---------------------------------------------------------------------------
72 void vvAnimatedGIFWriter::End()
76 // Quantize to 8 bit colors
77 vtkSmartPointer<vtkImageQuantizeRGBToIndex> quant = vtkSmartPointer<vtkImageQuantizeRGBToIndex>::New();
78 quant->SetNumberOfColors(256);
79 #if VTK_MAJOR_VERSION <= 5
80 quant->SetInput(RGBvolume->GetOutput());
82 quant->SetInputConnection(RGBvolume->GetOutputPort());
86 // Convert to 8 bit image
87 vtkSmartPointer<vtkImageCast> cast = vtkSmartPointer<vtkImageCast>::New();
88 #if VTK_MAJOR_VERSION <= 5
89 cast->SetInput( quant->GetOutput() );
91 cast->SetInputConnection( quant->GetOutputPort() );
93 cast->SetOutputScalarTypeToUnsignedChar();
96 // Create palette for CxImage => Swap r and b in LUT
98 memcpy(pal, (RGBQUAD*)(quant->GetLookupTable()->GetPointer(0)), sizeof(RGBQUAD)*256);
99 for(unsigned int j=0; j<256; j++)
100 std::swap(pal[j].rgbBlue, pal[j].rgbRed);
102 // Create a stack of CxImages
103 DWORD width = cast->GetOutput()->GetExtent()[1]-cast->GetOutput()->GetExtent()[0]+1;
104 DWORD height = cast->GetOutput()->GetExtent()[3]-cast->GetOutput()->GetExtent()[2]+1;
105 std::vector<CxImage*> cximages( RGBslices.size() );
106 for(unsigned int i=0; i<RGBslices.size(); i++) {
107 cximages[i] = new CxImage;
108 cximages[i]->SetFrameDelay(100/Rate);
110 cximages[i]->CreateFromArray((BYTE *)RGBvolume->GetOutput()->GetScalarPointer(0,0,i),
111 width, height, 24, width*3, false);
112 cximages[i]->SwapRGB2BGR();
113 cximages[i]->DecreaseBpp(8, true, pal);
116 cximages[i]->CreateFromArray((BYTE *)cast->GetOutput()->GetScalarPointer(0,0,i),
117 width, height, 8, width, false);
118 cximages[i]->SetPalette(pal);
124 pFile = fopen (this->FileName, "wb");
126 vtkErrorMacro("Error in vvAnimatedGIFWriter::End: could not open " << this->FileName );
129 CxImageGIF cximagegif;
130 cximagegif.SetLoops(Loops);
131 bool result = cximagegif.Encode(pFile,&(cximages[0]), (int)RGBslices.size(), true);
135 for(unsigned int i=0; i<RGBslices.size(); i++)
138 vtkErrorMacro("Error in CxImage: " << cximagegif.GetLastError() );
142 //---------------------------------------------------------------------------
143 void vvAnimatedGIFWriter::PrintSelf(ostream& os, vtkIndent indent)
145 this->Superclass::PrintSelf(os, indent);