summaryrefslogtreecommitdiff
path: root/vcl/source/bitmap/BitmapTools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/bitmap/BitmapTools.cxx')
-rw-r--r--vcl/source/bitmap/BitmapTools.cxx68
1 files changed, 68 insertions, 0 deletions
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index eddef22cfb53..2a9dc870ddc1 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -13,6 +13,7 @@
#include <array>
#include <utility>
+#include <tools/helpers.hxx>
#include <vcl/BitmapTools.hxx>
#include <sal/log.hxx>
@@ -1140,6 +1141,73 @@ bool convertBitmap32To24Plus8(BitmapEx const & rInput, BitmapEx & rResult)
return true;
}
+Bitmap GetDownsampledBitmap(Size const& rDstSizeTwip, Point const& rSrcPt, Size const& rSrcSz,
+ Bitmap const& rBmp, tools::Long nMaxBmpDPIX, tools::Long nMaxBmpDPIY)
+{
+ Bitmap aBmp(rBmp);
+
+ if (!aBmp.IsEmpty())
+ {
+ const tools::Rectangle aBmpRect( Point(), aBmp.GetSizePixel() );
+ tools::Rectangle aSrcRect( rSrcPt, rSrcSz );
+
+ // do cropping if necessary
+ if( aSrcRect.Intersection( aBmpRect ) != aBmpRect )
+ {
+ if( !aSrcRect.IsEmpty() )
+ aBmp.Crop( aSrcRect );
+ else
+ aBmp.SetEmpty();
+ }
+
+ if( !aBmp.IsEmpty() )
+ {
+ // do downsampling if necessary
+ // #103209# Normalize size (mirroring has to happen outside of this method)
+ Size aDstSizeTwip(std::abs(rDstSizeTwip.Width()), std::abs(rDstSizeTwip.Height()));
+
+ const Size aBmpSize( aBmp.GetSizePixel() );
+ const double fBmpPixelX = aBmpSize.Width();
+ const double fBmpPixelY = aBmpSize.Height();
+ const double fMaxPixelX
+ = o3tl::convert<double>(aDstSizeTwip.Width(), o3tl::Length::twip, o3tl::Length::in)
+ * nMaxBmpDPIX;
+ const double fMaxPixelY
+ = o3tl::convert<double>(aDstSizeTwip.Height(), o3tl::Length::twip, o3tl::Length::in)
+ * nMaxBmpDPIY;
+
+ // check, if the bitmap DPI exceeds the maximum DPI (allow 4 pixel rounding tolerance)
+ if (((fBmpPixelX > (fMaxPixelX + 4)) ||
+ (fBmpPixelY > (fMaxPixelY + 4))) &&
+ (fBmpPixelY > 0.0) && (fMaxPixelY > 0.0))
+ {
+ // do scaling
+ Size aNewBmpSize;
+ const double fBmpWH = fBmpPixelX / fBmpPixelY;
+ const double fMaxWH = fMaxPixelX / fMaxPixelY;
+
+ if (fBmpWH < fMaxWH)
+ {
+ aNewBmpSize.setWidth(FRound(fMaxPixelY * fBmpWH));
+ aNewBmpSize.setHeight(FRound(fMaxPixelY));
+ }
+ else if (fBmpWH > 0.0)
+ {
+ aNewBmpSize.setWidth(FRound(fMaxPixelX));
+ aNewBmpSize.setHeight(FRound(fMaxPixelX / fBmpWH));
+ }
+
+ if( aNewBmpSize.Width() && aNewBmpSize.Height() )
+ aBmp.Scale(aNewBmpSize);
+ else
+ aBmp.SetEmpty();
+ }
+ }
+ }
+
+ return aBmp;
+}
+
} // end vcl::bitmap
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */