mirror of
https://github.com/greenshot/greenshot
synced 2025-07-16 10:03:44 -07:00
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
This commit is contained in:
parent
4a5e04ae23
commit
64bc855652
2 changed files with 34 additions and 40 deletions
|
@ -33,6 +33,22 @@ namespace GreenshotPlugin.Core {
|
||||||
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
|
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
|
||||||
private bool clone;
|
private bool clone;
|
||||||
private Bitmap bitmap;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the bitmap, you will always need to dispose the returned bitmap!!
|
/// Get the bitmap, you will always need to dispose the returned bitmap!!
|
||||||
|
@ -309,16 +325,28 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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!
|
/// Before the first time this is called the Lock() should be called once!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">X coordinate</param>
|
/// <param name="x">X coordinate</param>
|
||||||
/// <param name="y">Y Coordinate</param>
|
/// <param name="y">Y Coordinate</param>
|
||||||
/// <returns>Color</returns>
|
/// <returns>Color</returns>
|
||||||
public Color GetColorAtWithoutAlpha(int x, int y) {
|
public Color GetColorAtWithoutAlpha(int x, int y) {
|
||||||
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
|
if (x >= 0 && y >= 0 && x < rect.Width && y < rect.Height) {
|
||||||
int offset = x*bytesPerPixel+y*stride;
|
int offset = x * bytesPerPixel + y * stride;
|
||||||
return Color.FromArgb(255, pointer[rIndex+offset], pointer[gIndex+offset], pointer[bIndex+offset]);
|
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 {
|
} else {
|
||||||
return Color.Empty;
|
return Color.Empty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,6 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
public class WuQuantizer {
|
public class WuQuantizer {
|
||||||
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(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 MAXCOLOR = 512;
|
||||||
private const Int32 RED = 2;
|
private const Int32 RED = 2;
|
||||||
|
@ -102,14 +100,6 @@ namespace GreenshotPlugin.Core {
|
||||||
private Bitmap sourceBitmap;
|
private Bitmap sourceBitmap;
|
||||||
private Bitmap resultBitmap;
|
private Bitmap resultBitmap;
|
||||||
|
|
||||||
static WuQuantizer() {
|
|
||||||
BackgroundColor = Color.White;
|
|
||||||
Factors = new Double[256];
|
|
||||||
for (Int32 value = 0; value < 256; value++) {
|
|
||||||
Factors[value] = value / 255.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// See <see cref="IColorQuantizer.Prepare"/> for more details.
|
/// See <see cref="IColorQuantizer.Prepare"/> for more details.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -157,8 +147,7 @@ namespace GreenshotPlugin.Core {
|
||||||
bbbDest.Lock();
|
bbbDest.Lock();
|
||||||
for (int y = 0; y < bbbSrc.Height; y++) {
|
for (int y = 0; y < bbbSrc.Height; y++) {
|
||||||
for (int x = 0; x < bbbSrc.Width; x++) {
|
for (int x = 0; x < bbbSrc.Width; x++) {
|
||||||
Color color = bbbSrc.GetColorAt(x, y);
|
Color color = bbbSrc.GetColorAtWithoutAlpha(x, y);
|
||||||
color = ConvertAlpha(color);
|
|
||||||
// To count the colors
|
// To count the colors
|
||||||
int index = color.ToArgb() & 0x00ffffff;
|
int index = color.ToArgb() & 0x00ffffff;
|
||||||
// Check if we already have this color
|
// Check if we already have this color
|
||||||
|
@ -270,8 +259,7 @@ namespace GreenshotPlugin.Core {
|
||||||
byte bestMatch;
|
byte bestMatch;
|
||||||
for (int y = 0; y < bbbSrc.Height; y++) {
|
for (int y = 0; y < bbbSrc.Height; y++) {
|
||||||
for (int x = 0; x < bbbSrc.Width; x++) {
|
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
|
// Check if we already matched the color
|
||||||
if (!lookup.ContainsKey(color)) {
|
if (!lookup.ContainsKey(color)) {
|
||||||
// If not we need to find the best match
|
// If not we need to find the best match
|
||||||
|
@ -329,28 +317,6 @@ namespace GreenshotPlugin.Core {
|
||||||
return resultBitmap;
|
return resultBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts the alpha blended color to a non-alpha blended color.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color">The alpha blended color (ARGB).</param>
|
|
||||||
/// <returns>The non-alpha blended color (RGB).</returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the histogram to a series of moments.
|
/// Converts the histogram to a series of moments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue