Example #1
0
        /// <summary>
        /// Creates a comic rendered copy of the input image.
        /// </summary>
        public override Bitmap Render(Bitmap sourceImage)
        {
            GrayscaleToRGB convertColor = new GrayscaleToRGB();

            if (sourceImage.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                sourceImage = convertColor.Apply(sourceImage);
            }

            BilateralBlur blur  = new BilateralBlur(3, 0.1);
            Bitmap        comic = blur.Apply(sourceImage);

            // Edges
            Bitmap            grayscale = Grayscale.CommonAlgorithms.Y.Apply(comic);
            SobelEdgeDetector sobelEdge = new SobelEdgeDetector();

            sobelEdge.ScaleIntensity = true;
            Bitmap edgeLayer = sobelEdge.Apply(grayscale);

            edgeLayer = convertColor.Apply(edgeLayer);

            Invert invertEdge = new Invert();

            invertEdge.ApplyInPlace(edgeLayer);

            HSLLinear edgeLinear = new HSLLinear();

            edgeLinear.InLuminance.Min = 0;
            edgeLinear.InLuminance.Max = 0.8;
            edgeLinear.ApplyInPlace(edgeLayer);


            // highlights
            Bitmap     highlightLayer      = invertEdge.Apply(edgeLayer);
            Dilatation highlightDilitation = new Dilatation();

            highlightDilitation.ApplyInPlace(highlightLayer);

            BrightnessCorrection highlightBright = new BrightnessCorrection(-0.35);

            highlightBright.ApplyInPlace(highlightLayer);
            ColorDodge highlightBlend = new ColorDodge(highlightLayer);

            highlightBlend.ApplyInPlace(comic);


            // Merge edges with working layer
            Multiply multEdge = new Multiply(edgeLayer);

            multEdge.ApplyInPlace(comic);


            return(comic);
        }
Example #2
0
        public mFilterHSLLinear(wDomain SaturationIn, wDomain SaturationOut, wDomain LuminanceIn, wDomain LuminanceOut)
        {
            SatIn  = SaturationIn;
            SatOut = SaturationOut;
            LumIn  = LuminanceIn;
            LumOut = LuminanceOut;

            BitmapType = mFilter.BitmapTypes.None;

            Effect = new HSLLinear();

            Effect.InSaturation  = new Accord.Range((float)SatIn.T0, (float)SatIn.T1);
            Effect.OutSaturation = new Accord.Range((float)SatOut.T0, (float)SatOut.T1);

            Effect.InLuminance  = new Accord.Range((float)LumIn.T0, (float)LumIn.T1);
            Effect.OutLuminance = new Accord.Range((float)LumOut.T0, (float)LumOut.T1);

            filter = Effect;
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="f"></param>
        /// <param name="contrast">-1..1 float to adjust contrast. </param>
        /// <param name="brightness">-1..1 float to adjust luminance (brightness). 0 does nothing</param>
        /// <param name="saturation">-1..1 float to adjust saturation.  0 does nothing  </param>
        /// <param name="truncate">If false, adjusting brightness and luminance will adjust contrast also. True causes white/black washout instead.</param>
        protected void AdjustContrastBrightnessSaturation(HSLLinear f, float contrast, float brightness, float saturation, bool truncate)
        {
            brightness = Math.Max(-1.0f, Math.Min(1.0f, brightness));
            saturation = Math.Max(-1.0f, Math.Min(1.0f, saturation));
            contrast   = Math.Max(-1.0f, Math.Min(1.0f, contrast));


            // create luminance filter
            if (brightness > 0)
            {
                f.InLuminance  = new Range(0.0f, 1.0f - (truncate ? brightness : 0)); //TODO - isn't it better not to truncate, but compress?
                f.OutLuminance = new Range(brightness, 1.0f);
            }
            else
            {
                f.InLuminance  = new Range((truncate ? -brightness : 0), 1.0f);
                f.OutLuminance = new Range(0.0f, 1.0f + brightness);
            }
            // create saturation filter
            if (saturation > 0)
            {
                f.InSaturation  = new Range(0.0f, 1.0f - (truncate ? saturation : 0)); //Ditto?
                f.OutSaturation = new Range(saturation, 1.0f);
            }
            else
            {
                f.InSaturation  = new Range((truncate ? -saturation : 0), 1.0f);
                f.OutSaturation = new Range(0.0f, 1.0f + saturation);
            }

            if (contrast > 0)
            {
                float adjustment = contrast * (f.InLuminance.Max - f.InLuminance.Min) / 2;
                f.InLuminance = new Range(f.InLuminance.Min + adjustment, f.InLuminance.Max - adjustment);
            }
            else if (contrast < 0)
            {
                float adjustment = -contrast * (f.OutLuminance.Max - f.OutLuminance.Min) / 2;
                f.OutLuminance = new Range(f.OutLuminance.Min + adjustment, f.OutLuminance.Max - adjustment);
            }
        }
Example #4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Bitmap img = null;

            DA.GetData(0, ref img);
            Interval L = new Interval(0, 1);

            DA.GetData("Luminance", ref L);
            Interval S = new Interval(0, 1);

            DA.GetData("Saturation", ref S);
            Interval Y = new Interval(0, 255);

            DA.GetData("Luma", ref Y);
            Interval Cb = new Interval(-1, 1);

            DA.GetData("Chroma_Blue", ref Cb);
            Interval Cr = new Interval(-1, 1);

            DA.GetData("Chroma_Red", ref Cr);
            Interval R = new Interval(0, 255);

            DA.GetData("Red", ref R);
            Interval G = new Interval(0, 255);

            DA.GetData("Green", ref G);
            Interval B = new Interval(0, 255);

            DA.GetData("Blue", ref B);

            Bitmap filteredImage = img;

            Interval bInterval        = new Interval(0, 1);
            Interval Interval255      = new Interval(0, 255);
            Interval IntervalMinusOne = new Interval(-1, 1);

            //////////////////////////////////////////////////////////////////////////
            HSLLinear myHSLfilter = new HSLLinear();

            if (bInterval.IncludesInterval(L))
            {
                myHSLfilter.InLuminance = new AForge.Range(Convert.ToSingle(L.Min), Convert.ToSingle(L.Max));
            }
            if (bInterval.IncludesInterval(S))
            {
                myHSLfilter.InSaturation = new AForge.Range(Convert.ToSingle(S.Min), Convert.ToSingle(S.Max));
            }
            filteredImage = myHSLfilter.Apply(img);
            //////////////////////////////////////////////////////////////////////////
            YCbCrLinear myYCbCrfilter = new YCbCrLinear();

            if (Interval255.IncludesInterval(Y))
            {
                myYCbCrfilter.InCb = new AForge.Range(Convert.ToSingle(Y.Min), Convert.ToSingle(Y.Max));
            }
            if (IntervalMinusOne.IncludesInterval(Cb))
            {
                myYCbCrfilter.InCb = new AForge.Range(Convert.ToSingle(Cb.Min), Convert.ToSingle(Cb.Max));
            }
            if (IntervalMinusOne.IncludesInterval(Cr))
            {
                myYCbCrfilter.InCr = new AForge.Range(Convert.ToSingle(Cr.Min), Convert.ToSingle(Cr.Max));
            }
            filteredImage = myYCbCrfilter.Apply(filteredImage);
            //////////////////////////////////////////////////////////////////////////
            LevelsLinear myRGBfilter = new LevelsLinear();

            if (Interval255.IncludesInterval(R))
            {
                myRGBfilter.InRed = new AForge.IntRange((int)(R.Min), (int)(R.Max));
            }
            if (Interval255.IncludesInterval(G))
            {
                myRGBfilter.InGreen = new AForge.IntRange((int)(G.Min), (int)(G.Max));
            }
            if (Interval255.IncludesInterval(B))
            {
                myRGBfilter.InBlue = new AForge.IntRange((int)(B.Min), (int)(B.Max));
            }
            filteredImage = myRGBfilter.Apply(filteredImage);

            DA.SetData(0, filteredImage);
        }
Example #5
0
        protected void ApplyFiltersTo(ref Bitmap b, ImageState s)
        {
            var imageRectF   = s.layout.GetRingAsRectF("image");
            var areaOfEffect = imageRectF == null ? new Rectangle(0, 0, b.Width, b.Height) : PolygonMath.ToRectangleShrinkRound(imageRectF.Value);

            //TODO: if the image is unrotated, use a rectangle to limit the effect to the desired area

            string str = null;
            int    i   = 0;

            //If radiusunits is specified, use that code path.
            double units = s.settings.Get <double>("a.radiusunits", 1000);

            //TODO: move blur/sharpen aliases to a compatibility shim, deprecate them

            i = GetRadius(s, "blur", "a.blur", units);
            if (i > 0)
            {
                new GaussianBlur(1.4, i).ApplyInPlace(b, areaOfEffect);
            }

            i = GetRadius(s, "sharpen", "a.sharpen", units);
            if (i > 0)
            {
                new GaussianSharpen(1.4, Math.Min(11, i)).ApplyInPlace(b, areaOfEffect);
            }

            i = GetRadius(s, "a.oilpainting", null, units);
            if (i > 0)
            {
                new OilPainting(i).ApplyInPlace(b, areaOfEffect);
            }

            if ("true".Equals(s.settings["a.removenoise"], StringComparison.OrdinalIgnoreCase))
            {
                new ConservativeSmoothing(3).ApplyInPlace(b, areaOfEffect);
            }
            else
            {
                i = GetRadius(s, "a.removenoise", null, units);
                if (i > 0)
                {
                    new ConservativeSmoothing(i).ApplyInPlace(b, areaOfEffect);
                }
            }



            //Sobel only supports 8bpp grayscale images.
            //true/false
            if ("true".Equals(s.settings["a.sobel"], StringComparison.OrdinalIgnoreCase))
            {
                Bitmap old = b;
                try{
                    b = Grayscale.CommonAlgorithms.Y.Apply(b);
                }finally{
                    if (old != s.sourceBitmap)
                    {
                        old.Dispose();
                    }
                }

                new SobelEdgeDetector().ApplyInPlace(b, areaOfEffect);

                str = s.settings["a.threshold"]; //radius
                if (!string.IsNullOrEmpty(str) && int.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i) && i > 0)
                {
                    new Threshold(i).ApplyInPlace(b, areaOfEffect);
                }
            }
            //Canny Edge Detector only supports 8bpp grayscale images.
            //true/false
            if ("true".Equals(s.settings["a.canny"], StringComparison.OrdinalIgnoreCase))
            {
                Bitmap old = b;
                try {
                    b = Grayscale.CommonAlgorithms.Y.Apply(b);
                } finally {
                    if (old != s.sourceBitmap)
                    {
                        old.Dispose();
                    }
                }
                new CannyEdgeDetector().ApplyInPlace(b, areaOfEffect);
            }

            //true/false - duplicate with SimpleFilters?
            if ("true".Equals(s.settings["a.sepia"], StringComparison.OrdinalIgnoreCase))
            {
                new Sepia().ApplyInPlace(b, areaOfEffect);
            }

            //true/false
            if ("true".Equals(s.settings["a.equalize"], StringComparison.OrdinalIgnoreCase))
            {
                new HistogramEqualization().ApplyInPlace(b, areaOfEffect);
            }

            //White balance adjustment
            var whiteAlg = s.settings.Get <HistogramThresholdAlgorithm>("a.balancewhite");
            var whiteVal = s.settings.Get <double>("a.balancethreshold");


            if (whiteAlg != null || whiteVal != null)
            {
                var bal = new AutoWhiteBalance(whiteAlg ?? HistogramThresholdAlgorithm.Area);
                if (whiteVal != null)
                {
                    bal.LowThreshold = bal.HighThreshold = whiteVal.Value / 100;
                }
                bal.ApplyInPlace(b, areaOfEffect);
            }

            str = s.settings["a.posterize"]; //number of colors to merge
            if (!string.IsNullOrEmpty(str) && int.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i) && i > 0)
            {
                SimplePosterization sp = new SimplePosterization();
                if (i < 1)
                {
                    i = 1;
                }
                if (i > 255)
                {
                    i = 255;
                }
                sp.PosterizationInterval = (byte)i;
                sp.ApplyInPlace(b, areaOfEffect);
            }

            //Pixelate doesn't support 32-bit images, only 24-bit
            //str = s.settings["a.pixelate"]; //number of colors to merge
            //if (!string.IsNullOrEmpty(str) && int.TryParse(str, out i)){
            //     if (i < 2) i = 2;
            //    if (i > 32) i = 32;
            //    new Pixelate(i).ApplyInPlace(s.destBitmap);
            //}


            float contrast   = s.settings.Get <float>("a.contrast", 0);
            float brightness = s.settings.Get <float>("a.brightness", 0);
            float saturation = s.settings.Get <float>("a.saturation", 0);

            if (contrast != 0 || brightness != 0 || saturation != 0)
            {
                HSLLinear adjust = new HSLLinear();
                AdjustContrastBrightnessSaturation(adjust, contrast, brightness, saturation, "true".Equals(s.settings["a.truncate"]));
                adjust.ApplyInPlace(b, areaOfEffect);
            }
            //TODO - add grayscale?

            //For adding fax-like thresholding, use BradleyLocalThresholding

            //For trimming solid-color whitespace, use Shrink
        }