mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 17:13:44 -07:00
Added better 8 bit support, although the caller needs to call the right method... Maybe I can use indirect functions to speed this up? Changed the Quantizer to reflect the changes.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2472 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
f0b1f1f84d
commit
764cba9af7
2 changed files with 50 additions and 8 deletions
|
@ -33,6 +33,8 @@ 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;
|
||||||
|
// Used for indexed images
|
||||||
|
private Color[] colorEntries;
|
||||||
|
|
||||||
public static Color BackgroundBlendColor {
|
public static Color BackgroundBlendColor {
|
||||||
get;
|
get;
|
||||||
|
@ -164,6 +166,9 @@ namespace GreenshotPlugin.Core {
|
||||||
this.bitmap = sourceImage as Bitmap;
|
this.bitmap = sourceImage as Bitmap;
|
||||||
this.rect = sourceRect;
|
this.rect = sourceRect;
|
||||||
}
|
}
|
||||||
|
if (bitmap.PixelFormat == PixelFormat.Format8bppIndexed) {
|
||||||
|
colorEntries = bitmap.Palette.Entries;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -297,21 +302,33 @@ namespace GreenshotPlugin.Core {
|
||||||
/// </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>index</returns>
|
/// <returns>color index</returns>
|
||||||
public byte GetColorIndexAt(int x, int y) {
|
public byte GetColorIndexAt(int x, int y) {
|
||||||
int offset = x*bytesPerPixel+y*stride;
|
int offset = x*bytesPerPixel+y*stride;
|
||||||
return pointer[offset];
|
return pointer[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the color for an 8-bit image
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x"></param>
|
||||||
|
/// <param name="y"></param>
|
||||||
|
/// <returns>Color from the palette</returns>
|
||||||
|
public Color GetColor(int x, int y) {
|
||||||
|
int offset = x * bytesPerPixel + y * stride;
|
||||||
|
byte colorIndex = pointer[offset];
|
||||||
|
return colorEntries[colorIndex];
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the color index, for 8BPP, at location x,y
|
/// Set the color index, for 8BPP, at location x,y
|
||||||
/// </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>
|
||||||
/// <param name="color">Color index to set</param>
|
/// <param name="color">Color index to set</param>
|
||||||
public void SetColorIndexAt(int x, int y, byte color) {
|
public void SetColorIndexAt(int x, int y, byte colorIndex) {
|
||||||
int offset = x * bytesPerPixel + y * stride;
|
int offset = x * bytesPerPixel + y * stride;
|
||||||
pointer[offset] = color;
|
pointer[offset] = colorIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -369,6 +386,7 @@ namespace GreenshotPlugin.Core {
|
||||||
int blue = pointer[bIndex + offset];
|
int blue = pointer[bIndex + offset];
|
||||||
|
|
||||||
if (a < 255) {
|
if (a < 255) {
|
||||||
|
// As the request is to get without alpha, we blend.
|
||||||
int rem = 255 - a;
|
int rem = 255 - a;
|
||||||
red = (red * a + BackgroundBlendColor.R * rem) / 255;
|
red = (red * a + BackgroundBlendColor.R * rem) / 255;
|
||||||
green = (green * a + BackgroundBlendColor.G * rem) / 255;
|
green = (green * a + BackgroundBlendColor.G * rem) / 255;
|
||||||
|
|
|
@ -149,13 +149,19 @@ namespace GreenshotPlugin.Core {
|
||||||
// Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
|
// Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
|
||||||
resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format8bppIndexed);
|
resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format8bppIndexed);
|
||||||
resultBitmap.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
|
resultBitmap.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
|
||||||
|
bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
|
||||||
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
||||||
bbbSrc.Lock();
|
bbbSrc.Lock();
|
||||||
using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) {
|
using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) {
|
||||||
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.GetColorAtWithoutAlpha(x, y);
|
Color color;
|
||||||
|
if (is8Bit) {
|
||||||
|
color = bbbSrc.GetColor(x, y);
|
||||||
|
} else {
|
||||||
|
color = bbbSrc.GetColorAtWithoutAlpha(x, y);
|
||||||
|
}
|
||||||
// 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
|
||||||
|
@ -203,9 +209,15 @@ namespace GreenshotPlugin.Core {
|
||||||
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
||||||
bbbSrc.Lock();
|
bbbSrc.Lock();
|
||||||
byte index;
|
byte index;
|
||||||
|
bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
|
||||||
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;
|
||||||
|
if (is8Bit) {
|
||||||
|
color = bbbSrc.GetColor(x, y);
|
||||||
|
} else {
|
||||||
|
color = bbbSrc.GetColorAt(x, y);
|
||||||
|
}
|
||||||
if (lookup.ContainsKey(color)) {
|
if (lookup.ContainsKey(color)) {
|
||||||
index = lookup[color];
|
index = lookup[color];
|
||||||
} else {
|
} else {
|
||||||
|
@ -240,9 +252,12 @@ namespace GreenshotPlugin.Core {
|
||||||
/// Get the image
|
/// Get the image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Bitmap GetQuantizedImage(int allowedColorCount) {
|
public Bitmap GetQuantizedImage(int allowedColorCount) {
|
||||||
if (colorCount < 256) {
|
if (allowedColorCount > 256) {
|
||||||
|
throw new ArgumentOutOfRangeException("Quantizing muss be done to get less than 256 colors");
|
||||||
|
}
|
||||||
|
if (colorCount < allowedColorCount) {
|
||||||
// Simple logic to reduce to 8 bit
|
// Simple logic to reduce to 8 bit
|
||||||
LOG.Info("Using simple copy, no quantizing needed!");
|
LOG.Info("Colors in the image are already less as whished for, using simple copy to indexed image, no quantizing needed!");
|
||||||
return SimpleReindex();
|
return SimpleReindex();
|
||||||
}
|
}
|
||||||
// preprocess the colors
|
// preprocess the colors
|
||||||
|
@ -315,9 +330,18 @@ namespace GreenshotPlugin.Core {
|
||||||
bbbSrc.Lock();
|
bbbSrc.Lock();
|
||||||
Dictionary<Color, byte> lookup = new Dictionary<Color, byte>();
|
Dictionary<Color, byte> lookup = new Dictionary<Color, byte>();
|
||||||
byte bestMatch;
|
byte bestMatch;
|
||||||
|
bool is8Bit = sourceBitmap.PixelFormat == PixelFormat.Format8bppIndexed;
|
||||||
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.GetColorAtWithoutAlpha(x, y);
|
Color color;
|
||||||
|
if (is8Bit) {
|
||||||
|
color = bbbSrc.GetColor(x, y);
|
||||||
|
} else {
|
||||||
|
color = bbbSrc.GetColorAtWithoutAlpha(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to a strip the alpha as before
|
||||||
|
|
||||||
// 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue