Mercurial > hg > orthanc-stone
diff Framework/Radiography/RadiographyWidget.cpp @ 432:4eb96c6b4e96 am-vsol-upgrade
improved handling of MONOCHROME1, background and invertion
author | am@osimis.io |
---|---|
date | Mon, 03 Dec 2018 13:53:29 +0100 |
parents | 751fb354149e |
children | a750f11892ec |
line wrap: on
line diff
--- a/Framework/Radiography/RadiographyWidget.cpp Thu Nov 29 19:25:15 2018 +0100 +++ b/Framework/Radiography/RadiographyWidget.cpp Mon Dec 03 13:53:29 2018 +0100 @@ -21,18 +21,53 @@ #include "RadiographyWidget.h" +#include <Core/OrthancException.h> #include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> namespace OrthancStone { + + bool RadiographyWidget::IsInvertedInternal() const + { + return (scene_->GetPreferredPhotomotricDisplayMode() == PhotometricDisplayMode_Monochrome1) ^ invert_; // MONOCHROME1 images must be inverted and the user can invert the image too -> XOR the two + } + + void RadiographyWidget::RenderBackground(Orthanc::ImageAccessor& image, float minValue, float maxValue) + { + // wipe background before rendering + float backgroundValue = minValue; + + switch (scene_->GetPreferredPhotomotricDisplayMode()) + { + case PhotometricDisplayMode_Monochrome1: + case PhotometricDisplayMode_Default: + if (IsInvertedInternal()) + backgroundValue = maxValue; + else + backgroundValue = minValue; + break; + case PhotometricDisplayMode_Monochrome2: + if (IsInvertedInternal()) + backgroundValue = minValue; + else + backgroundValue = maxValue; + break; + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + + Orthanc::ImageProcessing::Set(image, backgroundValue); + } + bool RadiographyWidget::RenderInternal(unsigned int width, unsigned int height, ImageInterpolation interpolation) { float windowCenter, windowWidth; scene_->GetWindowingWithDefault(windowCenter, windowWidth); - + float x0 = windowCenter - windowWidth / 2.0f; float x1 = windowCenter + windowWidth / 2.0f; @@ -56,8 +91,10 @@ cairoBuffer_.reset(new CairoSurface(width, height)); } + RenderBackground(*floatBuffer_, x0, x1); + scene_->Render(*floatBuffer_, GetView().GetMatrix(), interpolation); - + // Conversion from Float32 to BGRA32 (cairo). Very similar to // GrayscaleFrameRenderer => TODO MERGE? @@ -65,7 +102,9 @@ cairoBuffer_->GetWriteableAccessor(target); float scaling = 255.0f / (x1 - x0); - + + bool invert = IsInvertedInternal(); + for (unsigned int y = 0; y < height; y++) { const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y)); @@ -88,7 +127,7 @@ v = static_cast<uint8_t>(scaling * (*p - x0)); // (*) } - if (invert_) + if (invert) { v = 255 - v; } @@ -172,14 +211,15 @@ void RadiographyWidget::OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message) { - LOG(INFO) << "Geometry has changed"; + LOG(INFO) << "Scene geometry has changed"; + FitContent(); } void RadiographyWidget::OnContentChanged(const RadiographyScene::ContentChangedMessage& message) { - LOG(INFO) << "Content has changed"; + LOG(INFO) << "Scene content has changed"; NotifyContentChanged(); } @@ -220,12 +260,14 @@ scene_ = scene; scene_->RegisterObserverCallback( - new Callable<RadiographyWidget, RadiographyScene::GeometryChangedMessage> - (*this, &RadiographyWidget::OnGeometryChanged)); + new Callable<RadiographyWidget, RadiographyScene::GeometryChangedMessage> + (*this, &RadiographyWidget::OnGeometryChanged)); scene_->RegisterObserverCallback( - new Callable<RadiographyWidget, RadiographyScene::ContentChangedMessage> - (*this, &RadiographyWidget::OnContentChanged)); + new Callable<RadiographyWidget, RadiographyScene::ContentChangedMessage> + (*this, &RadiographyWidget::OnContentChanged)); + + NotifyContentChanged(); // force redraw FitContent();