163 lines
5.5 KiB
C++
163 lines
5.5 KiB
C++
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_SAVE_PnG_Hh_
|
|
#define DLIB_SAVE_PnG_Hh_
|
|
|
|
#include "save_png_abstract.h"
|
|
#include "image_saver.h"
|
|
#include "../array2d.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include "../pixel.h"
|
|
#include "../matrix/matrix_exp.h"
|
|
#include "../image_transforms/assign_image.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
namespace impl
|
|
{
|
|
enum png_type
|
|
{
|
|
png_type_rgb,
|
|
png_type_rgb_alpha,
|
|
png_type_gray,
|
|
};
|
|
|
|
void impl_save_png (
|
|
const std::string& file_name,
|
|
std::vector<unsigned char*>& row_pointers,
|
|
const long width,
|
|
const png_type type,
|
|
const int bit_depth
|
|
);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename image_type
|
|
>
|
|
typename disable_if<is_matrix<image_type> >::type save_png(
|
|
const image_type& img_,
|
|
const std::string& file_name
|
|
)
|
|
{
|
|
const_image_view<image_type> img(img_);
|
|
|
|
// make sure requires clause is not broken
|
|
DLIB_CASSERT(img.size() != 0,
|
|
"\t save_png()"
|
|
<< "\n\t You can't save an empty image as a PNG"
|
|
);
|
|
|
|
|
|
#ifndef DLIB_PNG_SUPPORT
|
|
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
You are getting this error because you are trying to use save_png()
|
|
but you haven't defined DLIB_PNG_SUPPORT. You must do so to use
|
|
this function. You must also make sure you set your build environment
|
|
to link against the libpng library.
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
|
|
COMPILE_TIME_ASSERT(sizeof(image_type) == 0);
|
|
#else
|
|
std::vector<unsigned char*> row_pointers(img.nr());
|
|
typedef typename image_traits<image_type>::pixel_type pixel_type;
|
|
|
|
if (is_same_type<rgb_pixel,pixel_type>::value)
|
|
{
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb, 8);
|
|
}
|
|
else if (is_same_type<rgb_alpha_pixel,pixel_type>::value)
|
|
{
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb_alpha, 8);
|
|
}
|
|
else if (pixel_traits<pixel_type>::lab || pixel_traits<pixel_type>::hsi || pixel_traits<pixel_type>::rgb)
|
|
{
|
|
// convert from Lab or HSI to RGB (Or potentially RGB pixels that aren't laid out as R G B)
|
|
array2d<rgb_pixel> temp_img;
|
|
assign_image(temp_img, img_);
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&temp_img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb, 8);
|
|
}
|
|
else if (pixel_traits<pixel_type>::rgb_alpha)
|
|
{
|
|
// convert from RGBA pixels that aren't laid out as R G B A
|
|
array2d<rgb_alpha_pixel> temp_img;
|
|
assign_image(temp_img, img_);
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&temp_img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb_alpha, 8);
|
|
}
|
|
else // this is supposed to be grayscale
|
|
{
|
|
DLIB_CASSERT(pixel_traits<pixel_type>::grayscale, "impossible condition detected");
|
|
|
|
if (pixel_traits<pixel_type>::is_unsigned && sizeof(pixel_type) == 1)
|
|
{
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 8);
|
|
}
|
|
else if (pixel_traits<pixel_type>::is_unsigned && sizeof(pixel_type) == 2)
|
|
{
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 16);
|
|
}
|
|
else
|
|
{
|
|
// convert from whatever this is to 16bit grayscale
|
|
array2d<dlib::uint16> temp_img;
|
|
assign_image(temp_img, img_);
|
|
for (unsigned long i = 0; i < row_pointers.size(); ++i)
|
|
row_pointers[i] = (unsigned char*)(&temp_img[i][0]);
|
|
|
|
impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 16);
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename EXP
|
|
>
|
|
void save_png(
|
|
const matrix_exp<EXP>& img,
|
|
const std::string& file_name
|
|
)
|
|
{
|
|
array2d<typename EXP::type> temp;
|
|
assign_image(temp, img);
|
|
save_png(temp, file_name);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#ifdef NO_MAKEFILE
|
|
#include "save_png.cpp"
|
|
#endif
|
|
|
|
#endif // DLIB_SAVE_PnG_Hh_
|
|
|