mirror of https://github.com/davisking/dlib.git
Add webp support (#2565)
* Add BGR(A) to pixel_traits * add support for reading webp * Apply Davis' suggestions and fix formatting * Fix signed/unsigned warning * Update decoding paths * update pixel traits documentation * Add support for writing WebP images * Simplify image_saver code * WIP: add tests, PSNR is low but images look good * Add lossless compression for quality > 100 * Fix build when WebP support is disabled * Use C++ stream instead of C-style FILE * Fix indentation * Use reinterpret_cast instead of C-style cast * Improve impl::impl_save_webp signature * Remove empty line * Use switch statement and clean up code * Update Copyright and test libwebp on Linux * Fix formatting in github workflow * Fix operator== for bgr_alpha_pixel * Show where the test fails * Add libwebp to CI for the remaining Linux workflows * Use filename consistently * Improve message with wrong pixel type * Fix tests for WebP images * Prevent saving images which are too large and improve error messages * Use max dimension from WebP header directly * Update documentation, index and release notes * Update dlib/image_saver/save_webp_abstract.h Co-authored-by: Martin T. H. Sandsmark <martin.sandsmark@kde.org> Co-authored-by: Davis E. King <davis685@gmail.com>pull/2571/head
parent
0aa8b4cbfc
commit
a76f205bf6
@ -0,0 +1,34 @@
|
||||
#=============================================================================
|
||||
# Find WebP library
|
||||
# From OpenCV
|
||||
#=============================================================================
|
||||
# Find the native WebP headers and libraries.
|
||||
#
|
||||
# WEBP_INCLUDE_DIRS - where to find webp/decode.h, etc.
|
||||
# WEBP_LIBRARIES - List of libraries when using webp.
|
||||
# WEBP_FOUND - True if webp is found.
|
||||
#=============================================================================
|
||||
|
||||
# Look for the header file.
|
||||
|
||||
unset(WEBP_FOUND)
|
||||
|
||||
FIND_PATH(WEBP_INCLUDE_DIR NAMES webp/decode.h)
|
||||
|
||||
if(NOT WEBP_INCLUDE_DIR)
|
||||
unset(WEBP_FOUND)
|
||||
else()
|
||||
MARK_AS_ADVANCED(WEBP_INCLUDE_DIR)
|
||||
|
||||
# Look for the library.
|
||||
FIND_LIBRARY(WEBP_LIBRARY NAMES webp)
|
||||
MARK_AS_ADVANCED(WEBP_LIBRARY)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG WEBP_LIBRARY WEBP_INCLUDE_DIR)
|
||||
|
||||
SET(WEBP_LIBRARIES ${WEBP_LIBRARY})
|
||||
SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR})
|
||||
endif()
|
@ -0,0 +1,135 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Martin Sandsmark, Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_WEBP_LOADER_CPp_
|
||||
#define DLIB_WEBP_LOADER_CPp_
|
||||
|
||||
// only do anything with this file if DLIB_WEBP_SUPPORT is defined
|
||||
#ifdef DLIB_WEBP_SUPPORT
|
||||
|
||||
#include "../array2d.h"
|
||||
#include "../pixel.h"
|
||||
#include "../dir_nav.h"
|
||||
#include "webp_loader.h"
|
||||
|
||||
#include <webp/decode.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
static std::vector<unsigned char> load_contents(const std::string& filename)
|
||||
{
|
||||
std::ifstream stream(filename, std::ios::binary);
|
||||
stream.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit);
|
||||
stream.seekg(0, std::ios_base::end);
|
||||
std::vector<unsigned char> buffer(stream.tellg());
|
||||
stream.seekg(0);
|
||||
stream.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
webp_loader::
|
||||
webp_loader(const char* filename) : height_(0), width_(0)
|
||||
{
|
||||
data_ = load_contents(filename);
|
||||
get_info();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
webp_loader::
|
||||
webp_loader(const std::string& filename) : height_(0), width_(0)
|
||||
{
|
||||
data_ = load_contents(filename);
|
||||
get_info();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
webp_loader::
|
||||
webp_loader(const dlib::file& f) : height_(0), width_(0)
|
||||
{
|
||||
data_ = load_contents(f.full_name());
|
||||
get_info();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
webp_loader::
|
||||
webp_loader(const unsigned char* imgbuffer, size_t imgbuffersize) : height_(0), width_(0)
|
||||
{
|
||||
data_.resize(imgbuffersize);
|
||||
memcpy(data_.data(), imgbuffer, imgbuffersize);
|
||||
get_info();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::get_info()
|
||||
{
|
||||
if (!WebPGetInfo(data_.data(), data_.size(), &width_, &height_))
|
||||
{
|
||||
throw image_load_error("webp_loader: Invalid header");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::read_argb(unsigned char *out, const size_t out_size, const int out_stride) const
|
||||
{
|
||||
if (!WebPDecodeARGBInto(data_.data(), data_.size(), out, out_size, out_stride))
|
||||
{
|
||||
throw image_load_error("webp_loader: decoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::read_rgba(unsigned char *out, const size_t out_size, const int out_stride) const
|
||||
{
|
||||
if (!WebPDecodeRGBAInto(data_.data(), data_.size(), out, out_size, out_stride))
|
||||
{
|
||||
throw image_load_error("webp_loader: decoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::read_bgra(unsigned char *out, const size_t out_size, const int out_stride) const
|
||||
{
|
||||
if (!WebPDecodeBGRAInto(data_.data(), data_.size(), out, out_size, out_stride))
|
||||
{
|
||||
throw image_load_error("webp_loader: decoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::read_rgb(unsigned char *out, const size_t out_size, const int out_stride) const
|
||||
{
|
||||
if (!WebPDecodeRGBInto(data_.data(), data_.size(), out, out_size, out_stride))
|
||||
{
|
||||
throw image_load_error("webp_loader: decoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void webp_loader::read_bgr(unsigned char *out, const size_t out_size, const int out_stride) const
|
||||
{
|
||||
if (!WebPDecodeBGRInto(data_.data(), data_.size(), out, out_size, out_stride))
|
||||
{
|
||||
throw image_load_error("webp_loader: decoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_WEBP_SUPPORT
|
||||
|
||||
#endif // DLIB_WEBP_LOADER_CPp_
|
||||
|
@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Martin Sandsmark, Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_WEBP_IMPORT
|
||||
#define DLIB_WEBP_IMPORT
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webp_loader_abstract.h"
|
||||
#include "image_loader.h"
|
||||
#include "../pixel.h"
|
||||
#include "../dir_nav.h"
|
||||
#include "../test_for_odr_violations.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
class webp_loader : noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
webp_loader(const char* filename);
|
||||
webp_loader(const std::string& filename);
|
||||
webp_loader(const dlib::file& f);
|
||||
webp_loader(const unsigned char* imgbuffer, size_t buffersize);
|
||||
|
||||
template<typename image_type>
|
||||
void get_image(image_type& image) const
|
||||
{
|
||||
#ifndef DLIB_WEBP_SUPPORT
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
You are getting this error because you are trying to use the webp_loader
|
||||
object but you haven't defined DLIB_WEBP_SUPPORT. You must do so to use
|
||||
this object. You must also make sure you set your build environment
|
||||
to link against the libwebp library.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
|
||||
static_assert(sizeof(image_type) == 0, "webp support not enabled.");
|
||||
#endif
|
||||
image_view<image_type> vimg(image);
|
||||
vimg.set_size(height_, width_);
|
||||
typedef typename image_traits<image_type>::pixel_type pixel_type;
|
||||
|
||||
unsigned char* output = reinterpret_cast<unsigned char*>(image_data(vimg));
|
||||
const int stride = width_step(vimg);
|
||||
const size_t output_size = stride * height_;
|
||||
|
||||
if (pixel_traits<pixel_type>::rgb_alpha)
|
||||
{
|
||||
if (pixel_traits<pixel_type>::bgr_layout)
|
||||
read_bgra(output, output_size, stride);
|
||||
else
|
||||
read_rgba(output, output_size, stride);
|
||||
return;
|
||||
}
|
||||
if (pixel_traits<pixel_type>::rgb)
|
||||
{
|
||||
if (pixel_traits<pixel_type>::bgr_layout)
|
||||
read_bgr(output, output_size, stride);
|
||||
else
|
||||
read_rgb(output, output_size, stride);
|
||||
return;
|
||||
}
|
||||
// If we end up here, we are out of our fast path, and have to do it manually
|
||||
|
||||
array2d<rgb_alpha_pixel> decoded;
|
||||
decoded.set_size(height_, width_);
|
||||
unsigned char* output_dec = reinterpret_cast<unsigned char*>(image_data(decoded));
|
||||
const int stride_dec = width_step(decoded);
|
||||
const size_t output_dec_size = stride_dec * height_;
|
||||
|
||||
read_rgba(output_dec, output_dec_size, stride_dec);
|
||||
|
||||
for (int r = 0; r < height_; r++)
|
||||
{
|
||||
for (int c = 0; c < width_; c++)
|
||||
{
|
||||
assign_pixel(vimg[r][c], decoded[r][c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void get_info();
|
||||
void read_bgra(unsigned char *out, const size_t out_size, const int out_stride) const;
|
||||
void read_bgr(unsigned char *out, const size_t out_size, const int out_stride) const;
|
||||
void read_rgba(unsigned char *out, const size_t out_size, const int out_stride) const;
|
||||
void read_rgb(unsigned char *out, const size_t out_size, const int out_stride) const;
|
||||
void read_argb(unsigned char *out, const size_t out_size, const int out_stride) const;
|
||||
|
||||
int height_;
|
||||
int width_;
|
||||
std::vector<unsigned char> data_;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const std::string& file_name
|
||||
)
|
||||
{
|
||||
webp_loader(file_name).get_image(image);
|
||||
}
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const unsigned char* imgbuff,
|
||||
size_t imgbuffsize
|
||||
)
|
||||
{
|
||||
webp_loader(imgbuff, imgbuffsize).get_image(image);
|
||||
}
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const char* imgbuff,
|
||||
size_t imgbuffsize
|
||||
)
|
||||
{
|
||||
webp_loader(reinterpret_cast<const unsigned char*>(imgbuff), imgbuffsize).get_image(image);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "webp_loader.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_WEBP_IMPORT
|
||||
|
||||
|
@ -0,0 +1,155 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Martin Sandsmark, Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_WEBP_IMPORT_ABSTRACT
|
||||
#ifdef DLIB_WEBP_IMPORT_ABSTRACT
|
||||
|
||||
#include "image_loader_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../pixel.h"
|
||||
#include "../dir_nav.h"
|
||||
#include "../image_processing/generic_image.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
class webp_loader : noncopyable
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a class capable of loading WEBP image files.
|
||||
Once an instance of it is created to contain a WEBP file from
|
||||
disk you can obtain the image stored in it via get_image().
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
webp_loader(
|
||||
const char* filename
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- loads the WEBP file with the given file name into this object
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- image_load_error
|
||||
This exception is thrown if there is some error that prevents
|
||||
us from loading the given WEBP file.
|
||||
!*/
|
||||
|
||||
webp_loader(
|
||||
const std::string& filename
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- loads the WEBP file with the given file name into this object
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- image_load_error
|
||||
This exception is thrown if there is some error that prevents
|
||||
us from loading the given WEBP file.
|
||||
!*/
|
||||
|
||||
webp_loader(
|
||||
const dlib::file& f
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- loads the WEBP file with the given file name into this object
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- image_load_error
|
||||
This exception is thrown if there is some error that prevents
|
||||
us from loading the given WEBP file.
|
||||
!*/
|
||||
|
||||
webp_loader(
|
||||
const unsigned char* imgbuffer,
|
||||
size_t buffersize
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- loads the WEBP from memory imgbuffer of size buffersize into this object
|
||||
throws
|
||||
- image_load_error
|
||||
This exception is thrown if there is some error that prevents
|
||||
us from loading the given WEBP buffer.
|
||||
!*/
|
||||
|
||||
~webp_loader(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all resources associated with *this has been released
|
||||
!*/
|
||||
|
||||
template<
|
||||
typename image_type
|
||||
>
|
||||
void get_image(
|
||||
image_type& img
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- image_type == an image object that implements the interface defined in
|
||||
dlib/image_processing/generic_image.h
|
||||
ensures
|
||||
- loads the WEBP image stored in this object into img
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const std::string& file_name
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- image_type == an image object that implements the interface defined in
|
||||
dlib/image_processing/generic_image.h
|
||||
ensures
|
||||
- performs: webp_loader(file_name).get_image(image);
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const unsigned char* imgbuff,
|
||||
size_t imgbuffsize
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- image_type == an image object that implements the interface defined in
|
||||
dlib/image_processing/generic_image.h
|
||||
ensures
|
||||
- performs: webp_loader(imgbuff, imgbuffsize).get_image(image);
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void load_webp (
|
||||
image_type& image,
|
||||
const char* imgbuff,
|
||||
size_t imgbuffsize
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- image_type == an image object that implements the interface defined in
|
||||
dlib/image_processing/generic_image.h
|
||||
ensures
|
||||
- performs: webp_loader((unsigned char*)imgbuff, imgbuffsize).get_image(image);
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_WEBP_IMPORT_ABSTRACT
|
||||
|
@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_WEBP_SAVER_CPp_
|
||||
#define DLIB_WEBP_SAVER_CPp_
|
||||
|
||||
// only do anything with this file if DLIB_WEBP_SUPPORT is defined
|
||||
#ifdef DLIB_WEBP_SUPPORT
|
||||
|
||||
#include "save_webp.h"
|
||||
#include "image_saver.h"
|
||||
#include <sstream>
|
||||
|
||||
#include <webp/encode.h>
|
||||
|
||||
namespace dlib {
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace impl
|
||||
{
|
||||
void impl_save_webp (
|
||||
const std::string& filename,
|
||||
const uint8_t* data,
|
||||
const int width,
|
||||
const int height,
|
||||
const int stride,
|
||||
const float quality,
|
||||
const webp_type type
|
||||
)
|
||||
{
|
||||
if (width > WEBP_MAX_DIMENSION || height > WEBP_MAX_DIMENSION)
|
||||
throw image_save_error("Error while encoding " + filename + ". Bad picture dimensions: "
|
||||
+ std::to_string(width) + "x" + std::to_string(height)
|
||||
+ ". Maximum WebP width and height allowed is "
|
||||
+ std::to_string(WEBP_MAX_DIMENSION) + " pixels");
|
||||
|
||||
std::ofstream fout(filename, std::ios::binary);
|
||||
if (!fout.good())
|
||||
throw image_save_error("Unable to open " + filename + " for writing.");
|
||||
|
||||
uint8_t* output;
|
||||
size_t output_size = 0;
|
||||
switch (type)
|
||||
{
|
||||
case webp_type::rgb:
|
||||
if (quality > 100)
|
||||
output_size = WebPEncodeLosslessRGB(data, width, height, stride, &output);
|
||||
else
|
||||
output_size = WebPEncodeRGB(data, width, height, stride, quality, &output);
|
||||
break;
|
||||
case webp_type::rgba:
|
||||
if (quality > 100)
|
||||
output_size = WebPEncodeLosslessRGBA(data, width, height, stride, &output);
|
||||
else
|
||||
output_size = WebPEncodeRGBA(data, width, height, stride, quality, &output);
|
||||
break;
|
||||
case webp_type::bgr:
|
||||
if (quality > 100)
|
||||
output_size = WebPEncodeLosslessBGR(data, width, height, stride, &output);
|
||||
else
|
||||
output_size = WebPEncodeBGR(data, width, height, stride, quality, &output);
|
||||
break;
|
||||
case webp_type::bgra:
|
||||
if (quality > 100)
|
||||
output_size = WebPEncodeLosslessBGRA(data, width, height, stride, &output);
|
||||
else
|
||||
output_size = WebPEncodeBGRA(data, width, height, stride, quality, &output);
|
||||
break;
|
||||
default:
|
||||
throw image_save_error("Invalid WebP color type");
|
||||
}
|
||||
|
||||
if (output_size > 0)
|
||||
{
|
||||
fout.write(reinterpret_cast<char*>(output), output_size);
|
||||
if (!fout.good())
|
||||
throw image_save_error("Error while writing WebP image to " + filename + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw image_save_error("Error while encoding WebP image to " + filename + ".");
|
||||
}
|
||||
WebPFree(output);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_WEBP_SUPPORT
|
||||
|
||||
#endif // DLIB_WEBP_SAVER_CPp_
|
||||
|
@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SAVE_WEBP_Hh_
|
||||
#define DLIB_SAVE_WEBP_Hh_
|
||||
|
||||
#include "save_webp_abstract.h"
|
||||
|
||||
#include "../enable_if.h"
|
||||
#include "image_saver.h"
|
||||
#include "../matrix.h"
|
||||
#include "../array2d.h"
|
||||
#include "../pixel.h"
|
||||
#include "../image_processing/generic_image.h"
|
||||
#include <string>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace impl
|
||||
{
|
||||
enum class webp_type
|
||||
{
|
||||
rgb,
|
||||
bgr,
|
||||
rgba,
|
||||
bgra
|
||||
};
|
||||
|
||||
void impl_save_webp (
|
||||
const std::string& filename,
|
||||
const uint8_t* data,
|
||||
const int width,
|
||||
const int height,
|
||||
const int stride,
|
||||
const float quality,
|
||||
const webp_type type
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
typename disable_if<is_matrix<image_type>>::type save_webp (
|
||||
const image_type& img_,
|
||||
const std::string& filename,
|
||||
float quality = 75
|
||||
)
|
||||
{
|
||||
#ifndef DLIB_WEBP_SUPPORT
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
You are getting this error because you are trying to use the save_webp
|
||||
function but you haven't defined DLIB_WEBP_SUPPORT. You must do so to use
|
||||
this object. You must also make sure you set your build environment
|
||||
to link against the libwebp library.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
|
||||
static_assert(sizeof(image_type) == 0, "webp support not enabled.");
|
||||
#endif
|
||||
const_image_view<image_type> img(img_);
|
||||
using pixel_type = typename image_traits<image_type>::pixel_type;
|
||||
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(img.size() != 0,
|
||||
"\t save_webp()"
|
||||
<< "\n\t You can't save an empty image as a WEBP."
|
||||
);
|
||||
DLIB_CASSERT(0 <= quality,
|
||||
"\t save_webp()"
|
||||
<< "\n\t Invalid quality value."
|
||||
<< "\n\t quality: " << quality
|
||||
);
|
||||
|
||||
auto data = reinterpret_cast<const uint8_t*>(image_data(img));
|
||||
const int width = img.nc();
|
||||
const int height = img.nr();
|
||||
const int stride = width_step(img);
|
||||
if (pixel_traits<pixel_type>::rgb_alpha)
|
||||
{
|
||||
if (pixel_traits<pixel_type>::bgr_layout)
|
||||
impl::impl_save_webp(filename, data, width, height, stride, quality, impl::webp_type::bgra);
|
||||
else
|
||||
impl::impl_save_webp(filename, data, width, height, stride, quality, impl::webp_type::rgba);
|
||||
}
|
||||
else if (pixel_traits<pixel_type>::rgb)
|
||||
{
|
||||
if (pixel_traits<pixel_type>::bgr_layout)
|
||||
impl::impl_save_webp(filename, data, width, height, stride, quality, impl::webp_type::bgr);
|
||||
else
|
||||
impl::impl_save_webp(filename, data, width, height, stride, quality, impl::webp_type::rgb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is some other kind of color image so just save it as an RGB image.
|
||||
array2d<rgb_pixel> temp;
|
||||
assign_image(temp, img);
|
||||
auto data = reinterpret_cast<const uint8_t*>(image_data(temp));
|
||||
impl::impl_save_webp(filename, data, width, height, stride, quality, impl::webp_type::rgb);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename EXP
|
||||
>
|
||||
void save_webp(
|
||||
const matrix_exp<EXP>& img,
|
||||
const std::string& filename,
|
||||
float quality = 75
|
||||
)
|
||||
{
|
||||
array2d<typename EXP::type> temp;
|
||||
assign_image(temp, img);
|
||||
save_webp(temp, filename, quality);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_WEBP_SUPPORT
|
@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2022 Davis E. King (davis@dlib.net), Adrià Arrufat
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SAVE_WEBP_ABSTRACT_Hh_
|
||||
#ifdef DLIB_SAVE_WEBP_ABSTRACT_Hh_
|
||||
|
||||
#include "../image_processing/generic_image.h"
|
||||
#include "../pixel.h"
|
||||
#include <string>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename image_type
|
||||
>
|
||||
void save_webp (
|
||||
const image_type& img,
|
||||
const std::string& filename,
|
||||
float quality = 75
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- image_type == an image object that implements the interface defined in
|
||||
dlib/image_processing/generic_image.h or a matrix expression
|
||||
- image.size() != 0
|
||||
- quality >= 0
|
||||
ensures
|
||||
- writes the image to the file indicated by filename in the WEBP format.
|
||||
- image[0][0] will be in the upper left corner of the image.
|
||||
- image[image.nr()-1][image.nc()-1] will be in the lower right corner of the
|
||||
image.
|
||||
- This routine can save images containing any type of pixel. However,
|
||||
save_webp() can only natively store rgb_pixel, bgr_pixel, rgb_alpha_pixel and
|
||||
bgr_alpha_pixel pixel types. All other pixel types will be converted into one
|
||||
of these types as appropriate before being saved to disk.
|
||||
- The quality value determines how lossy the compression is. Larger quality
|
||||
values result in larger output images but the images will look better. A value
|
||||
between 0 and 100 will use lossy compression, while any value larger than
|
||||
100 will perform lossless compression.
|
||||
throws
|
||||
- image_save_error
|
||||
This exception is thrown if there is an error that prevents us from saving
|
||||
the image.
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SAVE_WEBP_ABSTRACT_Hh_
|
||||
|
Loading…
Reference in new issue