示例#1
0
        /// <summary>
        /// Color filtering in HSL color space.
        /// </summary>
        public static unsafe Bitmap HSLFilter(Bitmap image, Rectangle rect, IntRange hue, DoubleRange sat, DoubleRange lum)
        {
            Bitmap     dest        = new Bitmap(image.Width, image.Height, PixelFormat.Format8bppIndexed);
            BitmapData source      = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);
            BitmapData destination = dest.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, dest.PixelFormat);
            int        startX      = rect.Left;
            int        startY      = rect.Top;
            int        stopX       = rect.Right;
            int        stopY       = rect.Bottom;

            // get pixel size
            int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
            int srcOffset = source.Stride - rect.Width * pixelSize;
            int dstOffset = destination.Stride - rect.Width;

            RGB rgb = new RGB();
            HSL hsl = new HSL();

            // do the job
            byte *src = (byte *)source.Scan0 + startY * source.Stride + startX * pixelSize;
            byte *dst = (byte *)destination.Scan0 + startY * destination.Stride + startX;

            // for each row
            for (int y = startY; y < stopY; y++)
            {
                // for each pixel
                for (int x = startX; x < stopX; x++, src += pixelSize, dst++)
                {
                    rgb.Red   = src[RGB.R];
                    rgb.Green = src[RGB.G];
                    rgb.Blue  = src[RGB.B];

                    // convert to HSL
                    HSL.FromRGB(rgb, hsl);

                    // check HSL values
                    if (hue.IsInside(hsl.Hue) && sat.IsInside(hsl.Saturation) && lum.IsInside(hsl.Luminance))
                    {
                        *dst = 0;
                    }
                    else
                    {
                        *dst = 255;
                    }
                }

                src += srcOffset;
                dst += dstOffset;
            }

            int width  = image.Width;
            int height = image.Height;
            int stride = destination.Stride;

            // remove upper part
            for (int y = 0; y < startY; y++)
            {
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, stride);
            }

            // remove lower part
            for (int y = stopY; y < height; y++)
            {
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, stride);
            }

            for (int y = startY; y < stopY; y++)
            {
                // remove left part
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, startX);

                // remove right part
                dst += stopX;
                SystemTools.SetUnmanagedMemory(dst, 255, stride - stopX);
            }

            image.UnlockBits(source);
            dest.UnlockBits(destination);

            return(dest);
        }
示例#2
0
        /// <summary>
        /// Adjust hue saturation lightness of image
        /// </summary>
        public static unsafe Bitmap AdjustHSL(Bitmap image, Rectangle rect, int hue, int saturation, int lightness)
        {
            int        pixelSize = Image.GetPixelFormatSize(image.PixelFormat) / 8;
            Bitmap     dest      = (Bitmap)image.Clone();
            BitmapData imgDat    = dest.LockBits(rect, ImageLockMode.ReadWrite, dest.PixelFormat);

            int startX = rect.Left;
            int startY = rect.Top;
            int stopX  = startX + rect.Width;
            int stopY  = startY + rect.Height;
            int offset = imgDat.Stride - rect.Width * pixelSize;

            RGB rgb = new RGB();
            HSL hsl = new HSL();

            // do the job
            byte *img = (byte *)imgDat.Scan0;

            // align pointer to the first pixel to process
            img += (startY * imgDat.Stride + startX * pixelSize);

            int intensity;
            int a, invA;
            RGB blendColor;

            if (lightness > 0)
            {
                a          = (int)((lightness * 255) / 100);
                blendColor = new RGB(255, 255, 255);
            }
            else
            {
                a          = (int)((-lightness * 255) / 100);
                blendColor = new RGB(0, 0, 0);
            }
            invA = 255 - a;

            if (lightness == 0)
            {
                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++, img += pixelSize)
                    {
                        // adjust saturation
                        intensity = (int)((7471 * img[RGB.B] + 38470 * img[RGB.G] + 19595 * img[RGB.R]) >> 16);
                        rgb.Red   = ClampToByte((intensity * 1024 + (img[RGB.R] - intensity) * saturation) >> 10);
                        rgb.Green = ClampToByte((intensity * 1024 + (img[RGB.G] - intensity) * saturation) >> 10);
                        rgb.Blue  = ClampToByte((intensity * 1024 + (img[RGB.B] - intensity) * saturation) >> 10);

                        // adjust hue
                        hsl      = HSL.FromRGB(rgb);
                        hsl.Hue += hue;
                        if (hsl.Hue < 0)
                        {
                            hsl.Hue += 360;
                        }
                        else if (hsl.Hue > 360)
                        {
                            hsl.Hue -= 360;
                        }
                        rgb = hsl.ToRGB();

                        img[RGB.R] = rgb.Red;
                        img[RGB.G] = rgb.Green;
                        img[RGB.B] = rgb.Blue;
                    }
                    img += offset;
                }
            }
            else
            {
                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++, img += pixelSize)
                    {
                        // adjust saturation
                        intensity = (int)((7471 * img[RGB.B] + 38470 * img[RGB.G] + 19595 * img[RGB.R]) >> 16);
                        rgb.Red   = ClampToByte((intensity * 1024 + (img[RGB.R] - intensity) * saturation) >> 10);
                        rgb.Green = ClampToByte((intensity * 1024 + (img[RGB.G] - intensity) * saturation) >> 10);
                        rgb.Blue  = ClampToByte((intensity * 1024 + (img[RGB.B] - intensity) * saturation) >> 10);

                        // adjust hue
                        hsl      = HSL.FromRGB(rgb);
                        hsl.Hue += hue;
                        if (hsl.Hue < 0)
                        {
                            hsl.Hue += 360;
                        }
                        else if (hsl.Hue > 360)
                        {
                            hsl.Hue -= 360;
                        }
                        rgb = hsl.ToRGB();

                        // adjust lightness
                        img[RGB.R] = (byte)(((rgb.Red * invA) + (blendColor.Red * a)) / 256);
                        img[RGB.G] = (byte)(((rgb.Green * invA) + (blendColor.Green * a)) / 256);
                        img[RGB.B] = (byte)(((rgb.Blue * invA) + (blendColor.Blue * a)) / 256);
                    }
                    img += offset;
                }
            }

            dest.UnlockBits(imgDat);

            return(dest);
        }