Enrollment 28.2.0
Loading...
Searching...
No Matches
Image.h
Go to the documentation of this file.
1
9#pragma once
10
12#include "enrollment/Export.h"
21#include <ciso646>
22#include <mutex>
23#include <optional>
24#include <variant>
25#include <vector>
26
27namespace inno
28{
29
33 */
34 class Image
35 {
36 public:
48 */
49 static std::shared_ptr<Image> Decode(const std::vector<uint8_t>& imageData)
50 {
51 return Decode(imageData, static_cast<unsigned int>(DefaultDpi), GlobalImageExecutor::Get());
52 }
53
65 */
66 static std::shared_ptr<Image> Decode(const std::vector<uint8_t>& imageData, unsigned int dpi)
67 {
68 return Decode(imageData, dpi, GlobalImageExecutor::Get());
69 }
70
82 */
83 static std::shared_ptr<Image> Decode(const std::vector<uint8_t>& imageData,
84 std::shared_ptr<ImageExecutor> executor)
85 {
86 return Decode(imageData, static_cast<unsigned int>(DefaultDpi), std::move(executor));
87 }
88
100 */
101 static std::shared_ptr<Image> Decode(const std::vector<uint8_t>& imageData,
102 unsigned int dpi,
103 std::shared_ptr<ImageExecutor> executor)
104 {
105 if (executor == nullptr)
106 {
107 throw NullArgumentException("executor can not be null");
108 }
109
110 const ImageType type = DeduceType(imageData);
111
112 auto* impl = executor->Create(imageData.data(), imageData.size(), dpi, ThrowOnError{});
113
114 if (impl == nullptr)
115 {
117 }
118
119 std::shared_ptr<ImageEncoder> encoder = ImageEncoder::Create(type);
120
121 return SharedImage(impl, std::move(encoder), std::move(executor));
122 }
123
124 /// Enum define possible intersection of Image and some Object e.g. Rectangle, Circle.
125 enum class Intersection : uint8_t
126 {
128 PARTIAL,
130 INSIDE,
132 OUTSIDE,
134 NO,
136 SAME
137 };
144 */
145 [[nodiscard]] Intersection RectangleIntersection(const Rectangle& rectangle) const
146 {
147 auto result = static_cast<Intersection>(exec->IntersectionRectangle(impl.get(),
148 rectangle.GetTopLeft().x,
149 rectangle.GetTopLeft().y,
150 rectangle.GetTopRight().x,
151 rectangle.GetTopRight().y,
152 rectangle.GetBottomRight().x,
153 rectangle.GetBottomRight().y,
154 rectangle.GetBottomLeft().x,
155 rectangle.GetBottomLeft().y,
156 ThrowOnError{}));
157
158 return result;
159 }
160
167 */
168 [[nodiscard]] Intersection CircleIntersection(const Circle& circle) const
169 {
170 auto result = static_cast<Intersection>(
171 exec->IntersectionCircle(impl.get(), circle.center.x, circle.center.y, circle.radius, ThrowOnError{}));
172
173 return result;
174 }
175
181 */
182 [[nodiscard]] Intersection PointIntersection(const Point& point) const
183 {
184 auto result =
185 static_cast<Intersection>(exec->IntersectionPoint(impl.get(), point.x, point.y, ThrowOnError{}));
186
187 return result;
188 }
189
200 */
201 static std::shared_ptr<Image> DecodeRawImage(
202 const RawImage& raw,
203 std::shared_ptr<ImageEncoder> originalEncoder = nullptr,
204 std::shared_ptr<ImageExecutor> executor = GlobalImageExecutor::Get())
205 {
206 auto* impl = executor->CreateRaw(
207 raw.width, raw.height, static_cast<unsigned int>(raw.dpi), raw.type, raw.Data().data(), ThrowOnError{});
208
209 if (originalEncoder != nullptr)
210 {
211 return SharedImage(impl, std::move(originalEncoder), std::move(executor));
212 }
213
214 std::shared_ptr<ImageEncoder> encoder = std::make_shared<IRawImageEncoder>();
215
216 return SharedImage(impl, std::move(encoder), std::move(executor));
217 }
218
226 */
227 static ImageType DeduceType(const std::vector<uint8_t>& imageData)
228 {
229 auto type = inno_local_Image_DeduceType(imageData.data(), imageData.size(), ThrowOnError{});
230 auto result = ImageType{ type };
231
232 return result;
233 }
234
238 */
239 [[nodiscard]] ImageDpi Dpi() const
240 {
241 return ImageDpi{ exec->Dpi(impl.get()) };
242 }
243
247 */
248 [[nodiscard]] ImageWidth Width() const
249 {
250 return exec->Width(impl.get());
251 }
252
256 */
257 [[nodiscard]] ImageHeight Height() const
258 {
259 return exec->Height(impl.get());
260 }
261
265 */
266 [[nodiscard]] std::shared_ptr<ImageEncoder> OriginalEncoder() const
267 {
268 return originalEncoder;
269 }
270
275 */
276 [[nodiscard]] RawImage AsRawImage() const
277 {
278 auto size = exec->RawSize(impl.get());
279 std::vector<uint8_t> raw(size, 0);
280 unsigned int type = 0;
281
282 exec->ToRaw(impl.get(), raw.data(), size, &type, ThrowOnError{});
283
284 return { Width(), Height(), Dpi(), static_cast<RawImage::Type>(type), std::move(raw) };
285 }
286
291 */
292 [[nodiscard]] RawImage AsRawGrayscale() const
293 {
294 auto size = exec->RawTypeSize(impl.get(), RawImage::Type::GRAYSCALE, ThrowOnError{});
295
296 std::vector<uint8_t> raw(size, 0);
297 exec->ToRawType(impl.get(), raw.data(), size, RawImage::Type::GRAYSCALE, ThrowOnError{});
298
299 return { Width(), Height(), Dpi(), RawImage::Type::GRAYSCALE, std::move(raw) };
300 }
301
306 */
307 [[nodiscard]] RawImage AsRawBGR() const
308 {
309 auto size = exec->RawTypeSize(impl.get(), RawImage::Type::BGR, ThrowOnError{});
310
311 std::vector<uint8_t> raw(size, 0);
312 exec->ToRawType(impl.get(), raw.data(), size, RawImage::Type::BGR, ThrowOnError{});
313
314 return { Width(), Height(), Dpi(), RawImage::Type::BGR, std::move(raw) };
315 }
316
321 */
322 [[nodiscard]] std::shared_ptr<Image> AsBGR() const
323 {
324 auto rawBgr = AsRawBGR();
325 return DecodeRawImage(rawBgr, originalEncoder, exec);
326 }
327
332 */
333 [[nodiscard]] RawImage AsRawBGRA() const
334 {
335 auto size = exec->RawTypeSize(impl.get(), RawImage::Type::BGRA, ThrowOnError{});
336
337 std::vector<uint8_t> raw(size, 0);
338 exec->ToRawType(impl.get(), raw.data(), size, RawImage::Type::BGRA, ThrowOnError{});
339
340 return { Width(), Height(), Dpi(), RawImage::Type::BGRA, std::move(raw) };
341 }
342
347 */
348 [[nodiscard]] std::shared_ptr<Image> AsBGRA() const
349 {
350 auto rawBgr = AsRawBGRA();
351 return DecodeRawImage(rawBgr, originalEncoder, exec);
352 }
353
360 */
361 [[nodiscard]] std::vector<uint8_t> EncodeIn(ImageEncoder& encoder) const
362 {
363 auto raw = AsRawImage();
364 return encoder.Encode(raw);
365 }
366
371 */
372 void SaveIn(ImageSaver& saver) const
373 {
374 auto raw = AsRawImage();
375 saver.Save(raw);
376 }
377
385 */
386 void SaveAs(const std::string& path) const
387 {
388 auto raw = AsRawImage();
389 auto saver = ImageFileSaver(path);
390 saver.Save(raw);
391 }
392
400 */
401 bool operator==(const Image& right) const
402 {
403 if (exec == nullptr && right.exec == nullptr)
404 {
405 // both images are empty
406 return true;
407 }
408 if (exec == right.exec)
409 {
410
411 auto result = exec->IsEqual(impl.get(), right.impl.get(), ThrowOnError{});
412
413 return result;
414 }
415 if (exec != nullptr && right.exec != nullptr)
416 {
417 // compare raw data
418 auto raw = AsRawImage();
419 auto rightRaw = right.AsRawImage();
420 return raw == rightRaw;
421 }
422
423 // one image is empty and one not, they are not same
424 return false;
425 }
426
435 */
436 [[nodiscard]] std::shared_ptr<Image> DrawShape(const ImageShape& shape) const
437 {
438 auto* newImpl = exec->Clone(impl.get(), ThrowOnError{});
439
440 ImplDrawer drawer(newImpl, exec);
441 shape.DrawIn(drawer);
442 drawer.DrawingFinished();
443 return SharedImage(newImpl, originalEncoder, exec);
444 }
445
458 */
459 [[nodiscard]] std::shared_ptr<Image> CropRectangle(const Rectangle& r) const
460 {
461 return CropRectangle(r, Colors::White);
462 }
463
476 */
477 [[nodiscard]] std::shared_ptr<Image> CropRectangle(const Rectangle& r, const RGBA& background) const
478 {
479 return CropRectangle(r, background, ImageDimensions{});
480 }
481
496 */
497 [[nodiscard]] std::shared_ptr<Image> CropRectangle(const Rectangle& r,
498 const RGBA& background,
499 const ImageDimensions& dimension) const
500 {
502 {
503 throw EnrollmentInvalidArgumentException("Given rectangle has no intersection with image");
504 }
505
506 auto* newImpl = exec->CropRectangle(impl.get(),
507 r.GetTopLeft().x,
508 r.GetTopLeft().y,
509 r.GetTopRight().x,
510 r.GetTopRight().y,
511 r.GetBottomRight().x,
512 r.GetBottomRight().y,
513 r.GetBottomLeft().x,
514 r.GetBottomLeft().y,
515 dimension.width,
516 dimension.height,
517 background.color.red,
518 background.color.green,
519 background.color.blue,
520 background.transparency,
521 ThrowOnError{});
522
523 return SharedImage(newImpl, originalEncoder, exec);
524 }
525
529 */
530 class ImageResampler
531 {
532 public:
540 */
541 explicit ImageResampler(ImageDpi targetDpi)
542 : dpi(targetDpi)
543 {
544 if (static_cast<unsigned int>(targetDpi) == 0)
545 {
546 throw EnrollmentInvalidArgumentException("Target DPI must be greater than 0");
547 }
548 }
549
556 [[nodiscard]] virtual std::shared_ptr<Image> Resample(const inno::Image& image) const = 0;
557
558 ImageResampler() = delete;
559 virtual ~ImageResampler() = default;
560 ImageResampler(const ImageResampler&) = default;
561 ImageResampler(ImageResampler&&) = default;
562 ImageResampler& operator=(const ImageResampler&) = default;
563 ImageResampler& operator=(ImageResampler&&) = default;
564
565 protected:
569 */
570 [[nodiscard]] ImageDpi GetDpi() const
571 {
572 return dpi;
573 }
574
575 private:
576 ImageDpi dpi;
577 };
578
583 */
585 {
586 public:
595 */
596 explicit BicubicImageResampler(ImageDpi targetDpi)
597 : ImageResampler(targetDpi)
598 {
599 }
600
607 */
608 [[nodiscard]] std::shared_ptr<Image> Resample(const inno::Image& image) const final
609 {
610 auto* newImpl =
611 image.exec->ChangeDpi(image.impl.get(), static_cast<unsigned int>(GetDpi()), ThrowOnError{});
612
613 return SharedImage(newImpl, image.originalEncoder, image.exec);
614 }
615
616 BicubicImageResampler() = delete;
617 virtual ~BicubicImageResampler() = default;
620 BicubicImageResampler& operator=(const BicubicImageResampler&) = default;
621 BicubicImageResampler& operator=(BicubicImageResampler&&) = default;
622 };
623
628 */
630 {
631 public:
641 */
642 explicit AreaImageResampler(ImageDpi targetDpi)
643 : ImageResampler(targetDpi)
644 {
645 }
646
656 */
657 [[nodiscard]] std::shared_ptr<Image> Resample(const inno::Image& image) const final
658 {
659 auto* newImpl =
660 image.exec->ChangeDpiArea(image.impl.get(), static_cast<unsigned int>(GetDpi()), ThrowOnError{});
661
662 return SharedImage(newImpl, image.originalEncoder, image.exec);
663 }
664
665 AreaImageResampler() = delete;
666 virtual ~AreaImageResampler() = default;
667 AreaImageResampler(const AreaImageResampler&) = default;
669 AreaImageResampler& operator=(const AreaImageResampler&) = default;
670 AreaImageResampler& operator=(AreaImageResampler&&) = default;
671 };
672
677 */
679 {
680 public:
681 /// Enum defines possible types of interpolation methods to apply during image resampling.
682 enum class InterpolationMethod : uint8_t
683 {
685 BICUBIC,
687 BILINEAR,
688 };
689
690 /// Enum defines possible types of filtering methods to apply before image resampling.
691 enum class FilterType : uint8_t
692 {
694 GAUSSIAN,
696 IDEAL,
697 };
698
713 */
714 explicit NISTImageResampler(ImageDpi targetDpi)
715 : ImageResampler(targetDpi)
716 {
717 }
718
746 */
747 NISTImageResampler(ImageDpi targetDpi, InterpolationMethod interpolationMethod, FilterType filterType)
748 : ImageResampler(targetDpi)
749 , interpolation(interpolationMethod)
750 , filter(filterType)
751 {
752 const auto checkInterpolationValueIsValid = [](InterpolationMethod i)
753 {
754 switch (i)
755 {
757 [[fallthrough]];
759 return;
760 }
761 throw EnrollmentInvalidArgumentException("Unknown value of interpolation method provided (" +
762 std::to_string(static_cast<int>(i)) + ")");
763 };
764
765 const auto checkFilterValueIsValid = [](FilterType f)
766 {
767 switch (f)
768 {
770 [[fallthrough]];
772 return;
773 }
774 throw EnrollmentInvalidArgumentException("Unknown value of filtering type provided (" +
775 std::to_string(static_cast<int>(f)) + ")");
776 };
777
778 checkInterpolationValueIsValid(interpolationMethod);
779 checkFilterValueIsValid(filterType);
780 }
781
790 */
791 [[nodiscard]] std::shared_ptr<Image> Resample(const inno::Image& image) const final
792 {
793 if (GetDpi() == image.Dpi())
794 {
795 throw EnrollmentInvalidArgumentException("Original and target DPI cannot be equal");
796 }
797 if (image.Channels() > 1)
798 {
800 "Only grayscale images are supported by NIST resampling algorithm");
801 }
802
803 void* newImpl = {};
804 if (interpolation.has_value() && filter.has_value())
805 {
806 newImpl = image.exec->ChangeDpiNistWithOptions(image.impl.get(),
807 static_cast<unsigned int>(GetDpi()),
808 static_cast<unsigned int>(interpolation.value()),
809 static_cast<unsigned int>(filter.value()),
810 ThrowOnError{});
811 }
812 else
813 {
814 newImpl =
815 image.exec->ChangeDpiNist(image.impl.get(), static_cast<unsigned int>(GetDpi()), ThrowOnError{});
816 }
817 return SharedImage(newImpl, image.originalEncoder, image.exec);
818 }
819
820 NISTImageResampler() = delete;
821 virtual ~NISTImageResampler() = default;
822 NISTImageResampler(const NISTImageResampler&) = default;
824 NISTImageResampler& operator=(const NISTImageResampler&) = default;
825 NISTImageResampler& operator=(NISTImageResampler&&) = default;
826
827 private:
828 std::optional<InterpolationMethod> interpolation;
829 std::optional<FilterType> filter;
830 };
831
841 */
842 [[nodiscard]] std::shared_ptr<Image> ChangeDpiTo(const ImageResampler& resampler) const
843 {
844 return resampler.Resample(*this);
845 }
846
855 */
856 [[nodiscard]] std::shared_ptr<Image> ChangeDpiTo(ImageDpi targetDpi) const
857 {
858 const BicubicImageResampler resampler{ targetDpi };
859 return ChangeDpiTo(resampler);
860 }
861
869 */
870 [[nodiscard]] std::shared_ptr<Image> Resize(float factor) const
871 {
872 if (not(factor > 0))
873 {
874 throw EnrollmentInvalidArgumentException("resize factor is not positive real number except 0");
875 }
876
877 auto* newImpl = exec->Resize(impl.get(), factor, ThrowOnError{});
878
879 return SharedImage(newImpl, originalEncoder, exec);
880 }
881
891 */
892 [[nodiscard]] std::shared_ptr<Image> ResizeToMaxDimension(ImageDimension maxDimension) const
893 {
894 auto actualMaxDimension = std::max(Width(), Height());
895 if (actualMaxDimension <= maxDimension)
896 {
897 // even if we can return this instance via std::shred_from_this, we will create new instance
898 // to keep all functions const. The std::shred_from_this cannot be used only in non const functions
899 auto result = SharedImage(exec->Clone(impl.get(), ThrowOnError{}), originalEncoder, exec);
900
901 return result;
902 }
903
904 if (maxDimension == 0)
905 {
906 return SharedImage(nullptr, originalEncoder, exec);
907 }
908
909 auto factor = static_cast<float>(maxDimension) / static_cast<float>(actualMaxDimension);
910 return Resize(factor);
911 }
912
923 */
924 [[nodiscard]] std::shared_ptr<Image> CropAlignedRectangle(const Rectangle& r) const
925 {
926 return CropAlignedRectangle(r, Colors::White);
927 }
928
940 */
941 [[nodiscard]] std::shared_ptr<Image> CropAlignedRectangle(const Rectangle& r, const RGBA& background) const
942 {
943 return CropAlignedRectangle(r, background, ImageDimensions{});
944 }
945
962 */
963 [[nodiscard]] std::shared_ptr<Image> CropAlignedRectangle(const Rectangle& r,
964 const RGBA& background,
965 const ImageDimensions& dimension) const
966 {
967 auto* newImpl = exec->CropAlignedRectangle(impl.get(),
968 r.GetTopLeft().x,
969 r.GetTopLeft().y,
970 r.GetTopRight().x,
971 r.GetTopRight().y,
972 r.GetBottomRight().x,
973 r.GetBottomRight().y,
974 r.GetBottomLeft().x,
975 r.GetBottomLeft().y,
976 r.GetWidth(),
977 r.GetHeight(),
978 dimension.width,
979 dimension.height,
980 background.color.red,
981 background.color.green,
982 background.color.blue,
983 background.transparency,
984 ThrowOnError{});
985
986 return SharedImage(newImpl, originalEncoder, exec);
987 }
988
999 */
1000 [[nodiscard]] std::shared_ptr<Image> CropCircle(const Circle& circle,
1001 const RGBA& background = Colors::White) const
1002 {
1003 if (CircleIntersection(circle) == Intersection::NO)
1004 {
1005 throw EnrollmentInvalidArgumentException("Given circle has no intersection with image");
1006 }
1007
1008 auto* newImpl = exec->CropCircle(impl.get(),
1009 circle.center.x,
1010 circle.center.y,
1011 circle.radius,
1012 background.color.red,
1013 background.color.green,
1014 background.color.blue,
1015 background.transparency,
1016 ThrowOnError{});
1017
1018 return SharedImage(newImpl, originalEncoder, exec);
1019 }
1020
1030 [[nodiscard]] std::shared_ptr<Image> MaskImageBy(const ImageMask& mask) const
1031 {
1032 auto* maskerImpl = exec->CreateMasker(impl.get(), ThrowOnError{});
1033 ImplMasker masker(maskerImpl, exec);
1034 mask.MaskWith(masker);
1035 auto* newImageImpl = masker.GetMaskedImage();
1036 return SharedImage(newImageImpl, originalEncoder, exec);
1037 }
1038
1047 [[nodiscard]] size_t Channels() const
1048 {
1049 const size_t numOfChannels = exec->Channels(impl.get(), ThrowOnError{});
1050 return numOfChannels;
1051 }
1052
1053 Image(const Image& image) = delete;
1054 Image(Image&& image) = delete;
1055 Image& operator=(const Image& image) = delete;
1056 Image& operator=(Image&& image) = delete;
1057 ~Image() = default;
1058 Image() = delete;
1059
1060 private:
1061 std::unique_ptr<void, void (*)(void*)> impl;
1062 std::shared_ptr<ImageEncoder> originalEncoder;
1063 std::shared_ptr<ImageExecutor> exec;
1064 static constexpr size_t MaxErrorMessage = 200;
1065
1066 Image(void* i, std::shared_ptr<ImageEncoder> encoder, std::shared_ptr<ImageExecutor> e)
1067 : impl(i, e->Destroy())
1068 , originalEncoder(std::move(encoder))
1069 , exec(std::move(e))
1070 {
1071 }
1072
1073 static std::shared_ptr<Image> SharedImage(void* i,
1074 std::shared_ptr<ImageEncoder> encoder,
1075 std::shared_ptr<ImageExecutor> e)
1076 {
1077 return std::shared_ptr<Image>(new Image(i, std::move(encoder), std::move(e)));
1078 }
1079
1080 class ImplDrawer : public ImageShapeDrawer
1081 {
1082 public:
1083 void DrawLine(const Line& line, const ImageShapeAttributes& attr) final
1084 {
1085 exec->DrawLine(impl,
1086 line.begin.x,
1087 line.begin.y,
1088 line.end.x,
1089 line.end.y,
1090 attr.rgba.color.red,
1091 attr.rgba.color.green,
1092 attr.rgba.color.blue,
1093 attr.rgba.transparency,
1094 attr.thickness,
1095 ThrowOnError{});
1096 }
1097
1098 void DrawCircle(const Circle& circle, const ImageShapeAttributes& attr) final
1099 {
1100 exec->DrawCircle(impl,
1101 circle.center.x,
1102 circle.center.y,
1103 circle.radius,
1104 attr.rgba.color.red,
1105 attr.rgba.color.green,
1106 attr.rgba.color.blue,
1107 attr.rgba.transparency,
1108 attr.thickness,
1109 ThrowOnError{});
1110 }
1111
1112 void DrawRectangle(const Rectangle& rect, const ImageShapeAttributes& attr) final
1113 {
1114 DrawLine(Line{ rect.GetTopLeft(), rect.GetTopRight() }, attr);
1115 DrawLine(Line{ rect.GetTopRight(), rect.GetBottomRight() }, attr);
1116 DrawLine(Line{ rect.GetBottomRight(), rect.GetBottomLeft() }, attr);
1117 DrawLine(Line{ rect.GetBottomLeft(), rect.GetTopLeft() }, attr);
1118 }
1119
1120 void DrawingFinished()
1121 {
1122 exec->DrawingFinished(impl, ThrowOnError{});
1123 }
1124
1125 ImplDrawer(void* imageImpl, std::shared_ptr<ImageExecutor> e)
1126 : impl(imageImpl)
1127 , exec(std::move(e))
1128 {
1129 }
1130
1131 ImplDrawer() = delete;
1132 ImplDrawer(const ImplDrawer&) = delete;
1133 ImplDrawer(ImplDrawer&&) = delete;
1134 ImplDrawer& operator=(const ImplDrawer&) = delete;
1135 ImplDrawer& operator=(ImplDrawer&&) = delete;
1136 virtual ~ImplDrawer() = default;
1137
1138 private:
1139 void* impl;
1140 std::shared_ptr<ImageExecutor> exec;
1141 };
1142
1143 class ImplMasker final : public ImageMasker
1144 {
1145 public:
1146 void MaskCircle(const Circle& circle, const class ImageMaskConfiguration& conf) final
1147 {
1148
1149 exec->MaskCircle(impl.get(),
1150 circle.center.x,
1151 circle.center.y,
1152 static_cast<unsigned int>(circle.radius),
1153 conf.GetMaskColor().color.red,
1154 conf.GetMaskColor().color.green,
1155 conf.GetMaskColor().color.blue,
1156 conf.GetMaskColor().transparency,
1157 static_cast<unsigned int>(conf.GetMaskType()),
1158 ThrowOnError{});
1159 }
1160
1161 void MaskPolygon(const Polygon& polygon, const class ImageMaskConfiguration& conf) final
1162 {
1163 const auto& pp = polygon.GetPoints();
1164 std::vector<int> polygonX(pp.size());
1165 std::vector<int> polygonY(pp.size());
1166 for (auto x = polygonX.begin(), y = polygonY.begin(); const auto& p : pp)
1167 {
1168 *x = p.x;
1169 *y = p.y;
1170 std::advance(x, 1);
1171 std::advance(y, 1);
1172 }
1173
1174 exec->MaskPolygon(impl.get(),
1175 polygonX.data(),
1176 polygonY.data(),
1177 pp.size(),
1178 conf.GetMaskColor().color.red,
1179 conf.GetMaskColor().color.green,
1180 conf.GetMaskColor().color.blue,
1181 conf.GetMaskColor().transparency,
1182 static_cast<unsigned int>(conf.GetMaskType()),
1183 ThrowOnError{});
1184 }
1185
1186 void BlurCircle(const Circle& circle, ImageMaskType maskType, ImageBlurType blurType) final
1187 {
1188
1189 exec->BlurCircle(impl.get(),
1190 circle.center.x,
1191 circle.center.y,
1192 static_cast<unsigned int>(circle.radius),
1193 static_cast<unsigned int>(maskType),
1194 static_cast<unsigned int>(blurType),
1195 ThrowOnError{});
1196 }
1197
1198 void BlurPolygon(const Polygon& polygon, ImageMaskType maskType, ImageBlurType blurType) final
1199 {
1200 const auto& pp = polygon.GetPoints();
1201 std::vector<int> polygonX(pp.size());
1202 std::vector<int> polygonY(pp.size());
1203 for (auto x = polygonX.begin(), y = polygonY.begin(); const auto& p : pp)
1204 {
1205 *x = p.x;
1206 *y = p.y;
1207 std::advance(x, 1);
1208 std::advance(y, 1);
1209 }
1210
1211 exec->BlurPolygon(impl.get(),
1212 polygonX.data(),
1213 polygonY.data(),
1214 pp.size(),
1215 static_cast<unsigned int>(maskType),
1216 static_cast<unsigned int>(blurType),
1217 ThrowOnError{});
1218 }
1219
1220 void AddToBlur(const Circle& circle, ImageMaskType maskType) final
1221 {
1222
1223 exec->AddCircleToBlurMask(impl.get(),
1224 circle.center.x,
1225 circle.center.y,
1226 static_cast<unsigned int>(circle.radius),
1227 static_cast<unsigned int>(maskType),
1228 ThrowOnError{});
1229 }
1230
1231 void AddToBlur(const Polygon& polygon, ImageMaskType maskType) final
1232 {
1233 const auto& pp = polygon.GetPoints();
1234 std::vector<int> polygonX(pp.size());
1235 std::vector<int> polygonY(pp.size());
1236 for (auto x = polygonX.begin(), y = polygonY.begin(); const auto& p : pp)
1237 {
1238 *x = p.x;
1239 *y = p.y;
1240 std::advance(x, 1);
1241 std::advance(y, 1);
1242 }
1243
1244 exec->AddPolygonToBlurMask(impl.get(),
1245 polygonX.data(),
1246 polygonY.data(),
1247 pp.size(),
1248 static_cast<unsigned int>(maskType),
1249 ThrowOnError{});
1250 }
1251
1252 void ApplyBlur(ImageBlurType blurType) final
1253 {
1254
1255 exec->ApplyBlur(impl.get(), static_cast<unsigned int>(blurType), ThrowOnError{});
1256 }
1257
1258 [[nodiscard]] void* GetMaskedImage() const
1259 {
1260
1261 auto* newImage = exec->MaskingFinished(impl.get(), ThrowOnError{});
1262
1263 return newImage;
1264 }
1265
1266 ImplMasker(void* imageImpl, std::shared_ptr<ImageExecutor> e)
1267 : impl(imageImpl, e->DestroyMask())
1268 , exec(std::move(e))
1269 {
1270 }
1271
1272 ImplMasker() = delete;
1273 ImplMasker(const ImplMasker&) = delete;
1274 ImplMasker(ImplMasker&&) = delete;
1275 ImplMasker& operator=(const ImplMasker&) = delete;
1276 ImplMasker& operator=(ImplMasker&&) = delete;
1277 virtual ~ImplMasker() = default;
1278
1279 private:
1280 std::unique_ptr<void, void (*)(void*)> impl;
1281 std::shared_ptr<ImageExecutor> exec;
1282 };
1283 };
1284} // namespace inno
constexpr ImageDpi DefaultDpi
Provides default DPI Default DPI is 500.
Definition ImageAttribute.h:107
It holds circle dimensions.
Definition ImageAttribute.h:691
Point center
top left
Definition ImageAttribute.h:694
Radius radius
top right
Definition ImageAttribute.h:696
Base exception for all enrollment-sdk invalid argument exceptions.
Definition EnrollmentException.h:96
static std::shared_ptr< ImageExecutor > Get()
Provides current executor.
Definition ImageExecutor.h:1570
It holds width and height of Image.
Definition ImageAttribute.h:281
ImageWidth width
width
Definition ImageAttribute.h:295
ImageHeight height
height
Definition ImageAttribute.h:297
Image DPI.
Definition ImageAttribute.h:47
Interface for image formatting converting to ImageType.
Definition ImageEncoder.h:106
static std::shared_ptr< ImageEncoder > Create(ImageType type)
Create concrete default encoder for given type.
Definition ImageEncoder.h:881
virtual std::vector< uint8_t > Encode(const RawImage &raw) const =0
Encodes given RawImage as encoded image.
Exception for image processing.
Definition ImageException.h:24
@ DECODE_IMAGE
Image type is supported but image format is corrupted.
Definition ImageException.h:39
Saves image to file.
Definition ImageEncoder.h:933
Defines the interface for applying mask to the image with a masker.
Definition ImageMask.h:193
virtual void MaskWith(ImageMasker &masker) const =0
Applies a mask to the image using the provided ImageMasker.
Interface for image saving.
Definition ImageEncoder.h:911
virtual void Save(const RawImage &raw) const =0
Encodes and saves given image.
Any type of shape that wants to be drawn.
Definition ImageShape.h:142
virtual void DrawIn(ImageShapeDrawer &drawer) const =0
It draws shape in ImageShapeDrawer.
It contains all supported image types.
Definition ImageType.h:21
Image resampler for DPI-change operations, including upsampling and downsampling using area interpola...
Definition Image.h:629
AreaImageResampler(ImageDpi targetDpi)
Constructs pixel-area-relation interpolation image resampler for a target DPI.
Definition Image.h:641
std::shared_ptr< Image > Resample(const inno::Image &image) const final
Resample image to a target DPI using pixel-area-relation interpolation.
Definition Image.h:656
Image resampler for DPI-change operations, including upsampling and downsampling using bicubic interp...
Definition Image.h:584
std::shared_ptr< Image > Resample(const inno::Image &image) const final
Resample image to a target DPI using bicubic interpolation.
Definition Image.h:607
BicubicImageResampler(ImageDpi targetDpi)
Constructs bicubic interpolation image resampler for a target DPI.
Definition Image.h:595
Image resampler for DPI-change operations, including upsampling and downsampling.
Definition Image.h:530
ImageResampler(ImageDpi targetDpi)
Constructs an image resampler for a target DPI.
Definition Image.h:540
ImageDpi GetDpi() const
Retrieves target DPI of the resampler.
Definition Image.h:569
virtual std::shared_ptr< Image > Resample(const inno::Image &image) const =0
Resample image to a target DPI.
Image resampler for DPI-change operations, including upsampling and downsampling using NIST-compliant...
Definition Image.h:678
std::shared_ptr< Image > Resample(const inno::Image &image) const final
Resample image to a target DPI using NIST resamling algorithm.
Definition Image.h:790
InterpolationMethod
Enum defines possible types of interpolation methods to apply during image resampling.
Definition Image.h:682
@ BILINEAR
Apply bilinear interpolation.
Definition Image.h:686
@ BICUBIC
Apply bicubic interpolation.
Definition Image.h:684
NISTImageResampler(ImageDpi targetDpi, InterpolationMethod interpolationMethod, FilterType filterType)
Constructs a NIST-compliant image resampler for a target DPI using a custom interpolation method and ...
Definition Image.h:746
NISTImageResampler(ImageDpi targetDpi)
Constructs a NIST-compliant image resampler for a target DPI.
Definition Image.h:713
FilterType
Enum defines possible types of filtering methods to apply before image resampling.
Definition Image.h:691
@ IDEAL
Apply an ideal filter for sharpness.
Definition Image.h:695
@ GAUSSIAN
Apply a Gaussian filter for smoothing.
Definition Image.h:693
Image representation.
Definition Image.h:34
std::shared_ptr< Image > CropAlignedRectangle(const Rectangle &r, const RGBA &background, const ImageDimensions &dimension) const
Crop rectangle and align given top left rectangle point to coordinates [0,0] in new image.
Definition Image.h:962
void SaveIn(ImageSaver &saver) const
Save Image in given ImageSaver.
Definition Image.h:371
std::shared_ptr< Image > Resize(float factor) const
Resize image to new image.
Definition Image.h:869
Intersection CircleIntersection(const Circle &circle) const
Check intersection between circle and image.
Definition Image.h:167
std::shared_ptr< Image > MaskImageBy(const ImageMask &mask) const
Applies the specified mask to the image, creating a new masked image.
Definition Image.h:1029
static std::shared_ptr< Image > DecodeRawImage(const RawImage &raw, std::shared_ptr< ImageEncoder > originalEncoder=nullptr, std::shared_ptr< ImageExecutor > executor=GlobalImageExecutor::Get())
Creates Image from raw data.
Definition Image.h:200
size_t Channels() const
Returns the number of channels in the image.
Definition Image.h:1046
std::shared_ptr< Image > CropRectangle(const Rectangle &r) const
Crops a rectangle from the image, using a white background for any extra space.
Definition Image.h:458
std::shared_ptr< Image > CropRectangle(const Rectangle &r, const RGBA &background, const ImageDimensions &dimension) const
Crops a rectangle and places it on a canvas of specified dimensions, using a specified background col...
Definition Image.h:496
std::shared_ptr< ImageEncoder > OriginalEncoder() const
Provides original encoder to encode image to original format.
Definition Image.h:265
bool operator==(const Image &right) const
Images are equal when has same dimensions and same content.
Definition Image.h:400
std::shared_ptr< Image > CropCircle(const Circle &circle, const RGBA &background=Colors::White) const
Copy circle to new image.
Definition Image.h:999
ImageDpi Dpi() const
Returns image dpi.
Definition Image.h:238
static std::shared_ptr< Image > Decode(const std::vector< uint8_t > &imageData)
Creates Image from image data with 500 DPI.
Definition Image.h:48
ImageHeight Height() const
Returns image height.
Definition Image.h:256
std::shared_ptr< Image > ChangeDpiTo(ImageDpi targetDpi) const
Create image with given DPI.
Definition Image.h:855
static std::shared_ptr< Image > Decode(const std::vector< uint8_t > &imageData, std::shared_ptr< ImageExecutor > executor)
Creates Image from image data with 500 DPI.
Definition Image.h:82
Intersection
Enum define possible intersection of Image and some Object e.g. Rectangle, Circle.
Definition Image.h:125
@ INSIDE
Object is fully in Image.
Definition Image.h:129
@ OUTSIDE
Image is fully in Object.
Definition Image.h:131
@ NO
Image and Object has no intersection.
Definition Image.h:133
@ SAME
Image has same dimensions and vertices coordinates as Object.
Definition Image.h:135
@ PARTIAL
The Object and Image has intersection.
Definition Image.h:127
std::shared_ptr< Image > AsBGRA() const
Converts image to BGRA format.
Definition Image.h:347
std::shared_ptr< Image > ChangeDpiTo(const ImageResampler &resampler) const
Create image using provided DPI-change configuration.
Definition Image.h:841
static ImageType DeduceType(const std::vector< uint8_t > &imageData)
Deduce image type from image content.
Definition Image.h:226
RawImage AsRawGrayscale() const
Converts image to raw grayscale format.
Definition Image.h:291
RawImage AsRawImage() const
Converts image to RAW format that has been originally used.
Definition Image.h:275
RawImage AsRawBGRA() const
Converts image to raw BGRA format.
Definition Image.h:332
Intersection RectangleIntersection(const Rectangle &rectangle) const
Check intersection between rectangle and image.
Definition Image.h:144
static std::shared_ptr< Image > Decode(const std::vector< uint8_t > &imageData, unsigned int dpi, std::shared_ptr< ImageExecutor > executor)
Creates Image from image data with given DPI.
Definition Image.h:100
Intersection PointIntersection(const Point &point) const
Checks intersection between point and image.
Definition Image.h:181
RawImage AsRawBGR() const
Converts image to raw BGR format.
Definition Image.h:306
static std::shared_ptr< Image > Decode(const std::vector< uint8_t > &imageData, unsigned int dpi)
Creates Image from image data with given dpi.
Definition Image.h:65
std::shared_ptr< Image > DrawShape(const ImageShape &shape) const
Draws shape to new image.
Definition Image.h:435
std::shared_ptr< Image > CropAlignedRectangle(const Rectangle &r, const RGBA &background) const
Crop rectangle and align given top left rectangle point to coordinates [0,0] in new image.
Definition Image.h:940
std::shared_ptr< Image > AsBGR() const
Converts image to BGR format.
Definition Image.h:321
std::shared_ptr< Image > CropAlignedRectangle(const Rectangle &r) const
Crop rectangle and align given top left rectangle point to coordinates [0,0] in new image.
Definition Image.h:923
std::shared_ptr< Image > ResizeToMaxDimension(ImageDimension maxDimension) const
Resize image to new image with given max dimension.
Definition Image.h:891
std::shared_ptr< Image > CropRectangle(const Rectangle &r, const RGBA &background) const
Crops a rectangle from the image, using a white background for any extra space.
Definition Image.h:476
std::vector< uint8_t > EncodeIn(ImageEncoder &encoder) const
Encode image in given ImageEncoder.
Definition Image.h:360
void SaveAs(const std::string &path) const
Save Image in given path.
Definition Image.h:385
ImageWidth Width() const
Returns image width.
Definition Image.h:247
Null argument is not allowed.
Definition EnrollmentException.h:156
It holds X and Y coordinates of point.
Definition ImageAttribute.h:312
X x
X Coordinate.
Definition ImageAttribute.h:326
Y y
Y Coordinate.
Definition ImageAttribute.h:328
It holds RGB color with transparency.
Definition ImageAttribute.h:908
RGB color
color definition in RGB model
Definition ImageAttribute.h:911
unsigned char transparency
Transparency where 0 is fully transparent and 255 is fully opaque.
Definition ImageAttribute.h:913
unsigned char red
Red value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:865
unsigned char green
Green value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:867
unsigned char blue
Blue value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:869
Contains plain image data.
Definition ImageAttribute.h:135
const ImageHeight height
Image height in pixels.
Definition ImageAttribute.h:174
const ImageDpi dpi
Image DPI.
Definition ImageAttribute.h:170
const ImageWidth width
Image width in pixels.
Definition ImageAttribute.h:172
Type
RawImage encoding type.
Definition ImageAttribute.h:139
@ GRAYSCALE
Raw data where image pixels are stored in grayscale format.
Definition ImageAttribute.h:146
@ BGR
Raw data where image pixels are stored in BGR format.
Definition ImageAttribute.h:153
@ BGRA
Raw data where image pixels are stored in BGR with alpha format.
Definition ImageAttribute.h:166
const std::vector< uint8_t > & Data() const
Definition ImageAttribute.h:185
const Type type
RawImage type.
Definition ImageAttribute.h:176
It holds rectangle vertexes, width, height.
Definition ImageAttribute.h:357
const Point & GetBottomLeft() const
Provides bottom-left vertex.
Definition ImageAttribute.h:401
const Point & GetTopLeft() const
Provides top-left vertex.
Definition ImageAttribute.h:377
const Point & GetBottomRight() const
Provides bottom-right vertex.
Definition ImageAttribute.h:393
Width GetWidth() const
Provides width of rectangle The width is distance between top-left and top-right vertexes.
Definition ImageAttribute.h:412
const Point & GetTopRight() const
Provides top-right vertex.
Definition ImageAttribute.h:385
Height GetHeight() const
Provides height of rectangle The height is distance between bottom-left and top-left vertexes.
Definition ImageAttribute.h:423
ImageDimension ImageHeight
Image Height.
Definition ImageAttribute.h:36
ImageBlurType
Defines the type of border blurring applied to an image.
Definition ImageMask.h:39
unsigned int ImageDimension
Image dimension.
Definition ImageAttribute.h:31
ImageDimension ImageWidth
Image Width.
Definition ImageAttribute.h:41
ImageMaskType
Defines the polygon mask application area in image processing.
Definition ImageMask.h:23
@ INSIDE
Mask is applied to the region inside the shape, preserving the area outside.
Definition ImageMask.h:31
@ OUTSIDE
Mask is applied to the region outside the shape, preserving the area inside.
Definition ImageMask.h:27