diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index 524f5493b..8f654f6b0 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -533,7 +533,7 @@ namespace Greenshot.Drawing { /// The memento implementing the undo public void MakeUndoable(IMemento memento, bool allowMerge) { if (inUndoRedo) { - throw new InvalidOperationException("Involking do within an undo/redo action."); + throw new InvalidOperationException("Invoking do within an undo/redo action."); } if (memento != null) { bool allowPush = true; diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs index 640bf4fd2..c93c05226 100644 --- a/GreenshotPlugin/Core/ImageHelper.cs +++ b/GreenshotPlugin/Core/ImageHelper.cs @@ -1199,20 +1199,21 @@ namespace GreenshotPlugin.Core { /// The color to fill with, or Color.Empty to take the default depending on the pixel format /// /// - /// + /// Bitmap public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution, float verticalResolution) { // Create a new "clean" image Bitmap newImage = new Bitmap(width, height, format); newImage.SetResolution(horizontalResolution, verticalResolution); - - using (Graphics graphics = Graphics.FromImage(newImage)) { - // Make sure the background color is what we want (transparent or white, depending on the pixel format) - if (!Color.Empty.Equals(backgroundColor)) { - graphics.Clear(backgroundColor); - } else if (Image.IsAlphaPixelFormat(format)) { - graphics.Clear(Color.Transparent); - } else { - graphics.Clear(Color.White); + if (format != PixelFormat.Format8bppIndexed) { + using (Graphics graphics = Graphics.FromImage(newImage)) { + // Make sure the background color is what we want (transparent or white, depending on the pixel format) + if (!Color.Empty.Equals(backgroundColor)) { + graphics.Clear(backgroundColor); + } else if (Image.IsAlphaPixelFormat(format)) { + graphics.Clear(Color.Transparent); + } else { + graphics.Clear(Color.White); + } } } return newImage; diff --git a/GreenshotPlugin/Core/ImageOutput.cs b/GreenshotPlugin/Core/ImageOutput.cs index 02465dd55..72a5fdbf4 100644 --- a/GreenshotPlugin/Core/ImageOutput.cs +++ b/GreenshotPlugin/Core/ImageOutput.cs @@ -264,8 +264,8 @@ namespace GreenshotPlugin.Core { LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount); if (outputSettings.ReduceColors || colorCount < 256) { try { - LOG.Info("Reducing colors on bitmap to 255."); - tmpImage = quantizer.GetQuantizedImage(255); + LOG.Info("Reducing colors on bitmap to 256."); + tmpImage = quantizer.GetQuantizedImage(256); if (disposeImage) { imageToSave.Dispose(); } diff --git a/GreenshotPlugin/Core/QuantizerHelper.cs b/GreenshotPlugin/Core/QuantizerHelper.cs index 20c6bd70e..5c6bd5763 100644 --- a/GreenshotPlugin/Core/QuantizerHelper.cs +++ b/GreenshotPlugin/Core/QuantizerHelper.cs @@ -184,10 +184,52 @@ namespace GreenshotPlugin.Core { return colorCount; } + /// + /// Reindex the 24/32 BPP (A)RGB image to a 8BPP + /// + /// Bitmap + public Bitmap SimpleReindex() { + List colors = new List(); + Dictionary lookup = new Dictionary(); + using (BitmapBuffer bbbDest = new BitmapBuffer(resultBitmap, false)) { + bbbDest.Lock(); + using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) { + bbbSrc.Lock(); + byte index; + for (int y = 0; y < bbbSrc.Height; y++) { + for (int x = 0; x < bbbSrc.Width; x++) { + Color color = bbbSrc.GetColorAt(x, y); + if (lookup.ContainsKey(color)) { + index = lookup[color]; + } else { + colors.Add(color); + index = (byte)(colors.Count - 1); + lookup.Add(color, index); + } + bbbDest.SetColorIndexAt(x, y, index); + } + } + } + } + + // generates palette + ColorPalette imagePalette = resultBitmap.Palette; + for (Int32 paletteIndex = 0; paletteIndex < colorCount; paletteIndex++) { + imagePalette.Entries[paletteIndex] = colors[paletteIndex]; + } + resultBitmap.Palette = imagePalette; + return resultBitmap; + } + /// /// Get the image /// public Bitmap GetQuantizedImage(int allowedColorCount) { + if (colorCount < 256) { + // Simple logic to reduce to 8 bit + LOG.Info("Using simple copy, no quantizing needed!"); + return SimpleReindex(); + } // preprocess the colors CalculateMoments(); LOG.Info("Calculated the moments..."); @@ -302,9 +344,9 @@ namespace GreenshotPlugin.Core { } } - ColorPalette imagePalette = resultBitmap.Palette; // generates palette + ColorPalette imagePalette = resultBitmap.Palette; for (Int32 paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++) { if (sums[paletteIndex] > 0) { reds[paletteIndex] /= sums[paletteIndex];