Mercurial > hg > orthanc-wsi
comparison Framework/Inputs/OpenSlidePyramid.cpp @ 315:072968f00d26
support of transparency in OpenSlide
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 09 Sep 2024 20:12:14 +0200 |
parents | 0683312e21ba |
children | f611fb47d0e8 |
comparison
equal
deleted
inserted
replaced
314:9dc7f1e8716d | 315:072968f00d26 |
---|---|
28 #include <Images/ImageProcessing.h> | 28 #include <Images/ImageProcessing.h> |
29 #include <OrthancException.h> | 29 #include <OrthancException.h> |
30 #include <SerializationToolbox.h> | 30 #include <SerializationToolbox.h> |
31 #include <Logging.h> | 31 #include <Logging.h> |
32 | 32 |
33 #include <boost/math/special_functions/round.hpp> | |
33 #include <memory> | 34 #include <memory> |
34 | 35 |
35 namespace OrthancWSI | 36 namespace OrthancWSI |
36 { | 37 { |
37 void OpenSlidePyramid::ReadRegion(Orthanc::ImageAccessor& target, | 38 void OpenSlidePyramid::ReadRegion(Orthanc::ImageAccessor& target, |
38 unsigned int level, | 39 unsigned int level, |
39 unsigned int x, | 40 unsigned int x, |
40 unsigned int y) | 41 unsigned int y) |
41 { | 42 { |
42 std::unique_ptr<Orthanc::ImageAccessor> source(image_.ReadRegion(level, x, y, target.GetWidth(), target.GetHeight())); | 43 std::unique_ptr<Orthanc::ImageAccessor> source(image_.ReadRegion(level, x, y, target.GetWidth(), target.GetHeight())); |
43 Orthanc::ImageProcessing::Convert(target, *source); | 44 |
45 if (target.GetWidth() != source->GetWidth() || | |
46 target.GetHeight() != source->GetHeight()) | |
47 { | |
48 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); | |
49 } | |
50 | |
51 const unsigned int width = source->GetWidth(); | |
52 const unsigned int height = source->GetHeight(); | |
53 | |
54 if (target.GetFormat() == Orthanc::PixelFormat_RGB24 && | |
55 source->GetFormat() == Orthanc::PixelFormat_BGRA32) | |
56 { | |
57 // Implements alpha blending: https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending | |
58 for (unsigned int y = 0; y < height; y++) | |
59 { | |
60 const uint8_t* p = reinterpret_cast<const uint8_t*>(source->GetConstRow(y)); | |
61 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); | |
62 for (unsigned int x = 0; x < width; x++) | |
63 { | |
64 /** | |
65 Alpha blending using integer arithmetics only (16 bits avoids overflows) | |
66 | |
67 p = (1 - alpha) * background + alpha * value | |
68 <=> p = (1 - p[3] / 255) * background + p[3] / 255 * value | |
69 <=> p = ((255 - p[3]) * background + p[3] * value) / 255 | |
70 | |
71 **/ | |
72 | |
73 uint16_t alpha = p[3]; | |
74 q[0] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[0] + alpha * p[2]) / 255); | |
75 q[1] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[1] + alpha * p[1]) / 255); | |
76 q[2] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[2] + alpha * p[0]) / 255); | |
77 | |
78 p += 4; | |
79 q += 3; | |
80 } | |
81 } | |
82 } | |
83 else | |
84 { | |
85 Orthanc::ImageProcessing::Convert(target, *source); | |
86 } | |
44 } | 87 } |
45 | 88 |
46 | 89 |
47 OpenSlidePyramid::OpenSlidePyramid(const std::string& path, | 90 OpenSlidePyramid::OpenSlidePyramid(const std::string& path, |
48 unsigned int tileWidth, | 91 unsigned int tileWidth, |
49 unsigned int tileHeight) : | 92 unsigned int tileHeight) : |
50 image_(path), | 93 image_(path), |
51 tileWidth_(tileWidth), | 94 tileWidth_(tileWidth), |
52 tileHeight_(tileHeight) | 95 tileHeight_(tileHeight) |
53 { | 96 { |
97 backgroundColor_[0] = 255; | |
98 backgroundColor_[1] = 255; | |
99 backgroundColor_[2] = 255; | |
54 } | 100 } |
55 | 101 |
56 | 102 |
57 bool OpenSlidePyramid::LookupImagedVolumeSize(float& width, | 103 bool OpenSlidePyramid::LookupImagedVolumeSize(float& width, |
58 float& height) const | 104 float& height) const |
74 else | 120 else |
75 { | 121 { |
76 return false; | 122 return false; |
77 } | 123 } |
78 } | 124 } |
125 | |
126 | |
127 void OpenSlidePyramid::SetBackgroundColor(uint8_t red, | |
128 uint8_t green, | |
129 uint8_t blue) | |
130 { | |
131 backgroundColor_[0] = red; | |
132 backgroundColor_[1] = green; | |
133 backgroundColor_[2] = blue; | |
134 } | |
79 } | 135 } |