22 #ifndef CRNIMAGE_HEADER
23 #define CRNIMAGE_HEADER
30 #include <type_traits>
37 #define FOREACHPIXEL(x, y, img) for (size_t y = 0; y < (img).GetHeight(); y++) for (size_t x = 0; x < (img).GetWidth(); x++)
60 virtual std::unique_ptr<ImageBase>
Clone()
const = 0;
65 virtual void SaveJPEG(
const Path &fname,
unsigned int qual)
const = 0;
94 #ifdef CRN_USING_GDIPLUS
96 static std::unique_ptr<gditoken> gdiinit;
101 using SImage = std::shared_ptr<ImageBase>;
102 using SCImage = std::shared_ptr<const ImageBase>;
104 using WCImage = std::weak_ptr<const ImageBase>;
105 using UImage = std::unique_ptr<ImageBase>;
106 using UCImage = std::unique_ptr<const ImageBase>;
160 template<
typename Y>
explicit Image(
const Image<Y> &img);
162 explicit Image(
const Image<
typename BoolNotBool<T>::type> &img);
164 template<
typename Y>
Image(
const Image<Y> &img,
const Rect &bbox);
166 Image(
const Image<
typename BoolNotBool<T>::type> &img,
const Rect &bbox);
171 virtual ~Image()
override =
default;
180 template<
typename Y>
void Assign(
const Image<Y> &img);
184 virtual std::unique_ptr<ImageBase>
Clone()
const override {
return std::make_unique<Image>(*this); }
195 virtual void SavePNG(
const Path &fname)
const override;
197 virtual void SaveJPEG(
const Path &fname,
unsigned int qual)
const override;
211 typename std::vector<pixel_type>::iterator
begin() {
return pixels.begin(); }
212 typename std::vector<pixel_type>::const_iterator
begin()
const {
return pixels.begin(); }
213 typename std::vector<pixel_type>::iterator
end() {
return pixels.end(); }
214 typename std::vector<pixel_type>::const_iterator
end()
const {
return pixels.end(); }
215 typename std::vector<pixel_type>::const_iterator
cbegin()
const {
return pixels.begin(); }
216 typename std::vector<pixel_type>::const_iterator
cend()
const {
return pixels.end(); }
219 inline typename std::vector<pixel_type>::pointer
GetPixels() noexcept {
return pixels.data(); }
221 inline typename std::vector<pixel_type>::const_pointer
GetPixels() const noexcept {
return pixels.data(); }
224 inline typename std::vector<pixel_type>::reference
At(
size_t x,
size_t y) noexcept {
return pixels[x + y *
width]; }
226 inline typename std::vector<pixel_type>::reference
At(
size_t offset) noexcept {
return pixels[offset]; }
228 inline typename std::vector<pixel_type>::const_reference
At(
size_t x,
size_t y)
const noexcept {
return pixels[x + y *
width]; }
230 inline typename std::vector<pixel_type>::const_reference
At(
size_t offset)
const noexcept {
return pixels[offset]; }
262 template<
typename Y>
void Blit(
const Image<Y> &src,
const Rect &srczone,
size_t dx,
size_t dy);
275 virtual void ScaleToSize(
size_t w,
size_t h)
override;
281 template<
typename CMP = std::less<pixel_type>>
void Dilate(
const MatrixInt &strel, CMP cmp = std::less<pixel_type>{});
283 template<
typename CMP = std::less<pixel_type>>
void Erode(
const MatrixInt &strel, CMP cmp = std::less<pixel_type>{});
285 template<
typename CMP = std::less<pixel_type>>
void FastDilate(
size_t halfwin,
size_t index = 0, CMP cmp = std::less<pixel_type>{});
287 template<
typename CMP = std::less<pixel_type>>
void FastErode(
size_t halfwin,
size_t index = 0, CMP cmp = std::less<pixel_type>{});
290 void Convolve(
const MatrixDouble &mat);
306 template<
typename T,
typename CMP = std::less<T>> std::pair<T, T>
MinMax(
const Image<T> &img, CMP cmp = CMP{});
309 template<
typename T> Rect
AutoCrop(
const Image<T> &img,
const T &bgval);
311 template<
typename T> Image<T>
MakeAutoCrop(
const Image<T> &img,
const T &bgval);
314 template<
typename T,
typename Y> Point2DInt
CrossCorrelation(
const Image<T> &img1,
const Image<Y> &img2, T fill1 = T(0), Y fill2 = Y(0));
321 template<
typename IMG,
typename T> IMG
Downgrade(
const Image<T> &img);
327 template<
typename T> Image<T>
MakeRotation(
const Image<T> &img,
const Angle<Degree> &angle,
const T &bgColor);
329 template<
typename T> Image<T>
Make90Rotation(
const Image<T> &img);
335 template<
typename T>
inline auto Size(
const Image<T> &img) noexcept(noexcept(img.
Size())) -> decltype(img.
Size()) {
return img.
Size(); }
366 using new_pixel =
typename IMG::pixel_type;
367 using common_pixel =
typename std::common_type<T, new_pixel>::type;
370 const auto mM =
MinMax(img);
371 if ((common_pixel(mM.first) < common_pixel(std::numeric_limits<new_pixel>::lowest())) ||
372 (common_pixel(mM.second) > common_pixel(std::numeric_limits<new_pixel>::max())))
374 for (
auto tmp :
Range(img))
376 auto val = common_pixel(img.
At(tmp)) - common_pixel(mM.first);
377 val = (val * common_pixel(std::numeric_limits<new_pixel>::max())) / common_pixel(mM.second - mM.first);
378 res.At(tmp) = new_pixel(val);
383 for (
auto tmp :
Range(img))
384 res.At(tmp) = new_pixel(img.
At(tmp));
396 using new_pixel =
typename IMG::pixel_type;
397 using new_base =
typename new_pixel::type;
398 using common_base =
typename std::common_type<T, typename new_pixel::type>::type;
402 auto m = std::numeric_limits<T>::max();
403 auto M = std::numeric_limits<T>::lowest();
404 for (
const auto &p : img)
406 if (p.r < m) m = p.r;
407 if (p.g < m) m = p.g;
408 if (p.b < m) m = p.b;
409 if (p.r > M) M = p.r;
410 if (p.g > M) M = p.g;
411 if (p.b > M) M = p.b;
413 if ((common_base(m) < common_base(std::numeric_limits<new_base>::lowest())) ||
414 (common_base(M) > common_base(std::numeric_limits<new_base>::max())))
416 for (
auto tmp :
Range(img))
418 auto val = common_pixel(img.At(tmp)) - common_pixel(m);
419 val = (val * common_base(std::numeric_limits<new_base>::max())) / common_base(M - m);
420 res.At(tmp) = new_pixel(val);
425 for (
auto tmp :
Range(img))
426 res.At(tmp) = new_pixel(img.At(tmp));
458 SavePNG(Downgrade<ImageRGB>(img), fname);
467 SaveJPEG(Downgrade<ImageRGB>(img), fname, qual);
474 template<
typename T>
void SavePNG(
const Image<T> &img,
const Path &fname,
typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy =
nullptr)
476 SavePNG(Downgrade<ImageGray>(img), fname);
483 template<
typename T>
void SaveJPEG(
const Image<T> &img,
const Path &fname,
unsigned int qual,
typename std::enable_if<std::is_arithmetic<T>::value>::type *dummy =
nullptr)
485 SaveJPEG(Downgrade<ImageGray>(img), fname, qual);
493 template<
typename T>
void SavePNG(
const Image<T> &img,
const Path &fname,
typename std::enable_if<!std::is_arithmetic<T>::value>::type *dummy =
nullptr)
504 template<
typename T>
void SaveJPEG(
const Image<T> &img,
const Path &fname,
unsigned int qual,
typename std::enable_if<!std::is_arithmetic<T>::value>::type *dummy =
nullptr)
virtual std::unique_ptr< ImageBase > Clone() const =0
BoolNotBoolDummy operator-(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
void GaussianBlur(double sigma)
Gaussian blur.
Abstract class for images.
void Dilate(const MatrixInt &strel, CMP cmp=std::less< pixel_type >{})
Morphological dilatation.
crn::Image< crn::SumType< typename std::common_type< T1, T2 >::type > > operator*(const crn::Image< T1 > &i1, const crn::Image< T2 > &i2)
std::vector< pixel_type >::reference At(size_t offset) noexcept
Returns a reference to a pixel.
std::shared_ptr< const ImageBase > SCImage
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
BoolNotBoolDummy & operator+=(const BoolNotBoolDummy &)
void ScanFill(size_t x, size_t y, const pixel_type &val, crn::DistanceType dist=crn::DistanceType::D4)
Fills a portion of the image.
Orientation
An enumeration of orientations.
virtual void SaveJPEG(const Path &fname, unsigned int qual) const =0
Saves as JPEG file.
virtual void ScaleToSize(size_t w, size_t h)=0
Scales the image.
std::vector< pixel_type >::const_pointer GetPixels() const noexcept
Gets a const pointer to the pixels.
void Assign(const Image< Y > &img)
Force copy operator (pixel cast)
UImageBW NewImageBWFromFile(const Path &fname)
Loads an image from a file and converts it if necessary.
virtual void SavePNG(const Path &fname) const =0
Saves as PNG file.
std::vector< pixel_type >::reference At(size_t x, size_t y) noexcept
Returns a reference to a pixel.
Image< T > MakeRotation(const Image< T > &img, const Angle< Degree > &angle, const T &bgColor)
Creates a rotated version of the image.
size_t GetHeight() const noexcept
std::vector< pixel_type > pixels
std::vector< pixel_type >::const_iterator begin() const
std::vector< pixel_type >::const_reference At(size_t offset) const noexcept
Returns a reference to a pixel.
Rect AutoCrop(const Image< T > &img, const T &bgval)
Estimates the ideal crop for the image.
std::unique_ptr< ImageBase > UImage
std::vector< pixel_type >::const_iterator cbegin() const
std::weak_ptr< const ImageBase > WCImage
std::vector< pixel_type >::const_iterator end() const
virtual std::unique_ptr< ImageBase > Clone() const override
void Flip(const Orientation &ori)
Flips the image.
void SavePNG(const ImageBW &img, const Path &fname)
Saves as PNG file.
crn::Image< crn::SumType< typename std::common_type< T1, T2 >::type > > operator/(const crn::Image< T1 > &i1, const crn::Image< T2 > &i2)
std::vector< pixel_type >::const_iterator cend() const
std::vector< pixel_type >::iterator end()
void Erode(const MatrixInt &strel, CMP cmp=std::less< pixel_type >{})
Morphological erosion.
Image & operator*=(double f)
Multiplies all pixels.
crn::Image< crn::DiffType< typename std::common_type< T1, T2 >::type > > operator-(const crn::Image< T1 > &i1, const crn::Image< T2 > &i2)
BoolNotBoolDummy(int i=0)
void Swap(Image &other)
Swaps two images.
UImageGray NewImageGrayFromFile(const Path &fname)
Loads an image from a file and converts it if necessary.
size_t Size(const Vector &v) noexcept
Size of a vector.
bool operator!=(const Image &other) const
Tests equality.
Image< T > Make270Rotation(const Image< T > &img)
Creates a rotated version of the image.
void FastDilate(size_t halfwin, size_t index=0, CMP cmp=std::less< pixel_type >{})
Morphological dilatation.
Image & operator/=(const Image &img)
Divides by another image's pixels.
Image & operator=(const Image &img)=default
Copy operator.
UImageRGB NewImageRGBFromFile(const Path &fname)
Loads an image from a file and converts it if necessary.
A convenience class for file paths.
bool IsBitonal(const Image< T > &img)
Is the image binary (black & white)?
Image & operator+=(const Image &img)
Adds another image.
BoolNotBoolDummy operator*(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
ImageBase & operator=(const ImageBase &)=default
SummedAreaTable< SumType< T > > MakeSummedAreaTable(const Image< T > &img)
Creates a summed area table of the image.
BoolNotBoolDummy operator+(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
crn::Image< crn::SumType< typename std::common_type< T1, T2 >::type > > operator+(const crn::Image< T1 > &i1, const crn::Image< T2 > &i2)
Image & operator-=(const Image &img)
Subtracts another image.
Image< T > Make90Rotation(const Image< T > &img)
Creates a rotated version of the image.
Point2DInt CrossCorrelation(const Image< T > &img1, const Image< Y > &img2, T fill1=T(0), Y fill2=Y(0))
Best match between two images.
virtual void SavePNG(const Path &fname) const override
Saves as PNG file.
void Convolve(const MatrixDouble &mat)
Convolution.
void DrawLine(size_t x1, size_t y1, size_t x2, size_t y2, pixel_type color)
Draws a line using a specified color.
virtual void SaveJPEG(const Path &fname, unsigned int qual) const override
Saves as JPEG file.
std::unique_ptr< const ImageBase > UCImage
DistanceType
An enumeration of distances.
UImage NewImageFromFile(const Path &fname)
Loads an image from a file.
std::vector< pixel_type >::iterator begin()
std::weak_ptr< ImageBase > WImage
Image()
Default constructor.
Rect GetBBox() const noexcept
BoolNotBoolDummy operator/(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
IMG Downgrade(const Image< T > &img)
Converts the image to a type that has a smaller pixel range.
void Complement(pixel_type maxval=std::numeric_limits< pixel_type >::max())
Complement.
void Blit(const Image< Y > &src, const Rect &srczone, size_t dx, size_t dy)
Copies a part of an image.
std::pair< T, T > MinMax(const Image< T > &img, CMP cmp=CMP{})
Returns min and max pixel values.
void SaveJPEG(const ImageBW &img, const Path &fname, unsigned int qual)
Saves as JPEG file.
size_t GetWidth() const noexcept
#define CRN_DECLARE_CLASS_CONSTRUCTOR(classname)
Declares a class constructor.
size_t Size() const noexcept
MAT ToMatrix() const
Converts to matrix.
Image< T > MakeAutoCrop(const Image< T > &img, const T &bgval)
Creates a new image as the ideal crop for the image.
std::shared_ptr< ImageBase > SImage
std::vector< pixel_type >::pointer GetPixels() noexcept
Gets a pointer to the pixels.
Image< T > Make180Rotation(const Image< T > &img)
Creates a rotated version of the image.
void DrawRect(const Rect &r, pixel_type color, bool filled=false)
Draws a rectangle using a specified color.
ImageBase(size_t w, size_t h)
virtual void ScaleToSize(size_t w, size_t h) override
Scales the image.
bool operator==(const Image &other) const
Tests equality.
std::vector< pixel_type >::const_reference At(size_t x, size_t y) const noexcept
Returns a reference to a pixel.
virtual ~Image() override=default
Destructor.
void FastErode(size_t halfwin, size_t index=0, CMP cmp=std::less< pixel_type >{})
Morphological erosion.
Invalid argument error (e.g.: nullptr pointer)
void FloodFill(size_t x, size_t y, const pixel_type &val, crn::DistanceType dist=crn::DistanceType::D4)
Flood fills a portion of the image.