Example #1
0
        public Image Pixelate(Image sourceImage, int pixelSize)
        {
            if (sourceImage == null || !(sourceImage is Bitmap))
            {
                return(sourceImage);
            }

            if (sourceImage.Width < pixelSize)
            {
                pixelSize = sourceImage.Width;
            }
            if (sourceImage.Height < pixelSize)
            {
                pixelSize = sourceImage.Height;
            }

            using (IFastBitmap dest = FastBitmap.CreateCloneOf(sourceImage)) {
                using (IFastBitmap src = FastBitmap.Create(sourceImage as Bitmap)) {
                    FastBitmap.MixColors(dest, src, pixelSize);
                }

                Bitmap bmp = new Bitmap(dest.Width, dest.Height, sourceImage.PixelFormat);
                using (Graphics graphics = Graphics.FromImage(bmp)) {
                    dest.DrawTo(graphics, Point.Empty);
                }
                return(bmp);
            }
        }
Example #2
0
 private void ApplyBoxBlur(Bitmap destinationBitmap, int range)
 {
     // We only need one fastbitmap as we use it as source and target (the reading is done for one line H/V, writing after "parsing" one line H/V)
     using (IFastBitmap fastBitmap = FastBitmap.Create(destinationBitmap)) {
         FastBitmapOperator.ApplyBoxBlur(fastBitmap, range);
     }
 }
Example #3
0
        /// <summary>
        /// Implements the Apply code for the Brightness Filet
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="applyBitmap"></param>
        /// <param name="rect"></param>
        /// <param name="renderMode"></param>
        public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
        {
            Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);

            if (applyRect.Width == 0 || applyRect.Height == 0)
            {
                // nothing to do
                return;
            }
            GraphicsState state = graphics.Save();

            if (Invert)
            {
                graphics.SetClip(applyRect);
                graphics.ExcludeClip(rect);
            }
            using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect)) {
                Color highlightColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
                for (int y = fastBitmap.Top; y < fastBitmap.Bottom; y++)
                {
                    for (int x = fastBitmap.Left; x < fastBitmap.Right; x++)
                    {
                        Color color = fastBitmap.GetColorAt(x, y);
                        color = Color.FromArgb(color.A, Math.Min(highlightColor.R, color.R), Math.Min(highlightColor.G, color.G), Math.Min(highlightColor.B, color.B));
                        fastBitmap.SetColorAt(x, y, color);
                    }
                }
                fastBitmap.DrawTo(graphics, applyRect.Location);
            }
            graphics.Restore(state);
        }
Example #4
0
        public static void ApplyBoxBlur(IFastBitmap fastBitmap, int range)
        {
            // Range must be odd!
            if ((range & 1) == 0)
            {
                range++;
            }
            if (range <= 1)
            {
                return;
            }

            // Box blurs are frequently used to approximate a Gaussian blur.
            // By the central limit theorem, if applied 3 times on the same image, a box blur approximates the Gaussian kernel to within about 3%, yielding the same result as a quadratic convolution kernel.
            // This might be true, but the GDI+ BlurEffect doesn't look the same, a 2x blur is more simular and we only make 2x Box-Blur.
            // (Might also be a mistake in our blur, but for now it looks great)
            if (fastBitmap.hasAlphaChannel)
            {
                BoxBlurHorizontalAlpha(fastBitmap, range);
                BoxBlurVerticalAlpha(fastBitmap, range);
                BoxBlurHorizontalAlpha(fastBitmap, range);
                BoxBlurVerticalAlpha(fastBitmap, range);
            }
            else
            {
                BoxBlurHorizontal(fastBitmap, range);
                BoxBlurVertical(fastBitmap, range);
                BoxBlurHorizontal(fastBitmap, range);
                BoxBlurVertical(fastBitmap, range);
            }
        }
        public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
        {
            int       pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE);
            Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);

            if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0)
            {
                // Nothing to do
                return;
            }
            if (rect.Width < pixelSize)
            {
                pixelSize = rect.Width;
            }
            if (rect.Height < pixelSize)
            {
                pixelSize = rect.Height;
            }
            using (IFastBitmap dest = FastBitmap.CreateCloneOf(applyBitmap, rect)) {
                using (IFastBitmap src = FastBitmap.Create(applyBitmap, rect)) {
                    List <Color> colors        = new List <Color>();
                    int          halbPixelSize = pixelSize / 2;
                    for (int y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
                    {
                        for (int x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
                        {
                            colors.Clear();
                            for (int yy = y; yy < y + pixelSize; yy++)
                            {
                                if (yy >= src.Top && yy < src.Bottom)
                                {
                                    for (int xx = x; xx < x + pixelSize; xx++)
                                    {
                                        if (xx >= src.Left && xx < src.Right)
                                        {
                                            colors.Add(src.GetColorAt(xx, yy));
                                        }
                                    }
                                }
                            }
                            Color currentAvgColor = Colors.Mix(colors);
                            for (int yy = y; yy <= y + pixelSize; yy++)
                            {
                                if (yy >= src.Top && yy < src.Bottom)
                                {
                                    for (int xx = x; xx <= x + pixelSize; xx++)
                                    {
                                        if (xx >= src.Left && xx < src.Right)
                                        {
                                            dest.SetColorAt(xx, yy, currentAvgColor);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                dest.DrawTo(graphics, rect.Location);
            }
        }
 /// <summary>
 /// Apply BoxBlur to the fastBitmap
 /// </summary>
 /// <param name="fastBitmap">IFastBitmap to blur</param>
 /// <param name="range">Must be ODD!</param>
 public static void ApplyBoxBlur(IFastBitmap fastBitmap, int range)
 {
     // Range must be odd!
     if ((range & 1) == 0)
     {
         range++;
     }
     if (range <= 1)
     {
         return;
     }
     // Box blurs are frequently used to approximate a Gaussian blur.
     // By the central limit theorem, if applied 3 times on the same image, a box blur approximates the Gaussian kernel to within about 3%, yielding the same result as a quadratic convolution kernel.
     // This might be true, but the GDI+ BlurEffect doesn't look the same, a 2x blur is more simular and we only make 2x Box-Blur.
     // (Might also be a mistake in our blur, but for now it looks great)
     if (fastBitmap.hasAlphaChannel)
     {
         BoxBlurHorizontalAlpha(fastBitmap, range);
         BoxBlurVerticalAlpha(fastBitmap, range);
         BoxBlurHorizontalAlpha(fastBitmap, range);
         BoxBlurVerticalAlpha(fastBitmap, range);
     }
     else
     {
         BoxBlurHorizontal(fastBitmap, range);
         BoxBlurVertical(fastBitmap, range);
         BoxBlurHorizontal(fastBitmap, range);
         BoxBlurVertical(fastBitmap, range);
     }
 }
Example #7
0
        public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
        {
            int       blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
            Rectangle applyRect  = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);

            if (applyRect.Width == 0 || applyRect.Height == 0)
            {
                return;
            }
            GraphicsState state = graphics.Save();

            if (Invert)
            {
                graphics.SetClip(applyRect);
                graphics.ExcludeClip(rect);
            }
            if (GDIplus.IsBlurPossible(blurRadius))
            {
                GDIplus.DrawWithBlur(graphics, applyBitmap, applyRect, null, null, blurRadius, false);
            }
            else
            {
                using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect))
                {
                    ImageHelper.ApplyBoxBlur(fastBitmap, blurRadius);
                    fastBitmap.DrawTo(graphics, applyRect);
                }
            }
            graphics.Restore(state);
        }
Example #8
0
        public static Rectangle FindAutoCropRectangle(Image image, int cropDifference)
        {
            Rectangle    cropRectangle    = Rectangle.Empty;
            Rectangle    currentRectangle = Rectangle.Empty;
            List <Point> checkPoints      = new List <Point>();

            // Top Left
            checkPoints.Add(new Point(0, 0));
            // Bottom Left
            checkPoints.Add(new Point(0, image.Height - 1));
            // Top Right
            checkPoints.Add(new Point(image.Width - 1, 0));
            // Bottom Right
            checkPoints.Add(new Point(image.Width - 1, image.Height - 1));
            using (IFastBitmap fastBitmap = FastBitmap.Create((Bitmap)image)) {
                // find biggest area
                foreach (Point checkPoint in checkPoints)
                {
                    currentRectangle = FastBitmapOperator.FindAutoCropRectangle(fastBitmap, checkPoint, cropDifference);
                    if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height)
                    {
                        cropRectangle = currentRectangle;
                    }
                }
            }
            return(cropRectangle);
        }
Example #9
0
        private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.hasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
            }

            int w         = targetFastBitmap.Width;
            int halfRange = range / 2;

            Color[] newColors      = new Color[targetFastBitmap.Height];
            int     oldPixelOffset = -(halfRange + 1) * w;
            int     newPixelOffset = (halfRange) * w;

            byte[] tmpColor = new byte[4];
            for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
            {
                int hits = 0;
                int a    = 0;
                int r    = 0;
                int g    = 0;
                int b    = 0;
                for (int y = targetFastBitmap.Top - halfRange; y < targetFastBitmap.Bottom; y++)
                {
                    int oldPixel = y - halfRange - 1;
                    if (oldPixel >= targetFastBitmap.Top)
                    {
                        targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
                        a -= tmpColor[FastBitmap.COLOR_INDEX_A];
                        r -= tmpColor[FastBitmap.COLOR_INDEX_R];
                        g -= tmpColor[FastBitmap.COLOR_INDEX_G];
                        b -= tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits--;
                    }

                    int newPixel = y + halfRange;
                    if (newPixel < targetFastBitmap.Bottom)
                    {
                        //int colorg = pixels[index + newPixelOffset];
                        targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
                        a += tmpColor[FastBitmap.COLOR_INDEX_A];
                        r += tmpColor[FastBitmap.COLOR_INDEX_R];
                        g += tmpColor[FastBitmap.COLOR_INDEX_G];
                        b += tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits++;
                    }

                    if (y >= targetFastBitmap.Top)
                    {
                        newColors[y - targetFastBitmap.Top] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }

                for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
                {
                    targetFastBitmap.SetColorAt(x, y, newColors[y - targetFastBitmap.Top]);
                }
            }
        }
Example #10
0
        /// <summary>
        /// Factory for creating a FastBitmap as a destination
        /// </summary>
        /// <param name="newSize"></param>
        /// <param name="pixelFormat"></param>
        /// <param name="backgroundColor"></param>
        /// <returns>IFastBitmap</returns>
        public static IFastBitmap CreateEmpty(Size newSize, PixelFormat pixelFormat, Color backgroundColor)
        {
            Bitmap      destination = ImageHelper.CreateEmpty(newSize.Width, newSize.Height, pixelFormat, backgroundColor, 96f, 96f);
            IFastBitmap fastBitmap  = Create(destination);

            fastBitmap.NeedsDispose = true;
            return(fastBitmap);
        }
Example #11
0
        /// <summary>
        ///     BoxBlurVertical is a private helper method for the BoxBlur
        /// </summary>
        /// <param name="targetFastBitmap">BitmapBuffer which previously was created with BoxBlurHorizontal</param>
        /// <param name="range">Range must be odd!</param>
        private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.HasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
            }

            var halfRange = range / 2;
            var newColors = new Color[targetFastBitmap.Height];
            var tmpColor  = new byte[4];

            for (var x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
            {
                var hits = 0;
                var a    = 0;
                var r    = 0;
                var g    = 0;
                var b    = 0;

                for (var y = targetFastBitmap.Top - halfRange; y < targetFastBitmap.Bottom; y++)
                {
                    var oldPixel = y - halfRange - 1;

                    if (oldPixel >= targetFastBitmap.Top)
                    {
                        targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
                        a -= tmpColor[FastBitmapBase.ColorIndexA];
                        r -= tmpColor[FastBitmapBase.ColorIndexR];
                        g -= tmpColor[FastBitmapBase.ColorIndexG];
                        b -= tmpColor[FastBitmapBase.ColorIndexB];
                        hits--;
                    }

                    var newPixel = y + halfRange;

                    if (newPixel < targetFastBitmap.Bottom)
                    {
                        //int colorg = pixels[index + newPixelOffset];
                        targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
                        a += tmpColor[FastBitmapBase.ColorIndexA];
                        r += tmpColor[FastBitmapBase.ColorIndexR];
                        g += tmpColor[FastBitmapBase.ColorIndexG];
                        b += tmpColor[FastBitmapBase.ColorIndexB];
                        hits++;
                    }

                    if (y >= targetFastBitmap.Top)
                    {
                        newColors[y - targetFastBitmap.Top] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }

                for (var y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
                {
                    targetFastBitmap.SetColorAt(x, y, ref newColors[y - targetFastBitmap.Top]);
                }
            }
        }
Example #12
0
        /// <summary>
        ///     BoxBlurHorizontal is a private helper method for the BoxBlur, only for IFastBitmaps with alpha channel
        /// </summary>
        /// <param name="targetFastBitmap">Target BitmapBuffer</param>
        /// <param name="range">Range must be odd!</param>
        private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.HasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
            }

            var halfRange = range / 2;
            var newColors = new Color[targetFastBitmap.Width];
            var tmpColor  = new byte[4];

            for (var y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
            {
                var hits = 0;
                var a    = 0;
                var r    = 0;
                var g    = 0;
                var b    = 0;

                for (var x = targetFastBitmap.Left - halfRange; x < targetFastBitmap.Right; x++)
                {
                    var oldPixel = x - halfRange - 1;

                    if (oldPixel >= targetFastBitmap.Left)
                    {
                        targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
                        a -= tmpColor[FastBitmapBase.ColorIndexA];
                        r -= tmpColor[FastBitmapBase.ColorIndexR];
                        g -= tmpColor[FastBitmapBase.ColorIndexG];
                        b -= tmpColor[FastBitmapBase.ColorIndexB];
                        hits--;
                    }

                    var newPixel = x + halfRange;

                    if (newPixel < targetFastBitmap.Right)
                    {
                        targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
                        a += tmpColor[FastBitmapBase.ColorIndexA];
                        r += tmpColor[FastBitmapBase.ColorIndexR];
                        g += tmpColor[FastBitmapBase.ColorIndexG];
                        b += tmpColor[FastBitmapBase.ColorIndexB];
                        hits++;
                    }

                    if (x >= targetFastBitmap.Left)
                    {
                        newColors[x - targetFastBitmap.Left] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }
                for (var x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
                {
                    targetFastBitmap.SetColorAt(x, y, ref newColors[x - targetFastBitmap.Left]);
                }
            }
        }
Example #13
0
        private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.hasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
            }
            int halfRange = range / 2;

            Color[] newColors = new Color[targetFastBitmap.Width];
            byte[]  tmpColor  = new byte[4];
            for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
            {
                int hits = 0;
                int a    = 0;
                int r    = 0;
                int g    = 0;
                int b    = 0;
                for (int x = targetFastBitmap.Left - halfRange; x < targetFastBitmap.Right; x++)
                {
                    int oldPixel = x - halfRange - 1;
                    if (oldPixel >= targetFastBitmap.Left)
                    {
                        targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
                        a -= tmpColor[FastBitmap.COLOR_INDEX_A];
                        r -= tmpColor[FastBitmap.COLOR_INDEX_R];
                        g -= tmpColor[FastBitmap.COLOR_INDEX_G];
                        b -= tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits--;
                    }

                    int newPixel = x + halfRange;
                    if (newPixel < targetFastBitmap.Right)
                    {
                        targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
                        a += tmpColor[FastBitmap.COLOR_INDEX_A];
                        r += tmpColor[FastBitmap.COLOR_INDEX_R];
                        g += tmpColor[FastBitmap.COLOR_INDEX_G];
                        b += tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits++;
                    }

                    if (x >= targetFastBitmap.Left)
                    {
                        newColors[x - targetFastBitmap.Left] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }
                for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
                {
                    targetFastBitmap.SetColorAt(x, y, newColors[x - targetFastBitmap.Left]);
                }
            }
        }
Example #14
0
        public static Bitmap Pixelate(Bitmap sourceImage, int pixelSize)
        {
            pixelSize = Math.Min(pixelSize, sourceImage.Width);
            pixelSize = Math.Min(pixelSize, sourceImage.Height);

            Bitmap result = sourceImage.CreateEmptyBitmap();

            using (IFastBitmap src = FastBitmap.Create(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height)))
                using (IFastBitmap dest = FastBitmap.Create(result))
                {
                    List <Color> colors        = new List <Color>();
                    int          halbPixelSize = pixelSize / 2;
                    for (int y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
                    {
                        for (int x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
                        {
                            colors.Clear();
                            for (int yy = y; yy < y + pixelSize; yy++)
                            {
                                if (yy >= src.Top && yy < src.Bottom)
                                {
                                    for (int xx = x; xx < x + pixelSize; xx++)
                                    {
                                        if (xx >= src.Left && xx < src.Right)
                                        {
                                            colors.Add(src.GetColorAt(xx, yy));
                                        }
                                    }
                                }
                            }
                            Color currentAvgColor = ColorHelpers.Mix(colors);
                            for (int yy = y; yy <= y + pixelSize; yy++)
                            {
                                if (yy >= src.Top && yy < src.Bottom)
                                {
                                    for (int xx = x; xx <= x + pixelSize; xx++)
                                    {
                                        if (xx >= src.Left && xx < src.Right)
                                        {
                                            dest.SetColorAt(xx, yy, currentAvgColor);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            return(result);
        }
Example #15
0
        public Image Blur(Image sourceImage, int radius)
        {
            if (sourceImage == null)
            {
                return(sourceImage);
            }

            using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(sourceImage)) {
                FastBitmapOperator.ApplyBoxBlur(fastBitmap, radius);
                Bitmap bmp = new Bitmap(sourceImage.Width, sourceImage.Height, sourceImage.PixelFormat);
                using (Graphics graphics = Graphics.FromImage(bmp)) {
                    fastBitmap.DrawTo(graphics, Point.Empty);
                }
                return(bmp);
            }
        }
Example #16
0
        //tiles = 16 means 16 x 16 atlas
        public List <Bitmap> Atlas2dInto1d(Bitmap atlas2d, int tiles, int atlassizezlimit)
        {
            IFastBitmap orig = d_FastBitmapFactory();

            orig.bmp = atlas2d;

            int tilesize = atlas2d.Width / tiles;

            int           atlasescount = Math.Max(1, (tiles * tiles * tilesize) / atlassizezlimit);
            List <Bitmap> atlases      = new List <Bitmap>();

            orig.Lock();

            //256 x 1
            IFastBitmap atlas1d = null;

            for (int i = 0; i < tiles * tiles; i++)
            {
                int x            = i % tiles;
                int y            = i / tiles;
                int tilesinatlas = (tiles * tiles / atlasescount);
                if (i % tilesinatlas == 0)
                {
                    if (atlas1d != null)
                    {
                        atlas1d.Unlock();
                        atlases.Add(atlas1d.bmp);
                    }
                    atlas1d     = d_FastBitmapFactory();
                    atlas1d.bmp = new Bitmap(tilesize, atlassizezlimit);
                    atlas1d.Lock();
                }
                for (int xx = 0; xx < tilesize; xx++)
                {
                    for (int yy = 0; yy < tilesize; yy++)
                    {
                        int c = orig.GetPixel(x * tilesize + xx, y * tilesize + yy);
                        atlas1d.SetPixel(xx, (i % tilesinatlas) * tilesize + yy, c);
                    }
                }
            }
            atlas1d.Unlock();
            atlases.Add(atlas1d.bmp);
            orig.Unlock();
            return(atlases);
        }
Example #17
0
        public override bool ProcessCapture(ISurface surface, ICaptureDetails captureDetails)
        {
            LOG.DebugFormat("Changing surface to grayscale!");
            using (IFastBitmap bbb = FastBitmap.Create(surface.Image as Bitmap)) {
                bbb.Lock();
                for (int y = 0; y < bbb.Height; y++)
                {
                    for (int x = 0; x < bbb.Width; x++)
                    {
                        Color color = bbb.GetColorAt(x, y);
                        int   luma  = (int)((0.3 * color.R) + (0.59 * color.G) + (0.11 * color.B));
                        color = Color.FromArgb(luma, luma, luma);
                        bbb.SetColorAt(x, y, color);
                    }
                }
            }

            return(true);
        }
Example #18
0
        public static void MixColors(IFastBitmap dest, IFastBitmap src, int pixelSize)
        {
            List <Color> colors        = new List <Color>();
            int          halbPixelSize = pixelSize / 2;

            for (int y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
            {
                for (int x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
                {
                    colors.Clear();
                    for (int yy = y; yy < y + pixelSize; yy++)
                    {
                        if (yy >= src.Top && yy < src.Bottom)
                        {
                            for (int xx = x; xx < x + pixelSize; xx++)
                            {
                                if (xx >= src.Left && xx < src.Right)
                                {
                                    colors.Add(src.GetColorAt(xx, yy));
                                }
                            }
                        }
                    }
                    Color currentAvgColor = Colors.Mix(colors);
                    for (int yy = y; yy <= y + pixelSize; yy++)
                    {
                        if (yy >= src.Top && yy < src.Bottom)
                        {
                            for (int xx = x; xx <= x + pixelSize; xx++)
                            {
                                if (xx >= src.Left && xx < src.Right)
                                {
                                    dest.SetColorAt(xx, yy, currentAvgColor);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #19
0
        /// <summary>
        ///     Private helper method for the FindAutoCropRectangle
        /// </summary>
        /// <param name="fastBitmap">IFastBitmap</param>
        /// <param name="referenceColor">color for reference</param>
        /// <param name="cropDifference">int</param>
        /// <returns>NativeRect</returns>
        private static NativeRect FindAutoCropRectangle(this IFastBitmap fastBitmap, Color referenceColor, int cropDifference)
        {
            var cropRectangle = NativeRect.Empty;
            var min           = new NativePoint(int.MaxValue, int.MaxValue);
            var max           = new NativePoint(int.MinValue, int.MinValue);

            if (cropDifference > 0)
            {
                for (var y = 0; y < fastBitmap.Height; y++)
                {
                    for (var x = 0; x < fastBitmap.Width; x++)
                    {
                        var currentColor = fastBitmap.GetColorAt(x, y);
                        var diffR        = Math.Abs(currentColor.R - referenceColor.R);
                        var diffG        = Math.Abs(currentColor.G - referenceColor.G);
                        var diffB        = Math.Abs(currentColor.B - referenceColor.B);
                        if ((diffR + diffG + diffB) / 3 <= cropDifference)
                        {
                            continue;
                        }
                        if (x < min.X)
                        {
                            min = min.ChangeX(x);
                        }
                        if (y < min.Y)
                        {
                            min = min.ChangeY(y);
                        }
                        if (x > max.X)
                        {
                            max = max.ChangeX(x);
                        }
                        if (y > max.Y)
                        {
                            max = max.ChangeY(y);
                        }
                    }
                }
            }
            else
            {
                for (var y = 0; y < fastBitmap.Height; y++)
                {
                    for (var x = 0; x < fastBitmap.Width; x++)
                    {
                        var currentColor = fastBitmap.GetColorAt(x, y);
                        if (!referenceColor.Equals(currentColor))
                        {
                            continue;
                        }
                        if (x < min.X)
                        {
                            min = min.ChangeX(x);
                        }
                        if (y < min.Y)
                        {
                            min = min.ChangeY(y);
                        }
                        if (x > max.X)
                        {
                            max = max.ChangeX(x);
                        }
                        if (y > max.Y)
                        {
                            max = max.ChangeY(y);
                        }
                    }
                }
            }

            if (!(NativePoint.Empty.Equals(min) && max.Equals(new NativePoint(fastBitmap.Width - 1, fastBitmap.Height - 1))) &&
                !(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue))
            {
                cropRectangle = new NativeRect(min.X, min.Y, max.X - min.X + 1, max.Y - min.Y + 1);
            }
            return(cropRectangle);
        }
Example #20
0
        public static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference)
        {
            Rectangle cropRectangle  = Rectangle.Empty;
            Color     referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y);
            Point     min            = new Point(int.MaxValue, int.MaxValue);
            Point     max            = new Point(int.MinValue, int.MinValue);

            if (cropDifference > 0)
            {
                for (int y = 0; y < fastBitmap.Height; y++)
                {
                    for (int x = 0; x < fastBitmap.Width; x++)
                    {
                        Color currentColor = fastBitmap.GetColorAt(x, y);
                        int   diffR        = Math.Abs(currentColor.R - referenceColor.R);
                        int   diffG        = Math.Abs(currentColor.G - referenceColor.G);
                        int   diffB        = Math.Abs(currentColor.B - referenceColor.B);
                        if (((diffR + diffG + diffB) / 3) > cropDifference)
                        {
                            if (x < min.X)
                            {
                                min.X = x;
                            }
                            if (y < min.Y)
                            {
                                min.Y = y;
                            }
                            if (x > max.X)
                            {
                                max.X = x;
                            }
                            if (y > max.Y)
                            {
                                max.Y = y;
                            }
                        }
                    }
                }
            }
            else
            {
                for (int y = 0; y < fastBitmap.Height; y++)
                {
                    for (int x = 0; x < fastBitmap.Width; x++)
                    {
                        Color currentColor = fastBitmap.GetColorAt(x, y);
                        if (referenceColor.Equals(currentColor))
                        {
                            if (x < min.X)
                            {
                                min.X = x;
                            }
                            if (y < min.Y)
                            {
                                min.Y = y;
                            }
                            if (x > max.X)
                            {
                                max.X = x;
                            }
                            if (y > max.Y)
                            {
                                max.Y = y;
                            }
                        }
                    }
                }
            }

            if (!(Point.Empty.Equals(min) && max.Equals(new Point(fastBitmap.Width - 1, fastBitmap.Height - 1))))
            {
                if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue))
                {
                    cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X + 1, max.Y - min.Y + 1);
                }
            }
            return(cropRectangle);
        }
Example #21
0
        private static void BoxBlurVertical(IFastBitmap targetFastBitmap, int range)
        {
            var halfRange = range / 2;

            Parallel.For(targetFastBitmap.Left, targetFastBitmap.Right, x =>
            {
                unsafe
                {
                    var readColor = stackalloc byte[4];
                    var averages  = stackalloc byte[range << 2];
                    var hits      = 0;
                    var a         = 0;
                    var r         = 0;
                    var g         = 0;
                    var b         = 0;
                    for (var y = targetFastBitmap.Top; y < targetFastBitmap.Top + halfRange; y++)
                    {
                        targetFastBitmap.GetColorAt(x, y, readColor);
                        a += readColor[FastBitmapBase.ColorIndexA];
                        r += readColor[FastBitmapBase.ColorIndexR];
                        g += readColor[FastBitmapBase.ColorIndexG];
                        b += readColor[FastBitmapBase.ColorIndexB];
                        hits++;
                    }
                    for (var y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
                    {
                        var topSide = y - halfRange - 1;
                        if (topSide >= targetFastBitmap.Top)
                        {
                            // Get value at the top side of range
                            targetFastBitmap.GetColorAt(x, topSide, readColor);
                            a -= readColor[FastBitmapBase.ColorIndexA];
                            r -= readColor[FastBitmapBase.ColorIndexR];
                            g -= readColor[FastBitmapBase.ColorIndexG];
                            b -= readColor[FastBitmapBase.ColorIndexB];
                            hits--;
                        }

                        var bottomSide = y + halfRange;
                        if (bottomSide < targetFastBitmap.Bottom)
                        {
                            targetFastBitmap.GetColorAt(x, bottomSide, readColor);
                            a += readColor[FastBitmapBase.ColorIndexA];
                            r += readColor[FastBitmapBase.ColorIndexR];
                            g += readColor[FastBitmapBase.ColorIndexG];
                            b += readColor[FastBitmapBase.ColorIndexB];
                            hits++;
                        }

                        var writeLocation = (y % range) << 2;
                        averages[writeLocation + FastBitmapBase.ColorIndexA] = (byte)(a / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexR] = (byte)(r / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexG] = (byte)(g / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexB] = (byte)(b / hits);

                        if (topSide >= targetFastBitmap.Top)
                        {
                            // Write the value from the calculated avarages
                            var readLocation = (topSide % range) << 2;
                            targetFastBitmap.SetColorAt(x, topSide, averages, readLocation);
                        }
                    }
                }
            });
        }
Example #22
0
        private static void BoxBlurHorizontal(IFastBitmap targetFastBitmap, int range)
        {
            var halfRange = range / 2;

            Parallel.For(targetFastBitmap.Top, targetFastBitmap.Bottom, y =>
            {
                unsafe
                {
                    var averages  = stackalloc byte[range << 2];
                    var readColor = stackalloc byte[4];
                    var a         = 0;
                    var r         = 0;
                    var g         = 0;
                    var b         = 0;
                    var hits      = halfRange;
                    for (var x = targetFastBitmap.Left; x < targetFastBitmap.Left + halfRange; x++)
                    {
                        targetFastBitmap.GetColorAt(x, y, readColor);
                        a += readColor[FastBitmapBase.ColorIndexA];
                        r += readColor[FastBitmapBase.ColorIndexR];
                        g += readColor[FastBitmapBase.ColorIndexG];
                        b += readColor[FastBitmapBase.ColorIndexB];
                    }
                    for (var x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
                    {
                        var leftSide = x - halfRange - 1;
                        if (leftSide >= targetFastBitmap.Left)
                        {
                            // Get value at the left side of range
                            targetFastBitmap.GetColorAt(leftSide, y, readColor);
                            a -= readColor[FastBitmapBase.ColorIndexA];
                            r -= readColor[FastBitmapBase.ColorIndexR];
                            g -= readColor[FastBitmapBase.ColorIndexG];
                            b -= readColor[FastBitmapBase.ColorIndexB];
                            hits--;
                        }

                        var rightSide = x + halfRange;
                        if (rightSide < targetFastBitmap.Right)
                        {
                            targetFastBitmap.GetColorAt(rightSide, y, readColor);
                            a += readColor[FastBitmapBase.ColorIndexA];
                            r += readColor[FastBitmapBase.ColorIndexR];
                            g += readColor[FastBitmapBase.ColorIndexG];
                            b += readColor[FastBitmapBase.ColorIndexB];
                            hits++;
                        }

                        var writeLocation = (x % range) << 2;
                        averages[writeLocation + FastBitmapBase.ColorIndexA] = (byte)(a / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexR] = (byte)(r / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexG] = (byte)(g / hits);
                        averages[writeLocation + FastBitmapBase.ColorIndexB] = (byte)(b / hits);

                        if (leftSide >= targetFastBitmap.Left)
                        {
                            // Now we can write the value from the calculated avarages
                            var readLocation = (leftSide % range) << 2;
                            targetFastBitmap.SetColorAt(leftSide, y, averages, readLocation);
                        }
                    }
                }
            });
        }
Example #23
0
        /// <summary>
        /// Private helper method for the FindAutoCropRectangle
        /// </summary>
        /// <param name="fastBitmap"></param>
        /// <param name="colorPoint"></param>
        /// <param name="cropDifference"></param>
        /// <returns>Rectangle</returns>
        private static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference)
        {
            Rectangle cropRectangle = Rectangle.Empty;
            Color referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y);
            Point min = new Point(int.MaxValue, int.MaxValue);
            Point max = new Point(int.MinValue, int.MinValue);

            if (cropDifference > 0)
            {
                for (int y = 0; y < fastBitmap.Height; y++)
                {
                    for (int x = 0; x < fastBitmap.Width; x++)
                    {
                        Color currentColor = fastBitmap.GetColorAt(x, y);
                        int diffR = Math.Abs(currentColor.R - referenceColor.R);
                        int diffG = Math.Abs(currentColor.G - referenceColor.G);
                        int diffB = Math.Abs(currentColor.B - referenceColor.B);
                        if (((diffR + diffG + diffB) / 3) <= cropDifference)
                        {
                            continue;
                        }
                        if (x < min.X) min.X = x;
                        if (y < min.Y) min.Y = y;
                        if (x > max.X) max.X = x;
                        if (y > max.Y) max.Y = y;
                    }
                }
            }
            else
            {
                for (int y = 0; y < fastBitmap.Height; y++)
                {
                    for (int x = 0; x < fastBitmap.Width; x++)
                    {
                        Color currentColor = fastBitmap.GetColorAt(x, y);
                        if (!referenceColor.Equals(currentColor))
                        {
                            continue;
                        }
                        if (x < min.X) min.X = x;
                        if (y < min.Y) min.Y = y;
                        if (x > max.X) max.X = x;
                        if (y > max.Y) max.Y = y;
                    }
                }
            }

            if (!(Point.Empty.Equals(min) && max.Equals(new Point(fastBitmap.Width - 1, fastBitmap.Height - 1))))
            {
                if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue))
                {
                    cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X + 1, max.Y - min.Y + 1);
                }
            }
            return cropRectangle;
        }
Example #24
0
        /// <summary>
        /// BoxBlurVertical is a private helper method for the BoxBlur
        /// </summary>
        /// <param name="targetFastBitmap">BitmapBuffer which previously was created with BoxBlurHorizontal</param>
        /// <param name="range">Range must be odd!</param>
        private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.hasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
            }

            int halfRange = range / 2;
            Color[] newColors = new Color[targetFastBitmap.Height];
            byte[] tmpColor = new byte[4];
            for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
            {
                int hits = 0;
                int a = 0;
                int r = 0;
                int g = 0;
                int b = 0;
                for (int y = targetFastBitmap.Top - halfRange; y < targetFastBitmap.Bottom; y++)
                {
                    int oldPixel = y - halfRange - 1;
                    if (oldPixel >= targetFastBitmap.Top)
                    {
                        targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
                        a -= tmpColor[FastBitmap.COLOR_INDEX_A];
                        r -= tmpColor[FastBitmap.COLOR_INDEX_R];
                        g -= tmpColor[FastBitmap.COLOR_INDEX_G];
                        b -= tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits--;
                    }

                    int newPixel = y + halfRange;
                    if (newPixel < targetFastBitmap.Bottom)
                    {
                        //int colorg = pixels[index + newPixelOffset];
                        targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
                        a += tmpColor[FastBitmap.COLOR_INDEX_A];
                        r += tmpColor[FastBitmap.COLOR_INDEX_R];
                        g += tmpColor[FastBitmap.COLOR_INDEX_G];
                        b += tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits++;
                    }

                    if (y >= targetFastBitmap.Top)
                    {
                        newColors[y - targetFastBitmap.Top] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }

                for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
                {
                    targetFastBitmap.SetColorAt(x, y, newColors[y - targetFastBitmap.Top]);
                }
            }
        }
Example #25
0
        /// <summary>
        /// BoxBlurHorizontal is a private helper method for the BoxBlur, only for IFastBitmaps with alpha channel
        /// </summary>
        /// <param name="targetFastBitmap">Target BitmapBuffer</param>
        /// <param name="range">Range must be odd!</param>
        private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range)
        {
            if (!targetFastBitmap.hasAlphaChannel)
            {
                throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
            }
            int halfRange = range / 2;
            Color[] newColors = new Color[targetFastBitmap.Width];
            byte[] tmpColor = new byte[4];
            for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
            {
                int hits = 0;
                int a = 0;
                int r = 0;
                int g = 0;
                int b = 0;
                for (int x = targetFastBitmap.Left - halfRange; x < targetFastBitmap.Right; x++)
                {
                    int oldPixel = x - halfRange - 1;
                    if (oldPixel >= targetFastBitmap.Left)
                    {
                        targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
                        a -= tmpColor[FastBitmap.COLOR_INDEX_A];
                        r -= tmpColor[FastBitmap.COLOR_INDEX_R];
                        g -= tmpColor[FastBitmap.COLOR_INDEX_G];
                        b -= tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits--;
                    }

                    int newPixel = x + halfRange;
                    if (newPixel < targetFastBitmap.Right)
                    {
                        targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
                        a += tmpColor[FastBitmap.COLOR_INDEX_A];
                        r += tmpColor[FastBitmap.COLOR_INDEX_R];
                        g += tmpColor[FastBitmap.COLOR_INDEX_G];
                        b += tmpColor[FastBitmap.COLOR_INDEX_B];
                        hits++;
                    }

                    if (x >= targetFastBitmap.Left)
                    {
                        newColors[x - targetFastBitmap.Left] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
                    }
                }
                for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
                {
                    targetFastBitmap.SetColorAt(x, y, newColors[x - targetFastBitmap.Left]);
                }
            }
        }
Example #26
0
        /// <summary>
        /// Get the image
        /// </summary>
        public Bitmap GetQuantizedImage(int allowedColorCount)
        {
            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
                LOG.Info("Colors in the image are already less as whished for, using simple copy to indexed image, no quantizing needed!");
                return(SimpleReindex());
            }
            // preprocess the colors
            CalculateMoments();
            LOG.Info("Calculated the moments...");
            Int32 next = 0;

            Single[] volumeVariance = new Single[MAXCOLOR];

            // processes the cubes
            for (Int32 cubeIndex = 1; cubeIndex < allowedColorCount; ++cubeIndex)
            {
                // if cut is possible; make it
                if (Cut(cubes[next], cubes[cubeIndex]))
                {
                    volumeVariance[next]      = cubes[next].Volume > 1 ? CalculateVariance(cubes[next]) : 0.0f;
                    volumeVariance[cubeIndex] = cubes[cubeIndex].Volume > 1 ? CalculateVariance(cubes[cubeIndex]) : 0.0f;
                }
                else
                {
                    // the cut was not possible, revert the index
                    volumeVariance[next] = 0.0f;
                    cubeIndex--;
                }

                next = 0;
                Single temp = volumeVariance[0];

                for (Int32 index = 1; index <= cubeIndex; ++index)
                {
                    if (volumeVariance[index] > temp)
                    {
                        temp = volumeVariance[index];
                        next = index;
                    }
                }

                if (temp <= 0.0)
                {
                    allowedColorCount = cubeIndex + 1;
                    break;
                }
            }

            Int32[] lookupRed   = new Int32[MAXCOLOR];
            Int32[] lookupGreen = new Int32[MAXCOLOR];
            Int32[] lookupBlue  = new Int32[MAXCOLOR];

            tag = new byte[MAXVOLUME];

            // precalculates lookup tables
            for (int k = 0; k < allowedColorCount; ++k)
            {
                Mark(cubes[k], k, tag);

                long weight = Volume(cubes[k], weights);

                if (weight > 0)
                {
                    lookupRed[k]   = (int)(Volume(cubes[k], momentsRed) / weight);
                    lookupGreen[k] = (int)(Volume(cubes[k], momentsGreen) / weight);
                    lookupBlue[k]  = (int)(Volume(cubes[k], momentsBlue) / weight);
                }
                else
                {
                    lookupRed[k]   = 0;
                    lookupGreen[k] = 0;
                    lookupBlue[k]  = 0;
                }
            }

            reds   = new Int32[allowedColorCount + 1];
            greens = new Int32[allowedColorCount + 1];
            blues  = new Int32[allowedColorCount + 1];
            sums   = new Int32[allowedColorCount + 1];

            LOG.Info("Starting bitmap reconstruction...");

            using (FastChunkyBitmap dest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap)
            {
                using (IFastBitmap src = FastBitmap.Create(sourceBitmap))
                {
                    IFastBitmapWithBlend     srcBlend = src as IFastBitmapWithBlend;
                    Dictionary <Color, byte> lookup   = new Dictionary <Color, byte>();
                    byte bestMatch;
                    for (int y = 0; y < src.Height; y++)
                    {
                        for (int x = 0; x < src.Width; x++)
                        {
                            Color color;
                            if (srcBlend != null)
                            {
                                // WithoutAlpha, this makes it possible to ignore the alpha
                                color = srcBlend.GetBlendedColorAt(x, y);
                            }
                            else
                            {
                                color = src.GetColorAt(x, y);
                            }

                            // Check if we already matched the color
                            if (!lookup.ContainsKey(color))
                            {
                                // If not we need to find the best match

                                // First get initial match
                                bestMatch = dest.GetColorIndexAt(x, y);
                                bestMatch = tag[bestMatch];

                                Int32 bestDistance = 100000000;
                                for (int lookupIndex = 0; lookupIndex < allowedColorCount; lookupIndex++)
                                {
                                    Int32 foundRed   = lookupRed[lookupIndex];
                                    Int32 foundGreen = lookupGreen[lookupIndex];
                                    Int32 foundBlue  = lookupBlue[lookupIndex];
                                    Int32 deltaRed   = color.R - foundRed;
                                    Int32 deltaGreen = color.G - foundGreen;
                                    Int32 deltaBlue  = color.B - foundBlue;

                                    Int32 distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;

                                    if (distance < bestDistance)
                                    {
                                        bestDistance = distance;
                                        bestMatch    = (byte)lookupIndex;
                                    }
                                }
                                lookup.Add(color, bestMatch);
                            }
                            else
                            {
                                // Already matched, so we just use the lookup
                                bestMatch = lookup[color];
                            }

                            reds[bestMatch]   += color.R;
                            greens[bestMatch] += color.G;
                            blues[bestMatch]  += color.B;
                            sums[bestMatch]++;

                            dest.SetColorIndexAt(x, y, bestMatch);
                        }
                    }
                }
            }

            // generates palette
            ColorPalette imagePalette = resultBitmap.Palette;

            Color[] entries = imagePalette.Entries;
            for (Int32 paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++)
            {
                if (sums[paletteIndex] > 0)
                {
                    reds[paletteIndex]   /= sums[paletteIndex];
                    greens[paletteIndex] /= sums[paletteIndex];
                    blues[paletteIndex]  /= sums[paletteIndex];
                }

                entries[paletteIndex] = Color.FromArgb(255, reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
            }
            resultBitmap.Palette = imagePalette;

            // Make sure the bitmap is not disposed, as we return it.
            Bitmap tmpBitmap = resultBitmap;

            resultBitmap = null;
            return(tmpBitmap);
        }
Example #27
0
        /// <summary>
        /// Reindex the 24/32 BPP (A)RGB image to a 8BPP
        /// </summary>
        /// <returns>Bitmap</returns>
        public Bitmap SimpleReindex()
        {
            List <Color>             colors = new List <Color>();
            Dictionary <Color, byte> lookup = new Dictionary <Color, byte>();

            using (FastChunkyBitmap bbbDest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap)
            {
                bbbDest.Lock();
                using (IFastBitmap bbbSrc = FastBitmap.Create(sourceBitmap))
                {
                    IFastBitmapWithBlend bbbSrcBlend = bbbSrc as IFastBitmapWithBlend;

                    bbbSrc.Lock();
                    byte index;
                    for (int y = 0; y < bbbSrc.Height; y++)
                    {
                        for (int x = 0; x < bbbSrc.Width; x++)
                        {
                            Color color;
                            if (bbbSrcBlend != null)
                            {
                                color = bbbSrcBlend.GetBlendedColorAt(x, y);
                            }
                            else
                            {
                                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;

            Color[] entries = imagePalette.Entries;
            for (Int32 paletteIndex = 0; paletteIndex < 256; paletteIndex++)
            {
                if (paletteIndex < colorCount)
                {
                    entries[paletteIndex] = colors[paletteIndex];
                }
                else
                {
                    entries[paletteIndex] = Color.Black;
                }
            }
            resultBitmap.Palette = imagePalette;

            // Make sure the bitmap is not disposed, as we return it.
            Bitmap tmpBitmap = resultBitmap;

            resultBitmap = null;
            return(tmpBitmap);
        }
Example #28
0
        /// <summary>
        /// See <see cref="IColorQuantizer.Prepare"/> for more details.
        /// </summary>
        public WuQuantizer(Bitmap sourceBitmap)
        {
            this.sourceBitmap = sourceBitmap;
            // Make sure the color count variables are reset
            BitArray bitArray = new BitArray((int)Math.Pow(2, 24));

            colorCount = 0;

            // creates all the cubes
            cubes = new WuColorCube[MAXCOLOR];

            // initializes all the cubes
            for (Int32 cubeIndex = 0; cubeIndex < MAXCOLOR; cubeIndex++)
            {
                cubes[cubeIndex] = new WuColorCube();
            }

            // resets the reference minimums
            cubes[0].RedMinimum   = 0;
            cubes[0].GreenMinimum = 0;
            cubes[0].BlueMinimum  = 0;

            // resets the reference maximums
            cubes[0].RedMaximum   = MAXSIDEINDEX;
            cubes[0].GreenMaximum = MAXSIDEINDEX;
            cubes[0].BlueMaximum  = MAXSIDEINDEX;

            weights      = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
            momentsRed   = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
            momentsGreen = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
            momentsBlue  = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
            moments      = new Single[SIDESIZE, SIDESIZE, SIDESIZE];

            Int32[] table = new Int32[256];

            for (Int32 tableIndex = 0; tableIndex < 256; ++tableIndex)
            {
                table[tableIndex] = tableIndex * tableIndex;
            }

            // Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
            using (IFastBitmap sourceFastBitmap = FastBitmap.Create(sourceBitmap))
            {
                IFastBitmapWithBlend sourceFastBitmapWithBlend = sourceFastBitmap as IFastBitmapWithBlend;
                sourceFastBitmap.Lock();
                using (FastChunkyBitmap destinationFastBitmap = FastBitmap.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap)
                {
                    destinationFastBitmap.Lock();
                    for (int y = 0; y < sourceFastBitmap.Height; y++)
                    {
                        for (int x = 0; x < sourceFastBitmap.Width; x++)
                        {
                            Color color;
                            if (sourceFastBitmapWithBlend == null)
                            {
                                color = sourceFastBitmap.GetColorAt(x, y);
                            }
                            else
                            {
                                color = sourceFastBitmapWithBlend.GetBlendedColorAt(x, y);
                            }
                            // To count the colors
                            int index = color.ToArgb() & 0x00ffffff;
                            // Check if we already have this color
                            if (!bitArray.Get(index))
                            {
                                // If not, add 1 to the single colors
                                colorCount++;
                                bitArray.Set(index, true);
                            }

                            Int32 indexRed   = (color.R >> 3) + 1;
                            Int32 indexGreen = (color.G >> 3) + 1;
                            Int32 indexBlue  = (color.B >> 3) + 1;

                            weights[indexRed, indexGreen, indexBlue]++;
                            momentsRed[indexRed, indexGreen, indexBlue]   += color.R;
                            momentsGreen[indexRed, indexGreen, indexBlue] += color.G;
                            momentsBlue[indexRed, indexGreen, indexBlue]  += color.B;
                            moments[indexRed, indexGreen, indexBlue]      += table[color.R] + table[color.G] + table[color.B];

                            // Store the initial "match"
                            Int32 paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
                            destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
                        }
                    }
                    resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
                }
            }
        }