The image buffer for storing and manipulating pixel information. Adapted from
Ejemplo n.º 1
0
 /// <summary>
 /// Quantizes the image contained within the <see cref="ImageBuffer"/> returning the result.
 /// </summary>
 /// <param name="imageBuffer">
 /// The <see cref="ImageBuffer"/> for storing and manipulating pixel information..
 /// </param>
 /// <param name="colorCount">
 /// The maximum number of colors apply to the image.
 /// </param>
 /// <param name="lookups">
 /// The array of <see cref="Color32"/> containing indexed versions of the images colors.
 /// </param>
 /// <param name="alphaThreshold">
 /// All colors with an alpha value less than this will be considered fully transparent.
 /// </param>
 /// <returns>
 /// The quantized <see cref="Bitmap"/>.
 /// </returns>
 internal override Bitmap GetQuantizedImage(ImageBuffer imageBuffer, int colorCount, Color32[] lookups, int alphaThreshold)
 {
     Bitmap result = new Bitmap(imageBuffer.Image.Width, imageBuffer.Image.Height, PixelFormat.Format8bppIndexed);
     result.SetResolution(imageBuffer.Image.HorizontalResolution, imageBuffer.Image.VerticalResolution);
     ImageBuffer resultBuffer = new ImageBuffer(result);
     PaletteColorHistory[] paletteHistogram = new PaletteColorHistory[colorCount + 1];
     resultBuffer.UpdatePixelIndexes(IndexedPixels(imageBuffer, lookups, alphaThreshold, paletteHistogram));
     result.Palette = BuildPalette(result.Palette, paletteHistogram);
     return result;
 }
Ejemplo n.º 2
0
        private static void BuildHistogram(Histogram histogram, ImageBuffer imageBuffer, int alphaThreshold, int alphaFader)
        {
            ColorMoment[, , ,] moments = histogram.Moments;

            foreach (Color32[] pixelLine in imageBuffer.PixelLines)
            {
                foreach (Color32 pixel in pixelLine)
                {
                    byte pixelAlpha = pixel.A;
                    if (pixelAlpha > alphaThreshold)
                    {
                        if (pixelAlpha < 255)
                        {
                            int alpha = pixel.A + (pixel.A % alphaFader);
                            pixelAlpha = (byte)(alpha > 255 ? 255 : alpha);
                        }

                        byte pixelRed = pixel.R;
                        byte pixelGreen = pixel.G;
                        byte pixelBlue = pixel.B;

                        pixelAlpha = (byte)((pixelAlpha >> 3) + 1);
                        pixelRed = (byte)((pixelRed >> 3) + 1);
                        pixelGreen = (byte)((pixelGreen >> 3) + 1);
                        pixelBlue = (byte)((pixelBlue >> 3) + 1);
                        moments[pixelAlpha, pixelRed, pixelGreen, pixelBlue].Add(pixel);
                    }
                }
            }

            // Set a default pixel for images with less than 256 colors.
            moments[0, 0, 0, 0].Add(new Color32(0, 0, 0, 0));
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Quantizes the image contained within the <see cref="ImageBuffer"/> returning the result.
 /// </summary>
 /// <param name="imageBuffer">
 /// The <see cref="ImageBuffer"/> for storing and manipulating pixel information..
 /// </param>
 /// <param name="colorCount">
 /// The maximum number of colors apply to the image.
 /// </param>
 /// <param name="lookups">
 /// The array of <see cref="Color32"/> containing indexed versions of the images colors.
 /// </param>
 /// <param name="alphaThreshold">
 /// All colors with an alpha value less than this will be considered fully transparent.
 /// </param>
 /// <returns>
 /// The quantized <see cref="Bitmap"/>.
 /// </returns>
 internal abstract Bitmap GetQuantizedImage(ImageBuffer imageBuffer, int colorCount, Color32[] lookups, int alphaThreshold);
Ejemplo n.º 4
0
        /// <summary>
        /// Quantize an image and return the resulting output bitmap
        /// </summary>
        /// <param name="source">
        /// The 32 bit per pixel image to quantize.
        /// </param>
        /// <param name="alphaThreshold">
        /// All colors with an alpha value less than this will be considered fully transparent.
        /// </param>
        /// <param name="alphaFader">
        /// Alpha values will be normalized to the nearest multiple of this value.
        /// </param>
        /// <param name="histogram">
        /// The <see cref="Histogram"/> representing the distribution of color data.
        /// </param>
        /// <param name="maxColors">
        /// The maximum number of colors apply to the image.
        /// </param>
        /// <returns>
        /// A quantized version of the image.
        /// </returns>
        public Bitmap Quantize(Image source, int alphaThreshold, int alphaFader, Histogram histogram, int maxColors)
        {
            try
            {
                ImageBuffer buffer;

                // The image has to be a 32 bit per pixel Argb image.
                if (Image.GetPixelFormatSize(source.PixelFormat) != 32)
                {
                    Bitmap clone = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppPArgb);
                    clone.SetResolution(source.HorizontalResolution, source.VerticalResolution);

                    using (Graphics graphics = Graphics.FromImage(clone))
                    {
                        graphics.PageUnit = GraphicsUnit.Pixel;
                        graphics.Clear(Color.Transparent);
                        graphics.DrawImageUnscaled(source, new Rectangle(0, 0, clone.Width, clone.Height));
                    }

                    source.Dispose();
                    buffer = new ImageBuffer(clone);
                }
                else
                {
                    buffer = new ImageBuffer((Bitmap)source);
                }

                if (histogram == null)
                {
                    histogram = new Histogram();
                }
                else
                {
                    histogram.Clear();
                }

                BuildHistogram(histogram, buffer, alphaThreshold, alphaFader);
                CalculateMoments(histogram.Moments);
                Box[] cubes = SplitData(ref maxColors, histogram.Moments);
                Color32[] lookups = BuildLookups(cubes, histogram.Moments);
                return this.GetQuantizedImage(buffer, maxColors, lookups, alphaThreshold);
            }
            catch (Exception ex)
            {
                throw new QuantizationException(ex.Message, ex);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets an enumerable array of bytes representing each row of the image.
        /// </summary>
        /// <param name="image">
        /// The <see cref="ImageBuffer"/> for storing and manipulating pixel information.
        /// </param>
        /// <param name="lookups">
        /// The array of <see cref="Color32"/> containing indexed versions of the images colors.
        /// </param>
        /// <param name="alphaThreshold">
        /// The alpha threshold.
        /// </param>
        /// <param name="paletteHistogram">
        /// The palette histogram.
        /// </param>
        /// <returns>
        /// The enumerable list of <see cref="byte"/> representing each pixel.
        /// </returns>
        private static IEnumerable<byte[]> IndexedPixels(ImageBuffer image, Color32[] lookups, int alphaThreshold, PaletteColorHistory[] paletteHistogram)
        {
            byte[] lineIndexes = new byte[image.Image.Width];
            PaletteLookup lookup = new PaletteLookup(lookups);

            // Determine the correct fallback color.
            byte fallback = lookups.Length < AlphaMax ? AlphaMin : AlphaMax;
            foreach (Color32[] pixelLine in image.PixelLines)
            {
                int length = pixelLine.Length;
                for (int i = 0; i < length; i++)
                {
                    Color32 pixel = pixelLine[i];
                    byte bestMatch = fallback;
                    if (pixel.A > alphaThreshold)
                    {
                        bestMatch = lookup.GetPaletteIndex(pixel);
                        paletteHistogram[bestMatch].AddPixel(pixel);
                    }

                    lineIndexes[i] = bestMatch;
                }

                yield return lineIndexes;
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Quantizes the image contained within the <see cref="ImageBuffer"/> returning the result.
 /// </summary>
 /// <param name="imageBuffer">
 /// The <see cref="ImageBuffer"/> for storing and manipulating pixel information..
 /// </param>
 /// <param name="colorCount">
 /// The maximum number of colors apply to the image.
 /// </param>
 /// <param name="lookups">
 /// The array of <see cref="Color32"/> containing indexed versions of the images colors.
 /// </param>
 /// <param name="alphaThreshold">
 /// All colors with an alpha value less than this will be considered fully transparent.
 /// </param>
 /// <returns>
 /// The quantized <see cref="Bitmap"/>.
 /// </returns>
 internal abstract Bitmap GetQuantizedImage(ImageBuffer imageBuffer, int colorCount, Color32[] lookups, int alphaThreshold);