1 #include "vvAnimatedGIFWriter.h"
6 #include <vtkImageData.h>
7 #include <vtkImageQuantizeRGBToIndex.h>
8 #include <vtkImageAppend.h>
9 #include <vtkImageCast.h>
10 #include <vtkObjectFactory.h>
11 #include <vtkLookupTable.h>
13 //---------------------------------------------------------------------------
14 vtkStandardNewMacro(vvAnimatedGIFWriter);
16 //---------------------------------------------------------------------------
17 vvAnimatedGIFWriter::vvAnimatedGIFWriter()
24 //---------------------------------------------------------------------------
25 vvAnimatedGIFWriter::~vvAnimatedGIFWriter()
29 //---------------------------------------------------------------------------
30 void vvAnimatedGIFWriter::Start()
32 // Create one volume with all slices
33 RGBvolume = vtkSmartPointer<vtkImageAppend>::New();
34 RGBvolume->SetAppendAxis(2);
38 //---------------------------------------------------------------------------
39 void vvAnimatedGIFWriter::Write()
42 this->GetInput()->UpdateInformation();
43 int *wExtent = this->GetInput()->GetWholeExtent();
44 this->GetInput()->SetUpdateExtent(wExtent);
45 this->GetInput()->Update();
47 RGBslices.push_back( vtkSmartPointer<vtkImageData>::New() );
48 RGBslices.back()->ShallowCopy(this->GetInput());
49 RGBvolume->AddInput(RGBslices.back());
52 //---------------------------------------------------------------------------
53 void vvAnimatedGIFWriter::End()
57 // Quantize to 8 bit colors
58 vtkSmartPointer<vtkImageQuantizeRGBToIndex> quant = vtkSmartPointer<vtkImageQuantizeRGBToIndex>::New();
59 quant->SetNumberOfColors(256);
60 quant->SetInput(RGBvolume->GetOutput());
63 // Convert to 8 bit image
64 vtkSmartPointer<vtkImageCast> cast = vtkSmartPointer<vtkImageCast>::New();
65 cast->SetInput( quant->GetOutput() );
66 cast->SetOutputScalarTypeToUnsignedChar();
69 // Create palette for CxImage => Swap r and b in LUT
71 memcpy(pal, (RGBQUAD*)(quant->GetLookupTable()->GetPointer(0)), sizeof(RGBQUAD)*256);
72 for(unsigned int j=0; j<256; j++)
73 std::swap(pal[j].rgbBlue, pal[j].rgbRed);
75 // Create a stack of CxImages
76 DWORD width = cast->GetOutput()->GetExtent()[1]-cast->GetOutput()->GetExtent()[0]+1;
77 DWORD height = cast->GetOutput()->GetExtent()[3]-cast->GetOutput()->GetExtent()[2]+1;
78 std::vector<CxImage*> cximages( RGBslices.size() );
79 for(unsigned int i=0; i<RGBslices.size(); i++) {
80 cximages[i] = new CxImage;
81 cximages[i]->SetFrameDelay(100/Rate);
83 cximages[i]->CreateFromArray((BYTE *)RGBvolume->GetOutput()->GetScalarPointer(0,0,i),
84 width, height, 24, width*3, false);
85 cximages[i]->SwapRGB2BGR();
86 cximages[i]->DecreaseBpp(8, true, pal);
89 cximages[i]->CreateFromArray((BYTE *)cast->GetOutput()->GetScalarPointer(0,0,i),
90 width, height, 8, width, false);
91 cximages[i]->SetPalette(pal);
97 pFile = fopen (this->FileName, "wb");
99 vtkErrorMacro("Error in vvAnimatedGIFWriter::End: could not open " << this->FileName );
102 CxImageGIF cximagegif;
103 cximagegif.SetLoops(Loops);
104 bool result = cximagegif.Encode(pFile,&(cximages[0]), (int)RGBslices.size(), true);
108 for(unsigned int i=0; i<RGBslices.size(); i++)
111 vtkErrorMacro("Error in CxImage: " << cximagegif.GetLastError() );
115 //---------------------------------------------------------------------------
116 void vvAnimatedGIFWriter::PrintSelf(ostream& os, vtkIndent indent)
118 this->Superclass::PrintSelf(os, indent);