From 64bc85565239e9e810c7bdc67375a20fb0254b69 Mon Sep 17 00:00:00 2001 From: RKrom Date: Wed, 21 Mar 2012 13:12:19 +0000 Subject: [PATCH] Fixed missing alpha blending and optimized performance. git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1718 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4 --- GreenshotPlugin/Core/BitmapBuffer.cs | 36 ++++++++++++++++++++--- GreenshotPlugin/Core/QuantizerHelper.cs | 38 ++----------------------- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/GreenshotPlugin/Core/BitmapBuffer.cs b/GreenshotPlugin/Core/BitmapBuffer.cs index e12600cd2..075931156 100644 --- a/GreenshotPlugin/Core/BitmapBuffer.cs +++ b/GreenshotPlugin/Core/BitmapBuffer.cs @@ -33,6 +33,22 @@ namespace GreenshotPlugin.Core { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer)); private bool clone; private Bitmap bitmap; + private static int[] factors = new int[256]; + private static int[] remainings = new int[256]; + + static BitmapBuffer() { + // Pre calculate for alpha blending + for (int i = 0; i < 256; i++) { + int factor = 0x10000 * i / 255; + factors[i] = factor; + remainings[i] = (0x10000 * 255) - factor; + } + } + + public static Color BackgroundBlendColor { + get; + set; + } /// /// Get the bitmap, you will always need to dispose the returned bitmap!! @@ -309,16 +325,28 @@ namespace GreenshotPlugin.Core { } /// - /// Retrieve the color, without alpha, at location x,y + /// Retrieve the color, without alpha (is blended), at location x,y /// Before the first time this is called the Lock() should be called once! /// /// X coordinate /// Y Coordinate /// Color public Color GetColorAtWithoutAlpha(int x, int y) { - if(x>=0 && y>=0 && x= 0 && y >= 0 && x < rect.Width && y < rect.Height) { + int offset = x * bytesPerPixel + y * stride; + int a = (aIndex == -1) ? (byte)255 : pointer[aIndex + offset]; + int red = pointer[rIndex + offset]; + int green = pointer[gIndex + offset]; + int blue = pointer[bIndex + offset]; + + if (a < 255) { + int aMult = factors[a]; + int rem = remainings[a]; + red = (red * rem + BackgroundBlendColor.R * aMult) >> 16; + green = (green * rem + BackgroundBlendColor.G * aMult) >> 16; + blue = (blue * rem + BackgroundBlendColor.B * aMult) >> 16; + } + return Color.FromArgb(255, red, green, blue); } else { return Color.Empty; } diff --git a/GreenshotPlugin/Core/QuantizerHelper.cs b/GreenshotPlugin/Core/QuantizerHelper.cs index 37490d4c6..92f6fc8a6 100644 --- a/GreenshotPlugin/Core/QuantizerHelper.cs +++ b/GreenshotPlugin/Core/QuantizerHelper.cs @@ -71,8 +71,6 @@ namespace GreenshotPlugin.Core { public class WuQuantizer { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WuQuantizer)); - private static readonly Color BackgroundColor; - private static readonly Double[] Factors; private const Int32 MAXCOLOR = 512; private const Int32 RED = 2; @@ -102,14 +100,6 @@ namespace GreenshotPlugin.Core { private Bitmap sourceBitmap; private Bitmap resultBitmap; - static WuQuantizer() { - BackgroundColor = Color.White; - Factors = new Double[256]; - for (Int32 value = 0; value < 256; value++) { - Factors[value] = value / 255.0; - } - } - /// /// See for more details. /// @@ -157,8 +147,7 @@ namespace GreenshotPlugin.Core { bbbDest.Lock(); for (int y = 0; y < bbbSrc.Height; y++) { for (int x = 0; x < bbbSrc.Width; x++) { - Color color = bbbSrc.GetColorAt(x, y); - color = ConvertAlpha(color); + Color color = bbbSrc.GetColorAtWithoutAlpha(x, y); // To count the colors int index = color.ToArgb() & 0x00ffffff; // Check if we already have this color @@ -270,8 +259,7 @@ namespace GreenshotPlugin.Core { byte bestMatch; for (int y = 0; y < bbbSrc.Height; y++) { for (int x = 0; x < bbbSrc.Width; x++) { - Color color = bbbSrc.GetColorAt(x, y); - + Color color = bbbSrc.GetColorAtWithoutAlpha(x, y); // Check if we already matched the color if (!lookup.ContainsKey(color)) { // If not we need to find the best match @@ -329,28 +317,6 @@ namespace GreenshotPlugin.Core { return resultBitmap; } - /// - /// Converts the alpha blended color to a non-alpha blended color. - /// - /// The alpha blended color (ARGB). - /// The non-alpha blended color (RGB). - private static Color ConvertAlpha(Color color) { - Color result = color; - - if (color.A < 255) { - // performs a alpha blending (second color is BackgroundColor, by default a Control color) - Double colorFactor = Factors[color.A]; - Double backgroundFactor = Factors[255 - color.A]; - Int32 red = (Int32)(color.R * colorFactor + BackgroundColor.R * backgroundFactor); - Int32 green = (Int32)(color.G * colorFactor + BackgroundColor.G * backgroundFactor); - Int32 blue = (Int32)(color.B * colorFactor + BackgroundColor.B * backgroundFactor); - Int32 argb = 255 << 24 | red << 16 | green << 8 | blue; - result = Color.FromArgb(argb); - } - - return result; - } - /// /// Converts the histogram to a series of moments. ///