Halting first steps towards encoding .pngs.

This commit is contained in:
Nick 2020-04-17 06:22:30 -04:00
parent 415c11ee18
commit 104e7bd9c2
5 changed files with 142 additions and 4 deletions

@ -51,6 +51,7 @@ set(headers
ConnectivityProxy.h
Cylinderizer.h
DecodePNG.h
EncodePNG.h
LineRenderer.h
MatrixHelpers.h
Scene.h
@ -85,6 +86,7 @@ set(sources
Camera.cxx
Color.cxx
DecodePNG.cxx
EncodePNG.cxx
raytracing/Logger.cxx
)

@ -14,6 +14,7 @@
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/DecodePNG.h>
#include <vtkm/rendering/EncodePNG.h>
#include <vtkm/rendering/LineRenderer.h>
#include <vtkm/rendering/TextRenderer.h>
#include <vtkm/rendering/WorldAnnotator.h>
@ -568,11 +569,40 @@ void Canvas::SetViewToScreenSpace(const vtkm::rendering::Camera& vtkmNotUsed(cam
void Canvas::SaveAs(const std::string& fileName) const
{
this->RefreshColorBuffer();
std::ofstream of(fileName.c_str(), std::ios_base::binary | std::ios_base::out);
auto ends_with = [](std::string const& value, std::string const& ending) {
if (ending.size() > value.size())
{
return false;
}
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
};
ColorBufferType::ReadPortalType colorPortal = GetColorBuffer().ReadPortal();
vtkm::Id width = GetWidth();
vtkm::Id height = GetHeight();
if (ends_with(fileName, ".png"))
{
std::vector<unsigned char> img(static_cast<size_t>(width * height));
for (vtkm::Id yIndex = height - 1; yIndex >= 0; yIndex--)
{
for (vtkm::Id xIndex = 0; xIndex < width; xIndex++)
{
vtkm::Vec4f_32 tuple = colorPortal.Get(yIndex * width + xIndex);
size_t idx = static_cast<size_t>(4 * width * yIndex + 4 * xIndex);
img[idx + 0] = (unsigned char)(tuple[0] * 255);
img[idx + 1] = (unsigned char)(tuple[1] * 255);
img[idx + 2] = (unsigned char)(tuple[2] * 255);
img[idx + 3] = (unsigned char)(tuple[3] * 255);
}
}
SavePNG(fileName, img, static_cast<unsigned long>(width), static_cast<unsigned long>(height));
return;
}
std::ofstream of(fileName.c_str(), std::ios_base::binary | std::ios_base::out);
of << "P6" << std::endl << width << " " << height << std::endl << 255 << std::endl;
ColorBufferType::ReadPortalType colorPortal = GetColorBuffer().ReadPortal();
for (vtkm::Id yIndex = height - 1; yIndex >= 0; yIndex--)
{
for (vtkm::Id xIndex = 0; xIndex < width; xIndex++)

@ -14,8 +14,6 @@
#include <vtkm/internal/Configure.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#define LODEPNG_NO_COMPILE_ENCODER
#define LODEPNG_NO_COMPILE_DISK
#include <vtkm/thirdparty/lodepng/vtkmlodepng/lodepng.cpp>
VTKM_THIRDPARTY_PRE_INCLUDE

@ -0,0 +1,69 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <algorithm> // for std::equal
#include <vtkm/rendering/EncodePNG.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/internal/Configure.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <vtkm/thirdparty/lodepng/vtkmlodepng/lodepng.cpp>
VTKM_THIRDPARTY_PRE_INCLUDE
namespace vtkm
{
namespace rendering
{
vtkm::UInt32 EncodePNG(std::vector<unsigned char> const& image,
unsigned long width,
unsigned long height,
std::vector<unsigned char>& output_png)
{
// The default is 8 bit RGBA; does anyone care to have more options?
vtkm::UInt32 error = vtkm::png::lodepng::encode(output_png, image, width, height);
if (error)
{
// TODO: Use logging framework instead:
std::cerr << "PNG Encoder error number " << error << ": " << png::lodepng_error_text(error)
<< "\n";
}
return error;
}
vtkm::UInt32 SavePNG(std::string const& filename,
std::vector<unsigned char> const& image,
unsigned long width,
unsigned long height)
{
auto ends_with = [](std::string const& value, std::string const& ending) {
if (ending.size() > value.size())
{
return false;
}
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
};
if (!ends_with(filename, ".png"))
{
std::cerr << "PNG filename must end with .png\n";
}
std::vector<unsigned char> output_png;
vtkm::UInt32 error = EncodePNG(image, width, height, output_png);
if (!error)
{
vtkm::png::lodepng::save_file(output_png, filename);
}
return error;
}
}
} // namespace vtkm::rendering

@ -0,0 +1,39 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_rendering_EncodePNG_h
#define vtk_m_rendering_EncodePNG_h
#include <vtkm/Types.h>
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vector>
namespace vtkm
{
namespace rendering
{
//
VTKM_RENDERING_EXPORT
vtkm::UInt32 EncodePNG(std::vector<unsigned char> const& image,
unsigned long width,
unsigned long height,
unsigned char* out_png,
std::size_t out_size);
VTKM_RENDERING_EXPORT
vtkm::UInt32 SavePNG(std::string filename,
std::vector<unsigned char> const& image,
unsigned long width,
unsigned long height);
}
} // vtkm::rendering
#endif //vtk_m_rendering_EncodePNG_h