Mercurial > hg > orthanc-wsi
changeset 315:072968f00d26
support of transparency in OpenSlide
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 09 Sep 2024 20:12:14 +0200 |
parents | 9dc7f1e8716d |
children | 51ef122c1882 |
files | Applications/Dicomizer.cpp Framework/Inputs/OpenSlidePyramid.cpp Framework/Inputs/OpenSlidePyramid.h |
diffstat | 3 files changed, 66 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/Dicomizer.cpp Wed Aug 14 15:52:13 2024 +0200 +++ b/Applications/Dicomizer.cpp Mon Sep 09 20:12:14 2024 +0200 @@ -1109,6 +1109,10 @@ new OrthancWSI::OpenSlidePyramid(path, parameters.GetTargetTileWidth(512), parameters.GetTargetTileHeight(512))); + openslide->SetBackgroundColor(parameters.GetBackgroundColorRed(), + parameters.GetBackgroundColorGreen(), + parameters.GetBackgroundColorBlue()); + float volumeWidth, volumeHeight; if (openslide->LookupImagedVolumeSize(volumeWidth, volumeHeight)) {
--- a/Framework/Inputs/OpenSlidePyramid.cpp Wed Aug 14 15:52:13 2024 +0200 +++ b/Framework/Inputs/OpenSlidePyramid.cpp Mon Sep 09 20:12:14 2024 +0200 @@ -30,6 +30,7 @@ #include <SerializationToolbox.h> #include <Logging.h> +#include <boost/math/special_functions/round.hpp> #include <memory> namespace OrthancWSI @@ -40,7 +41,49 @@ unsigned int y) { std::unique_ptr<Orthanc::ImageAccessor> source(image_.ReadRegion(level, x, y, target.GetWidth(), target.GetHeight())); - Orthanc::ImageProcessing::Convert(target, *source); + + if (target.GetWidth() != source->GetWidth() || + target.GetHeight() != source->GetHeight()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); + } + + const unsigned int width = source->GetWidth(); + const unsigned int height = source->GetHeight(); + + if (target.GetFormat() == Orthanc::PixelFormat_RGB24 && + source->GetFormat() == Orthanc::PixelFormat_BGRA32) + { + // Implements alpha blending: https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending + for (unsigned int y = 0; y < height; y++) + { + const uint8_t* p = reinterpret_cast<const uint8_t*>(source->GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + for (unsigned int x = 0; x < width; x++) + { + /** + Alpha blending using integer arithmetics only (16 bits avoids overflows) + + p = (1 - alpha) * background + alpha * value + <=> p = (1 - p[3] / 255) * background + p[3] / 255 * value + <=> p = ((255 - p[3]) * background + p[3] * value) / 255 + + **/ + + uint16_t alpha = p[3]; + q[0] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[0] + alpha * p[2]) / 255); + q[1] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[1] + alpha * p[1]) / 255); + q[2] = static_cast<uint8_t>(((255 - alpha) * backgroundColor_[2] + alpha * p[0]) / 255); + + p += 4; + q += 3; + } + } + } + else + { + Orthanc::ImageProcessing::Convert(target, *source); + } } @@ -51,6 +94,9 @@ tileWidth_(tileWidth), tileHeight_(tileHeight) { + backgroundColor_[0] = 255; + backgroundColor_[1] = 255; + backgroundColor_[2] = 255; } @@ -76,4 +122,14 @@ return false; } } + + + void OpenSlidePyramid::SetBackgroundColor(uint8_t red, + uint8_t green, + uint8_t blue) + { + backgroundColor_[0] = red; + backgroundColor_[1] = green; + backgroundColor_[2] = blue; + } }
--- a/Framework/Inputs/OpenSlidePyramid.h Wed Aug 14 15:52:13 2024 +0200 +++ b/Framework/Inputs/OpenSlidePyramid.h Mon Sep 09 20:12:14 2024 +0200 @@ -34,6 +34,7 @@ OpenSlideLibrary::Image image_; unsigned int tileWidth_; unsigned int tileHeight_; + uint8_t backgroundColor_[3]; protected: virtual void ReadRegion(Orthanc::ImageAccessor& target, @@ -83,5 +84,9 @@ bool LookupImagedVolumeSize(float& width, float& height) const; + + void SetBackgroundColor(uint8_t red, + uint8_t green, + uint8_t blue); }; }