/// <summary>
        /// Provides the interface for merging two bitmaps together.
        /// </summary>
        /// <param name="bitmapA">The first bitmap for the merge</param>
        /// <param name="bitmapB">The second bitmap for the merge</param>
        /// <returns>The resulting bitmap</returns>
        public Bitmap Merge(Bitmap bitmapA, Bitmap bitmapB)
        {
            // Build the storage for the resulting bitmap
            PixelFormat pixelFormat     = bitmapA.PixelFormat;
            Bitmap      resultingBitmap = new Bitmap(bitmapA.Width, bitmapA.Height, pixelFormat);

            // Perform the merge
            for (int w = 0; w < bitmapA.Width; w++)
            {
                for (int h = 0; h < bitmapA.Height; h++)
                {
                    Color pixelA = bitmapA.GetPixel(w, h);
                    Color pixelB = bitmapB.GetPixel(w, h);

                    if (!PixelUtils.ColorWithinThresholdOfWhite(pixelA, WhiteThreshold))
                    {
                        // Set to the average of the two pixels
                        if (PixelUtils.ColorsAreClose(pixelA, pixelB, LikenessThreshold))
                        {
                            resultingBitmap.SetPixel(w, h, pixelA);
                        }
                        else
                        {
                            int   brightnessA = PixelUtils.GetBrightness(pixelA);
                            int   brightnessB = PixelUtils.GetBrightness(pixelB);
                            Color blendedPixel;

                            // Determine which order to blend the pixels in
                            if (brightnessA > brightnessB)
                            {
                                blendedPixel = BlendPixels(pixelB, pixelA, BlendAmount);
                            }
                            else
                            {
                                blendedPixel = BlendPixels(pixelA, pixelB, BlendAmount);
                            }
                            resultingBitmap.SetPixel(w, h, blendedPixel);
                        }
                    }
                    else if (!PixelUtils.ColorWithinThresholdOfWhite(pixelA, WhiteThreshold))
                    {
                        // PixelA has valid data, copy it
                        resultingBitmap.SetPixel(w, h, pixelA);
                    }
                    else
                    {
                        // Just set this pixel to the value of pixelB
                        resultingBitmap.SetPixel(w, h, pixelB);
                    }
                }
            }

            return(resultingBitmap);
        }
Beispiel #2
0
        /// <summary>
        /// Determines if a tile is complete.
        /// </summary>
        /// <returns>True if complete, else false</returns>
        public bool IsComplete()
        {
            Bitmap tileImage = GetBitmap();
            int width = tileImage.Width;
            int height = tileImage.Height;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Color currentPixel = tileImage.GetPixel(x, y);
                    if (PixelUtils.ColorWithinThresholdOfWhite(currentPixel, 5))
                        return false;
                }
            }
            return true;
        }
Beispiel #3
0
        /// <summary>
        /// Provides the interface for merging two bitmaps together.
        /// </summary>
        /// <param name="bitmapA">The first bitmap for the merge</param>
        /// <param name="bitmapB">The second bitmap for the merge</param>
        /// <returns>The resulting bitmap</returns>
        public Bitmap Merge(Bitmap bitmapA, Bitmap bitmapB)
        {
            //ApplicationController.Instance.Logger.Log("Using fast");
            // Build the storage for the resulting bitmap
            PixelFormat pixelFormat     = bitmapA.PixelFormat;
            Bitmap      resultingBitmap = new Bitmap(bitmapA.Width, bitmapA.Height, pixelFormat);

            int width  = bitmapA.Width;
            int height = bitmapA.Height;

            unsafe
            {
                BitmapData bitmapAData         = bitmapA.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, pixelFormat);
                BitmapData bitmapBData         = bitmapB.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, pixelFormat);
                BitmapData resultingBitmapData = resultingBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, pixelFormat);

                int   bytesPerPixel  = Bitmap.GetPixelFormatSize(pixelFormat) / 8;
                int   heightInPixels = bitmapAData.Height;
                int   widthInBytes   = bitmapAData.Width * bytesPerPixel;
                byte *firstPixelA    = (byte *)bitmapAData.Scan0;
                byte *firstPixelB    = (byte *)bitmapBData.Scan0;
                byte *firstPixelRes  = (byte *)resultingBitmapData.Scan0;

                Parallel.For(0, heightInPixels, y =>
                {
                    byte *currentLineA   = firstPixelA + (y * bitmapAData.Stride);
                    byte *currentLineB   = firstPixelB + (y * bitmapBData.Stride);
                    byte *currentLineRes = firstPixelRes + (y * resultingBitmapData.Stride);

                    for (int x = 0; x < widthInBytes; x = x + bytesPerPixel)
                    {
                        // Load the RGB values for the bitmaps
                        int rA = currentLineA[x];
                        int rB = currentLineB[x];
                        int gA = currentLineA[x + 1];
                        int gB = currentLineB[x + 1];
                        int bA = currentLineA[x + 2];
                        int bB = currentLineB[x + 2];

                        // Translate to Microsoft classes
                        // TODO: It would probably be faster to cut out the middle-man here...
                        Color currentPixelA = Color.FromArgb(rA, gA, bA);
                        Color currentPixelB = Color.FromArgb(rB, gB, bB);

                        if (!PixelUtils.ColorWithinThresholdOfWhite(currentPixelA, WhiteThreshold))
                        {
                            if (PixelUtils.ColorsAreClose(currentPixelA, currentPixelB, LikenessThreshold))
                            {
                                // These colors are quite similar, just copy out the pixel from the first bitmap
                                currentLineRes[x]     = (byte)rA;
                                currentLineRes[x + 1] = (byte)gA;
                                currentLineRes[x + 2] = (byte)bA;
                            }
                            else
                            {
                                // Blend the pixels together
                                int brightnessA = PixelUtils.GetBrightness(currentPixelA);
                                int brightnessB = PixelUtils.GetBrightness(currentPixelB);
                                Color blendedPixel;

                                // Determine which order to blend the pixels in
                                if (brightnessA > brightnessB)
                                {
                                    blendedPixel = BlendPixels(currentPixelB, currentPixelA, BlendAmount);
                                }
                                else
                                {
                                    blendedPixel = BlendPixels(currentPixelA, currentPixelB, BlendAmount);
                                }

                                currentLineRes[x]     = blendedPixel.R;
                                currentLineRes[x + 1] = blendedPixel.G;
                                currentLineRes[x + 2] = blendedPixel.B;
                            }
                        }
                        else if (!PixelUtils.ColorWithinThresholdOfWhite(currentPixelA, WhiteThreshold))
                        {
                            // Just default to the pixel form bitmap a
                            currentLineRes[x]     = (byte)rA;
                            currentLineRes[x + 1] = (byte)gA;
                            currentLineRes[x + 2] = (byte)bA;
                        }
                        else
                        {
                            // Fall back to the pixel from bitmap b
                            currentLineRes[x]     = (byte)rB;
                            currentLineRes[x + 1] = (byte)gB;
                            currentLineRes[x + 2] = (byte)bB;
                        }
                    }
                });
            }

            return(resultingBitmap);
        }