Example #1
0
        /// <summary>
        ///     Get a rectangle for the image which crops the image of all colors equal to that on 0,0
        /// </summary>
        /// <param name="image"></param>
        /// <param name="cropDifference"></param>
        /// <returns>NativeRect</returns>
        public static NativeRect FindAutoCropRectangle(this Image image, int cropDifference)
        {
            var cropRectangle = NativeRect.Empty;
            var checkPoints   = new List <NativePoint>
            {
                new NativePoint(0, 0),
                new NativePoint(0, image.Height - 1),
                new NativePoint(image.Width - 1, 0),
                new NativePoint(image.Width - 1, image.Height - 1)
            };

            // Top Left
            // Bottom Left
            // Top Right
            // Bottom Right
            using (var fastBitmap = FastBitmapFactory.Create((Bitmap)image))
            {
                // find biggest area
                foreach (var checkPoint in checkPoints)
                {
                    var currentRectangle = fastBitmap.FindAutoCropRectangle(fastBitmap.GetColorAt(checkPoint.X, checkPoint.Y), cropDifference);
                    if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height)
                    {
                        cropRectangle = currentRectangle;
                    }
                }
            }
            return(cropRectangle);
        }
Example #2
0
        public virtual Bitmap Apply(Bitmap sourceBitmap, Matrix matrix)
        {
            var result = FastBitmapFactory.CreateCloneOf(sourceBitmap);

            result.ApplyBoxBlur(Range);
            return(result.UnlockAndReturnBitmap());
        }
Example #3
0
 /// <summary>
 ///     Apply BoxBlur to the destinationBitmap
 /// </summary>
 /// <param name="destinationBitmap">Bitmap to blur</param>
 /// <param name="range">Must be ODD, if not +1 is used</param>
 public static void ApplyBoxBlur(this 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 (var fastBitmap = FastBitmapFactory.Create(destinationBitmap))
     {
         fastBitmap.ApplyBoxBlur(range);
     }
 }
Example #4
0
 /// <summary>
 /// Create stitching information for this bitmap
 /// </summary>
 /// <param name="bitmap">Bitmap</param>
 public StitchInfo(Bitmap bitmap)
 {
     _bitmap = bitmap;
     using (var fastBitmap = FastBitmapFactory.Create(bitmap))
     {
         _hashes = Enumerable.Range(0, fastBitmap.Height).Select(i => fastBitmap.HorizontalHash(i)).ToList();
     }
     _sourceRect = new NativeRect(NativePoint.Empty, bitmap.Size);
 }
Example #5
0
        /// <summary>
        ///     Use "Scale2x" algorithm to produce bitmap from the original.
        /// </summary>
        /// <param name="original">Bitmap to scale 2x</param>
        public static Bitmap Scale2X(this Bitmap original)
        {
            using (var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original))
                using (var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width << 1, original.Height << 1), original.PixelFormat))
                {
                    // Every pixel from input texture produces 4 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
                    Parallel.For(0, source.Height, y =>
                    {
                        unsafe
                        {
                            var colorB = stackalloc byte[4];
                            var colorD = stackalloc byte[4];
                            var colorE = stackalloc byte[4];
                            var colorF = stackalloc byte[4];
                            var colorH = stackalloc byte[4];
                            var x      = 0;
                            while (x < source.Width)
                            {
                                source.GetColorAt(x, y - 1, colorB);
                                source.GetColorAt(x, y + 1, colorH);
                                source.GetColorAt(x - 1, y, colorD);
                                source.GetColorAt(x + 1, y, colorF);
                                source.GetColorAt(x, y, colorE);

                                byte *colorE0, colorE1, colorE2, colorE3;
                                if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
                                {
                                    colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
                                    colorE1 = AreColorsSame(colorB, colorF) ? colorF : colorE;
                                    colorE2 = AreColorsSame(colorD, colorH) ? colorD : colorE;
                                    colorE3 = AreColorsSame(colorH, colorF) ? colorF : colorE;
                                }
                                else
                                {
                                    colorE0 = colorE;
                                    colorE1 = colorE;
                                    colorE2 = colorE;
                                    colorE3 = colorE;
                                }

                                destination.SetColorAt(x << 1, y << 1, colorE0);
                                destination.SetColorAt((x << 1) + 1, y << 1, colorE1);
                                destination.SetColorAt(x << 1, (y << 1) + 1, colorE2);
                                destination.SetColorAt((x << 1) + 1, (y << 1) + 1, colorE3);

                                x++;
                            }
                        }
                    });
                    return(destination.UnlockAndReturnBitmap());
                }
        }
Example #6
0
 /// <summary>
 ///     Helper method to remove the corners from a DMW capture
 /// </summary>
 /// <param name="image">The bitmap to remove the corners from.</param>
 private static void RemoveCorners(Bitmap image)
 {
     using (var fastBitmap = FastBitmapFactory.Create(image))
     {
         for (var y = 0; y < CoreConfiguration.WindowCornerCutShape.Count; y++)
         {
             for (var x = 0; x < CoreConfiguration.WindowCornerCutShape[y]; x++)
             {
                 fastBitmap.SetColorAt(x, y, ref _transparentColor);
                 fastBitmap.SetColorAt(image.Width - 1 - x, y, ref _transparentColor);
                 fastBitmap.SetColorAt(image.Width - 1 - x, image.Height - 1 - y, ref _transparentColor);
                 fastBitmap.SetColorAt(x, image.Height - 1 - y, ref _transparentColor);
             }
         }
     }
 }
Example #7
0
 /// <summary>
 ///     Apply transparency by comparing a transparent capture with a black and white background
 ///     A "Math.min" makes sure there is no overflow, but this could cause the picture to have shifted colors.
 ///     The pictures should have been taken without differency, except for the colors.
 /// </summary>
 /// <param name="blackBitmap">Bitmap with the black image</param>
 /// <param name="whiteBitmap">Bitmap with the black image</param>
 /// <returns>Bitmap with transparency</returns>
 private static Bitmap ApplyTransparency(Bitmap blackBitmap, Bitmap whiteBitmap)
 {
     using (var targetBuffer = FastBitmapFactory.CreateEmpty(blackBitmap.Size, PixelFormat.Format32bppArgb, Color.Transparent))
     {
         targetBuffer.SetResolution(blackBitmap.HorizontalResolution, blackBitmap.VerticalResolution);
         using (var blackBuffer = FastBitmapFactory.Create(blackBitmap))
         {
             using (var whiteBuffer = FastBitmapFactory.Create(whiteBitmap))
             {
                 for (var y = 0; y < blackBuffer.Height; y++)
                 {
                     for (var x = 0; x < blackBuffer.Width; x++)
                     {
                         var c0 = blackBuffer.GetColorAt(x, y);
                         var c1 = whiteBuffer.GetColorAt(x, y);
                         // Calculate alpha as double in range 0-1
                         var alpha = c0.R - c1.R + 255;
                         if (alpha == 255)
                         {
                             // Alpha == 255 means no change!
                             targetBuffer.SetColorAt(x, y, ref c0);
                         }
                         else if (alpha == 0)
                         {
                             // Complete transparency, use transparent pixel
                             targetBuffer.SetColorAt(x, y, ref _transparentColor);
                         }
                         else
                         {
                             // Calculate original color
                             var originalAlpha = (byte)Math.Min(255, alpha);
                             var alphaFactor   = alpha / 255d;
                             //Log.Debug().WriteLine("Alpha {0} & c0 {1} & c1 {2}", alpha, c0, c1);
                             var originalRed   = (byte)Math.Min(255, c0.R / alphaFactor);
                             var originalGreen = (byte)Math.Min(255, c0.G / alphaFactor);
                             var originalBlue  = (byte)Math.Min(255, c0.B / alphaFactor);
                             var originalColor = Color.FromArgb(originalAlpha, originalRed, originalGreen, originalBlue);
                             //Color originalColor = Color.FromArgb(originalAlpha, originalRed, c0.G, c0.B);
                             targetBuffer.SetColorAt(x, y, ref originalColor);
                         }
                     }
                 }
             }
         }
         return(targetBuffer.UnlockAndReturnBitmap());
     }
 }
Example #8
0
 /// <summary>
 ///     Returns a b/w of Bitmap
 /// </summary>
 /// <param name="sourceBitmap">Bitmap to create a b/w of</param>
 /// <param name="threshold">Threshold for monochrome filter (0 - 255), lower value means less black</param>
 /// <returns>b/w bitmap</returns>
 public static Bitmap CreateMonochrome(Bitmap sourceBitmap, byte threshold)
 {
     using (var fastBitmap = FastBitmapFactory.CreateCloneOf(sourceBitmap, sourceBitmap.PixelFormat))
     {
         Parallel.For(0, fastBitmap.Height, y =>
         {
             // TODO: use stackalloc / unsafe
             for (var x = 0; x < fastBitmap.Width; x++)
             {
                 var color           = fastBitmap.GetColorAt(x, y);
                 var colorBrightness = (color.R + color.G + color.B) / 3 > threshold ? 255 : 0;
                 var monoColor       = Color.FromArgb(color.A, colorBrightness, colorBrightness, colorBrightness);
                 fastBitmap.SetColorAt(x, y, ref monoColor);
             }
         });
         return(fastBitmap.UnlockAndReturnBitmap());
     }
 }
Example #9
0
        /// <summary>
        /// Check if the bitmaps are equal
        /// </summary>
        /// <param name="bitmap1">Bitmap</param>
        /// <param name="bitmap2">Bitmap</param>
        /// <returns>bool true if they are equal</returns>
        public static bool IsEqualTo(this Bitmap bitmap1, Bitmap bitmap2)
        {
            if (bitmap1.Width != bitmap2.Width || bitmap1.Height != bitmap2.Height)
            {
                Log.Debug().WriteLine("Different sizes 1={0}, 2={1}", bitmap1.Size, bitmap2.Size);
                // Different sizes
                return(false);
            }

            if (bitmap1.PixelFormat != bitmap2.PixelFormat)
            {
                // Different pixel formats
                Log.Debug().WriteLine("Different pixel formats 1={0}, 2={1}", bitmap1.PixelFormat, bitmap2.PixelFormat);
                return(false);
            }
            bool result = true;

            using (var fastBitmap1 = FastBitmapFactory.Create(bitmap1))
                using (var fastBitmap2 = FastBitmapFactory.Create(bitmap2))
                {
                    Parallel.For(0, fastBitmap1.Height, (y, state) =>
                    {
                        unsafe
                        {
                            var tmpColor1 = stackalloc byte[4];
                            var tmpColor2 = stackalloc byte[4];
                            for (int x = 0; x < fastBitmap1.Width; x++)
                            {
                                fastBitmap1.GetColorAt(x, y, tmpColor1);
                                fastBitmap2.GetColorAt(x, y, tmpColor2);
                                if (AreColorsSame(tmpColor1, tmpColor2))
                                {
                                    continue;
                                }
                                Log.Debug().WriteLine("Different colors at {0},{1}", x, y);
                                result = false;
                                state.Break();
                            }
                        }
                    });
                }
            return(result);
        }
Example #10
0
        /// <summary>
        ///     Count how many times the supplied color exists
        /// </summary>
        /// <param name="sourceImage">Image to count the pixels of</param>
        /// <param name="colorToCount">Color to count</param>
        /// <param name="includeAlpha">true if Alpha needs to be checked</param>
        /// <returns>int with the number of pixels which have colorToCount</returns>
        public static int CountColor(this Image sourceImage, Color colorToCount, bool includeAlpha = true)
        {
            var lockObject = new object();
            var colors     = 0;
            var toCount    = colorToCount.ToArgb();

            if (!includeAlpha)
            {
                toCount = toCount & 0xffffff;
            }
            using (var bb = FastBitmapFactory.Create((Bitmap)sourceImage))
            {
                Parallel.For(0, bb.Height, () => 0, (y, state, initialColorCount) =>
                {
                    var currentColors = initialColorCount;
                    for (var x = 0; x < bb.Width; x++)
                    {
                        var bitmapcolor = bb.GetColorAt(x, y).ToArgb();
                        if (!includeAlpha)
                        {
                            bitmapcolor = bitmapcolor & 0xffffff;
                        }
                        if (bitmapcolor == toCount)
                        {
                            currentColors++;
                        }
                    }
                    return(currentColors);
                }, lineColorCount =>
                {
                    lock (lockObject)
                    {
                        colors += lineColorCount;
                    }
                });

                return(colors);
            }
        }
Example #11
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, NativeRect rect, RenderMode renderMode)
        {
            var applyRect = BitmapHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);

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

            if (Invert)
            {
                graphics.SetClip(applyRect);
                graphics.ExcludeClip(rect);
            }
            using (var fastBitmap = FastBitmapFactory.CreateCloneOf(applyBitmap, area: applyRect))
            {
                var highlightColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
                Parallel.For(fastBitmap.Top, fastBitmap.Bottom, y =>
                {
                    unsafe
                    {
                        var tmpColor = stackalloc byte[4];
                        for (var x = fastBitmap.Left; x < fastBitmap.Right; x++)
                        {
                            fastBitmap.GetColorAt(x, y, tmpColor);
                            tmpColor[FastBitmapBase.ColorIndexR] = Math.Min(highlightColor.R, tmpColor[FastBitmapBase.ColorIndexR]);
                            tmpColor[FastBitmapBase.ColorIndexG] = Math.Min(highlightColor.G, tmpColor[FastBitmapBase.ColorIndexG]);
                            tmpColor[FastBitmapBase.ColorIndexB] = Math.Min(highlightColor.B, tmpColor[FastBitmapBase.ColorIndexB]);
                            fastBitmap.SetColorAt(x, y, tmpColor);
                        }
                    }
                });
                fastBitmap.DrawTo(graphics, applyRect.Location);
            }
            graphics.Restore(graphicsState);
        }
Example #12
0
        public override void Apply(Graphics graphics, Bitmap applyBitmap, NativeRect rect, RenderMode renderMode)
        {
            var blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
            var applyRect  = BitmapHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);

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

            if (Invert)
            {
                graphics.SetClip(applyRect);
                graphics.ExcludeClip(rect);
            }
            using (var fastBitmap = FastBitmapFactory.CreateCloneOf(applyBitmap, area: applyRect))
            {
                fastBitmap.ApplyBoxBlur(blurRadius);
                fastBitmap.DrawTo(graphics, applyRect);
            }
            graphics.Restore(state);
        }
Example #13
0
        /// <summary>
        ///     Get the image
        /// </summary>
        public Bitmap GetQuantizedImage(int allowedColorCount = 256)
        {
            if (allowedColorCount > 256)
            {
                throw new ArgumentOutOfRangeException(nameof(allowedColorCount), "Quantizing muss be done to get less than 256 colors");
            }
            if (_colorCount < allowedColorCount)
            {
                // Simple logic to reduce to 8 bit
                Log.Info().WriteLine("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().WriteLine("Calculated the moments...");
            var next           = 0;
            var volumeVariance = new float[Maxcolor];

            // processes the cubes
            for (var 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;
                var temp = volumeVariance[0];

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

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

            var lookupRed   = new int[Maxcolor];
            var lookupGreen = new int[Maxcolor];
            var lookupBlue  = new int[Maxcolor];

            _tag = new byte[Maxvolume];

            // precalculates lookup tables
            for (var k = 0; k < allowedColorCount; ++k)
            {
                Mark(_cubes[k], k, _tag);

                var 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 int[allowedColorCount + 1];
            _greens = new int[allowedColorCount + 1];
            _blues  = new int[allowedColorCount + 1];
            _sums   = new int[allowedColorCount + 1];

            Log.Info().WriteLine("Starting bitmap reconstruction...");

            using (var dest = FastBitmapFactory.Create(_resultBitmap) as FastChunkyBitmap)
            {
                using (var src = FastBitmapFactory.Create(_sourceBitmap))
                {
                    var srcBlend = src as IFastBitmapWithBlend;
                    var lookup   = new Dictionary <Color, byte>();
                    for (var y = 0; y < src.Height; y++)
                    {
                        for (var 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
                            byte bestMatch;
                            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];

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

                                    var 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
            var imagePalette = _resultBitmap.Palette;
            var entries      = imagePalette.Entries;

            for (var 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.
            var tmpBitmap = _resultBitmap;

            _resultBitmap = null;
            return(tmpBitmap);
        }
Example #14
0
        public WuQuantizer(Bitmap sourceBitmap)
        {
            _sourceBitmap = sourceBitmap;
            // Make sure the color count variables are reset
            var bitArray = new BitArray((int)Math.Pow(2, 24));

            _colorCount = 0;

            // creates all the cubes
            _cubes = new WuColorCube[Maxcolor];

            // initializes all the cubes
            for (var 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 long[Sidesize, Sidesize, Sidesize];
            _momentsRed   = new long[Sidesize, Sidesize, Sidesize];
            _momentsGreen = new long[Sidesize, Sidesize, Sidesize];
            _momentsBlue  = new long[Sidesize, Sidesize, Sidesize];
            _moments      = new float[Sidesize, Sidesize, Sidesize];

            var table = new int[256];

            for (var 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 (var sourceFastBitmap = FastBitmapFactory.Create(sourceBitmap))
            {
                var sourceFastBitmapWithBlend = sourceFastBitmap as IFastBitmapWithBlend;
                sourceFastBitmap.Lock();
                using (var destinationFastBitmap = FastBitmapFactory.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap)
                {
                    for (var y = 0; y < sourceFastBitmap.Height; y++)
                    {
                        for (var 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
                            var 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);
                            }

                            var indexRed   = (color.R >> 3) + 1;
                            var indexGreen = (color.G >> 3) + 1;
                            var 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"
                            var paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
                            destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
                        }
                    }
                    _resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
                }
            }
        }
Example #15
0
        public override void Apply(Graphics graphics, Bitmap applyBitmap, NativeRect rect, RenderMode renderMode)
        {
            var pixelSize = GetFieldValueAsInt(FieldTypes.PIXEL_SIZE);

            BitmapHelper.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 (var dest = FastBitmapFactory.CreateCloneOf(applyBitmap, area: rect))
            {
                using (var src = FastBitmapFactory.Create(applyBitmap, rect))
                {
                    var halbPixelSize = pixelSize / 2;
                    // Create a list of x values
                    var xValues = new List <int>();
                    for (var x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
                    {
                        xValues.Add(x);
                    }
                    for (var y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
                    {
                        Parallel.ForEach(xValues, x =>
                        {
                            // TODO: Use stackalloc, or byte[]?
                            var colors = new List <Color>();
                            for (var yy = y; yy < y + pixelSize; yy++)
                            {
                                if (yy < src.Top || yy >= src.Bottom)
                                {
                                    continue;
                                }
                                for (var xx = x; xx < x + pixelSize; xx++)
                                {
                                    if (xx < src.Left || xx >= src.Right)
                                    {
                                        continue;
                                    }
                                    colors.Add(src.GetColorAt(xx, yy));
                                }
                            }
                            var currentAvgColor = Colors.Mix(colors);
                            for (var yy = y; yy <= y + pixelSize; yy++)
                            {
                                if (yy < src.Top || yy >= src.Bottom)
                                {
                                    continue;
                                }
                                for (var xx = x; xx <= x + pixelSize; xx++)
                                {
                                    if (xx < src.Left || xx >= src.Right)
                                    {
                                        continue;
                                    }
                                    dest.SetColorAt(xx, yy, ref currentAvgColor);
                                }
                            }
                        });
                    }
                }
                dest.DrawTo(graphics, rect.Location);
            }
        }
Example #16
0
        public static Bitmap Scale3X(this Bitmap original)
        {
            using (var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original))
                using (var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width * 3, original.Height * 3), original.PixelFormat))
                {
                    // Every pixel from input texture produces 6 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
                    Parallel.For(0, source.Height, y =>
                    {
                        unsafe
                        {
                            var x      = 0;
                            var colorA = stackalloc byte[4];
                            var colorB = stackalloc byte[4];
                            var colorC = stackalloc byte[4];
                            var colorD = stackalloc byte[4];
                            var colorE = stackalloc byte[4];
                            var colorF = stackalloc byte[4];
                            var colorG = stackalloc byte[4];
                            var colorH = stackalloc byte[4];
                            var colorI = stackalloc byte[4];
                            while (x < source.Width)
                            {
                                source.GetColorAt(x - 1, y - 1, colorA);
                                source.GetColorAt(x, y - 1, colorB);
                                source.GetColorAt(x + 1, y - 1, colorC);

                                source.GetColorAt(x - 1, y, colorD);
                                source.GetColorAt(x, y, colorE);
                                source.GetColorAt(x + 1, y, colorF);

                                source.GetColorAt(x - 1, y + 1, colorG);
                                source.GetColorAt(x, y + 1, colorH);
                                source.GetColorAt(x + 1, y + 1, colorI);

                                byte *colorE0, colorE1, colorE2, colorE3, colorE4, colorE5, colorE6, colorE7, colorE8;

                                if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
                                {
                                    colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
                                    colorE1 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorC) || AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorA) ? colorB : colorE;
                                    colorE2 = AreColorsSame(colorB, colorF) ? colorF : colorE;
                                    colorE3 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorG) || AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorA) ? colorD : colorE;

                                    colorE4 = colorE;
                                    colorE5 = AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorC) ? colorF : colorE;
                                    colorE6 = AreColorsSame(colorD, colorH) ? colorD : colorE;
                                    colorE7 = AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorG) ? colorH : colorE;
                                    colorE8 = AreColorsSame(colorH, colorF) ? colorF : colorE;
                                }
                                else
                                {
                                    colorE0 = colorE;
                                    colorE1 = colorE;
                                    colorE2 = colorE;
                                    colorE3 = colorE;
                                    colorE4 = colorE;
                                    colorE5 = colorE;
                                    colorE6 = colorE;
                                    colorE7 = colorE;
                                    colorE8 = colorE;
                                }
                                var multipliedX = 3 * x;
                                var multipliedY = 3 * y;

                                destination.SetColorAt(multipliedX, multipliedY, colorE0);
                                destination.SetColorAt(multipliedX + 1, multipliedY, colorE1);
                                destination.SetColorAt(multipliedX + 2, multipliedY, colorE2);

                                multipliedY++;
                                destination.SetColorAt(multipliedX, multipliedY, colorE3);
                                destination.SetColorAt(multipliedX + 1, multipliedY, colorE4);
                                destination.SetColorAt(multipliedX + 2, multipliedY, colorE5);

                                multipliedY++;
                                destination.SetColorAt(multipliedX, multipliedY, colorE6);
                                destination.SetColorAt(multipliedX + 1, multipliedY, colorE7);
                                destination.SetColorAt(multipliedX + 2, multipliedY, colorE8);

                                x++;
                            }
                        }
                    });
                    return(destination.UnlockAndReturnBitmap());
                }
        }
Example #17
0
        /// <summary>
        ///     Reindex the 24/32 BPP (A)RGB image to a 8BPP
        /// </summary>
        /// <returns>Bitmap</returns>
        public Bitmap SimpleReindex()
        {
            var colors = new List <Color>();
            var lookup = new Dictionary <Color, byte>();

            using (var bbbDest = FastBitmapFactory.Create(_resultBitmap) as FastChunkyBitmap)
            {
                bbbDest.Lock();
                using (var bbbSrc = FastBitmapFactory.Create(_sourceBitmap))
                {
                    var bbbSrcBlend = bbbSrc as IFastBitmapWithBlend;

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

            for (var 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.
            var tmpBitmap = _resultBitmap;

            _resultBitmap = null;
            return(tmpBitmap);
        }