示例#1
0
        /// <summary>
        /// (see http://stackoverflow.com/questions/16346212/can-you-change-one-colour-to-another-in-an-bitmap-image
        /// and https://msdn.microsoft.com/en-GB/library/ms229672%28v=vs.90%29.aspx)
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="inColourR"></param>
        /// <param name="inColourG"></param>
        /// <param name="inColourB"></param>
        /// <param name="outColourR"></param>
        /// <param name="outColourG"></param>
        /// <param name="outColourB"></param>
        internal unsafe static Bitmap changeColour(this Bitmap original, Color oldColor, Color newColor, int Tolerance = 0,enPixelCompare CompareType = enPixelCompare.pc_RGB_all)
        {
            byte inColourR_max, inColourG_max, inColourB_max;
            byte inColourR_min, inColourG_min, inColourB_min;
            byte outColourR, outColourG, outColourB;
            int tempValue;

            //create a clone of the original
            Bitmap newBitmap = (Bitmap)original.Clone();

            tempValue = (int)oldColor.R + Tolerance;
            inColourR_max = (tempValue > 255) ? (byte)255 : (byte)tempValue ; 

            tempValue = (int)oldColor.G + Tolerance;
            inColourG_max = (tempValue > 255) ? (byte)255 : (byte)tempValue ; 

            tempValue = (int)oldColor.B + Tolerance;
            inColourB_max = (tempValue > 255) ? (byte)255 : (byte)tempValue ; 

            tempValue = (int)oldColor.R - Tolerance;
            inColourR_min = (tempValue < 0) ? (byte)0 : (byte)tempValue ; 

            tempValue = (int)oldColor.G - Tolerance;
            inColourG_min = (tempValue < 0) ? (byte)0: (byte)tempValue ; 

            tempValue = (int)oldColor.B - Tolerance;
            inColourB_min = (tempValue < 0) ? (byte)0 : (byte)tempValue ; 

            outColourR = newColor.R;
            outColourG = newColor.G;
            outColourB = newColor.B;

            // Specify a pixel format.
            PixelFormat pxf = original.PixelFormat;

            // Lock the bitmap's bits.
            Rectangle rect      = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
            BitmapData bmpData  = newBitmap.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap. 
            // int numBytes = newBitmap.Width * newBitmap.Height * 3; 
            int numBytes = bmpData.Stride * newBitmap.Height;
            byte[] rgbValues = new byte[numBytes];

            // Copy the RGB values into the array.
            Marshal.Copy(ptr, rgbValues, 0, numBytes);
            
            double newColorBrightness = (double)(newColor.R+newColor.R+newColor.B+newColor.G+newColor.G+newColor.G)/6.0;

            // Manipulate the bitmap
            for (int line = 0; line < bmpData.Height ; line += 1)
            {
                for (int pixel = 0; (pixel+3) < bmpData.Stride ; pixel += 3)
                {
                    int currentPixel = line * bmpData.Stride + pixel;

                    switch (CompareType)
                    {
                        case enPixelCompare.pc_RGB_all:
                            if (((rgbValues[currentPixel]     >= inColourB_min) && (rgbValues[currentPixel]      <= inColourB_max)) &&
                                ((rgbValues[currentPixel + 1] >= inColourG_min) && (rgbValues[currentPixel + 1]  <= inColourG_max)) &&
                                ((rgbValues[currentPixel + 2] >= inColourR_min) && (rgbValues[currentPixel + 2]  <= inColourR_max)))
                            {
                                rgbValues[currentPixel]      = outColourB;
                                rgbValues[currentPixel + 1]  = outColourG;
                                rgbValues[currentPixel + 2]  = outColourR;
                            }
                            break;
                        case enPixelCompare.pc_RGB_single:
                            if (((rgbValues[currentPixel]     >= inColourB_min) && (rgbValues[currentPixel]      <= inColourB_max)) ||
                                ((rgbValues[currentPixel + 1] >= inColourG_min) && (rgbValues[currentPixel + 1]  <= inColourG_max)) ||
                                ((rgbValues[currentPixel + 2] >= inColourR_min) && (rgbValues[currentPixel + 2]  <= inColourR_max)))
                            {
                                rgbValues[currentPixel]      = outColourB;
                                rgbValues[currentPixel + 1]  = outColourG;
                                rgbValues[currentPixel + 2]  = outColourR;
                            }
                            break;
                        case enPixelCompare.pc_Brightness:
                            double currentBrighness = (double)(rgbValues[currentPixel + 2]+rgbValues[currentPixel + 2]+
                                                             rgbValues[currentPixel]    +
                                                             rgbValues[currentPixel + 1]+rgbValues[currentPixel + 1]+rgbValues[currentPixel + 1])
                                                             /6.0;

                            if (Math.Abs(currentBrighness - newColorBrightness) <= Tolerance)
                            {
                                rgbValues[currentPixel]      = outColourB;
                                rgbValues[currentPixel + 1]  = outColourG;
                                rgbValues[currentPixel + 2]  = outColourR;
                            }
                            break;
                    }
                }
            }

            // Copy the RGB values back to the bitmap
            Marshal.Copy(rgbValues, 0, ptr, numBytes);

            // Unlock the bits.
            newBitmap.UnlockBits(bmpData);

            return newBitmap;
        }
示例#2
0
文件: RNGraphics.cs 项目: mlof/ED-IBE
        /// <summary>
        /// (see http://stackoverflow.com/questions/16346212/can-you-change-one-colour-to-another-in-an-bitmap-image
        /// and https://msdn.microsoft.com/en-GB/library/ms229672%28v=vs.90%29.aspx)
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="inColourR"></param>
        /// <param name="inColourG"></param>
        /// <param name="inColourB"></param>
        /// <param name="outColourR"></param>
        /// <param name="outColourG"></param>
        /// <param name="outColourB"></param>
        internal unsafe static Bitmap changeColour(this Bitmap original, Color oldColor, Color newColor, int Tolerance = 0, enPixelCompare CompareType = enPixelCompare.pc_RGB_all)
        {
            byte inColourR_max, inColourG_max, inColourB_max;
            byte inColourR_min, inColourG_min, inColourB_min;
            byte outColourR, outColourG, outColourB;
            int  tempValue;

            //create a clone of the original
            Bitmap newBitmap = (Bitmap)original.Clone();

            tempValue     = (int)oldColor.R + Tolerance;
            inColourR_max = (tempValue > 255) ? (byte)255 : (byte)tempValue;

            tempValue     = (int)oldColor.G + Tolerance;
            inColourG_max = (tempValue > 255) ? (byte)255 : (byte)tempValue;

            tempValue     = (int)oldColor.B + Tolerance;
            inColourB_max = (tempValue > 255) ? (byte)255 : (byte)tempValue;

            tempValue     = (int)oldColor.R - Tolerance;
            inColourR_min = (tempValue < 0) ? (byte)0 : (byte)tempValue;

            tempValue     = (int)oldColor.G - Tolerance;
            inColourG_min = (tempValue < 0) ? (byte)0: (byte)tempValue;

            tempValue     = (int)oldColor.B - Tolerance;
            inColourB_min = (tempValue < 0) ? (byte)0 : (byte)tempValue;

            outColourR = newColor.R;
            outColourG = newColor.G;
            outColourB = newColor.B;

            // Specify a pixel format.
            PixelFormat pxf = original.PixelFormat;

            // Lock the bitmap's bits.
            Rectangle  rect    = new Rectangle(0, 0, newBitmap.Width, newBitmap.Height);
            BitmapData bmpData = newBitmap.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            // int numBytes = newBitmap.Width * newBitmap.Height * 3;
            int numBytes = bmpData.Stride * newBitmap.Height;

            byte[] rgbValues = new byte[numBytes];

            // Copy the RGB values into the array.
            Marshal.Copy(ptr, rgbValues, 0, numBytes);

            double newColorBrightness = (double)(newColor.R + newColor.R + newColor.B + newColor.G + newColor.G + newColor.G) / 6.0;

            // Manipulate the bitmap
            for (int line = 0; line < bmpData.Height; line += 1)
            {
                for (int pixel = 0; (pixel + 3) < bmpData.Stride; pixel += 3)
                {
                    int currentPixel = line * bmpData.Stride + pixel;

                    switch (CompareType)
                    {
                    case enPixelCompare.pc_RGB_all:
                        if (((rgbValues[currentPixel] >= inColourB_min) && (rgbValues[currentPixel] <= inColourB_max)) &&
                            ((rgbValues[currentPixel + 1] >= inColourG_min) && (rgbValues[currentPixel + 1] <= inColourG_max)) &&
                            ((rgbValues[currentPixel + 2] >= inColourR_min) && (rgbValues[currentPixel + 2] <= inColourR_max)))
                        {
                            rgbValues[currentPixel]     = outColourB;
                            rgbValues[currentPixel + 1] = outColourG;
                            rgbValues[currentPixel + 2] = outColourR;
                        }
                        break;

                    case enPixelCompare.pc_RGB_single:
                        if (((rgbValues[currentPixel] >= inColourB_min) && (rgbValues[currentPixel] <= inColourB_max)) ||
                            ((rgbValues[currentPixel + 1] >= inColourG_min) && (rgbValues[currentPixel + 1] <= inColourG_max)) ||
                            ((rgbValues[currentPixel + 2] >= inColourR_min) && (rgbValues[currentPixel + 2] <= inColourR_max)))
                        {
                            rgbValues[currentPixel]     = outColourB;
                            rgbValues[currentPixel + 1] = outColourG;
                            rgbValues[currentPixel + 2] = outColourR;
                        }
                        break;

                    case enPixelCompare.pc_Brightness:
                        double currentBrighness = (double)(rgbValues[currentPixel + 2] + rgbValues[currentPixel + 2] +
                                                           rgbValues[currentPixel] +
                                                           rgbValues[currentPixel + 1] + rgbValues[currentPixel + 1] + rgbValues[currentPixel + 1])
                                                  / 6.0;

                        if (Math.Abs(currentBrighness - newColorBrightness) <= Tolerance)
                        {
                            rgbValues[currentPixel]     = outColourB;
                            rgbValues[currentPixel + 1] = outColourG;
                            rgbValues[currentPixel + 2] = outColourR;
                        }
                        break;
                    }
                }
            }

            // Copy the RGB values back to the bitmap
            Marshal.Copy(rgbValues, 0, ptr, numBytes);

            // Unlock the bits.
            newBitmap.UnlockBits(bmpData);

            return(newBitmap);
        }