Beispiel #1
0
        /// <summary>
        /// The position in the original string where the first character of the captured substring was found.
        /// </summary>
        /// <param name="queryString">
        /// The query string to search.
        /// </param>
        /// <returns>
        /// The zero-based starting position in the original string where the captured substring was found.
        /// </returns>
        public int MatchRegexIndex(string queryString)
        {
            this.SortOrder = int.MaxValue;
            Match match = this.RegexPattern.Match(queryString);

            if (match.Success)
            {
                this.SortOrder = match.Index;

                int    maxSize;
                double maxSigma;
                int    maxThreshold;

                int.TryParse(this.Processor.Settings["MaxSize"], NumberStyles.Any, CultureInfo.InvariantCulture, out maxSize);
                double.TryParse(this.Processor.Settings["MaxSigma"], NumberStyles.Any, CultureInfo.InvariantCulture, out maxSigma);
                int.TryParse(this.Processor.Settings["MaxThreshold"], NumberStyles.Any, CultureInfo.InvariantCulture, out maxThreshold);

                NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
                int size = QueryParamParser.Instance.ParseValue <int>(queryCollection["sharpen"]);

                // Fall back to default sigma.
                double sigma = queryCollection["sigma"] != null?QueryParamParser.Instance.ParseValue <double>(queryCollection["sigma"]) : 1.4d;

                int threshold = QueryParamParser.Instance.ParseValue <int>(queryCollection["threshold"]);

                // Normalize and set the variables.
                size      = ImageMaths.Clamp(size, 0, maxSize);
                sigma     = ImageMaths.Clamp(sigma, 0, maxSigma);
                threshold = ImageMaths.Clamp(threshold, 0, maxThreshold);

                this.Processor.DynamicParameter = new GaussianLayer(size, sigma, threshold);
            }

            return(this.SortOrder);
        }
Beispiel #2
0
            public void ThenShouldUseMaxValueGivenValueGreaterThanMax(int maxValue, int value)
            {
                // Arrange //Act
                var result = ImageMaths.Clamp(value, int.MinValue, maxValue);

                // Assert
                Assert.That(result, Is.EqualTo(maxValue));
            }
        /// <summary>
        /// Changes the opacity of the current image.
        /// </summary>
        /// <param name="percentage">
        /// The percentage by which to alter the images opacity.
        /// Any integer between 0 and 100.
        /// </param>
        /// <returns>
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
        /// </returns>
        public ImageFactory Alpha(int percentage)
        {
            if (this.ShouldProcess)
            {
                // Sanitize the input.
                percentage = ImageMaths.Clamp(percentage, 0, 100);

                Alpha alpha = new Alpha {
                    DynamicParameter = percentage
                };
                this.CurrentImageFormat.ApplyProcessor(alpha.ProcessImage, this);
            }

            return(this);
        }
        /// <summary>
        /// The position in the original string where the first character of the captured substring was found.
        /// </summary>
        /// <param name="queryString">The query string to search.</param>
        /// <returns>
        /// The zero-based starting position in the original string where the captured substring was found.
        /// </returns>
        public int MatchRegexIndex(string queryString)
        {
            this.SortOrder = int.MaxValue;
            Match match = this.RegexPattern.Match(queryString);

            if (match.Success)
            {
                this.SortOrder = match.Index;
                NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
                int percentage = QueryParamParser.Instance.ParseValue <int>(queryCollection["brightness"]);
                percentage = ImageMaths.Clamp(percentage, -100, 100);
                this.Processor.DynamicParameter = percentage;
            }

            return(this.SortOrder);
        }
        /// <summary>
        /// The position in the original string where the first character of the captured substring was found.
        /// </summary>
        /// <param name="queryString">The query string to search.</param>
        /// <returns>
        /// The zero-based starting position in the original string where the captured substring was found.
        /// </returns>
        public int MatchRegexIndex(string queryString)
        {
            this.SortOrder = int.MaxValue;
            Match match = this.RegexPattern.Match(queryString);

            if (match.Success)
            {
                this.SortOrder = match.Index;
                NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
                Color[]             colors          = QueryParamParser.Instance.ParseValue <Color[]>(queryCollection["replace"]);
                int fuzziness = QueryParamParser.Instance.ParseValue <int>(queryCollection["fuzziness"]);

                fuzziness = ImageMaths.Clamp(fuzziness, 0, 128);
                this.Processor.DynamicParameter = new Tuple <Color, Color, int>(colors[0], colors[1], fuzziness);
            }

            return(this.SortOrder);
        }
Beispiel #6
0
        /// <summary>
        /// The position in the original string where the first character of the captured substring was found.
        /// </summary>
        /// <param name="queryString">The query string to search.</param>
        /// <returns>
        /// The zero-based starting position in the original string where the captured substring was found.
        /// </returns>
        public int MatchRegexIndex(string queryString)
        {
            this.SortOrder = int.MaxValue;
            Match match = this.RegexPattern.Match(queryString);

            if (match.Success)
            {
                this.SortOrder = match.Index;
                NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);

                int  degrees = QueryParamParser.Instance.ParseValue <int>(queryCollection["hue"]);
                bool rotate  = QueryParamParser.Instance.ParseValue <bool>(queryCollection["hue.rotate"]);
                degrees = ImageMaths.Clamp(degrees, 0, 360);

                this.Processor.DynamicParameter = new Tuple <int, bool>(degrees, rotate);
            }

            return(this.SortOrder);
        }
Beispiel #7
0
        /// <summary>
        /// Sets the resolution of the image.
        /// <remarks>
        /// This method sets both the bitmap data and EXIF resolution if available.
        /// </remarks>
        /// </summary>
        /// <param name="horizontal">The horizontal resolution.</param>
        /// <param name="vertical">The vertical resolution.</param>
        /// <param name="unit">
        /// The unit of measure for the horizontal resolution and the vertical resolution.
        /// Defaults to inches
        /// </param>
        /// <returns>
        /// The <see cref="ImageFactory"/>.
        /// </returns>
        public ImageFactory Resolution(int horizontal, int vertical, PropertyTagResolutionUnit unit = PropertyTagResolutionUnit.Inch)
        {
            if (this.ShouldProcess)
            {
                // Sanitize the input.
                horizontal = ImageMaths.Clamp(horizontal, 0, int.MaxValue);
                vertical   = ImageMaths.Clamp(vertical, 0, int.MaxValue);

                Tuple <int, int, PropertyTagResolutionUnit> resolution =
                    new Tuple <int, int, PropertyTagResolutionUnit>(horizontal, vertical, unit);

                Resolution dpi = new Resolution {
                    DynamicParameter = resolution
                };
                this.CurrentImageFormat.ApplyProcessor(dpi.ProcessImage, this);
            }

            return(this);
        }
 /// <summary>
 /// Converts an <see cref="T:System.Double"/> value into a valid <see cref="T:System.Byte"/>.
 /// <remarks>
 /// If the value given is less than 0 or greater than 255, the value will be constrained into
 /// those restricted ranges.
 /// </remarks>
 /// </summary>
 /// <param name="value">
 /// The <see cref="T:System.Double"/> to convert.
 /// </param>
 /// <returns>
 /// The <see cref="T:System.Byte"/>.
 /// </returns>
 public static byte ToByte(this double value)
 {
     return(Convert.ToByte(ImageMaths.Clamp(value, 0, 255)));
 }
Beispiel #9
0
 /// <summary>
 /// Checks the range of the given value to ensure that it remains within the acceptable boundaries.
 /// </summary>
 /// <param name="value">
 /// The value to check.
 /// </param>
 /// <returns>
 /// The sanitized <see cref="float"/>.
 /// </returns>
 private static float Clamp(float value)
 {
     return(ImageMaths.Clamp(value, 0, 100));
 }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="YCbCrColor"/> struct.
 /// </summary>
 /// <param name="y">The y luminance component.</param>
 /// <param name="cb">The u chroma component.</param>
 /// <param name="cr">The v chroma component.</param>
 private YCbCrColor(float y, float cb, float cr)
 {
     _y  = ImageMaths.Clamp(y, 0, 255);
     _cb = ImageMaths.Clamp(cb, 0, 255);
     _cr = ImageMaths.Clamp(cr, 0, 255);
 }
Beispiel #11
0
 /// <summary>
 /// Converts an <see cref="T:System.Int32"/> value into a valid <see cref="T:System.Byte"/>.
 /// <remarks>
 /// If the value given is less than 0 or greater than 255, the value will be constrained into
 /// those restricted ranges.
 /// </remarks>
 /// </summary>
 /// <param name="value">
 /// The <see cref="T:System.Int32"/> to convert.
 /// </param>
 /// <returns>
 /// The <see cref="T:System.Byte"/>.
 /// </returns>
 public static byte ToByte(this int value) => Convert.ToByte(ImageMaths.Clamp(value, 0, 255));
Beispiel #12
0
 /// <summary>
 /// Checks the range of the given value to ensure that it remains within the acceptable boundaries.
 /// </summary>
 /// <param name="value">
 /// The value to check.
 /// </param>
 /// <returns>
 /// The sanitized <see cref="float"/>.
 /// </returns>
 private static float Clamp(float value) => ImageMaths.Clamp(value, 0, 100);
Beispiel #13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="YCbCrColor"/> struct.
 /// </summary>
 /// <param name="y">The y luminance component.</param>
 /// <param name="cb">The u chroma component.</param>
 /// <param name="cr">The v chroma component.</param>
 private YCbCrColor(float y, float cb, float cr)
 {
     this.y  = ImageMaths.Clamp(y, 0, 255);
     this.cb = ImageMaths.Clamp(cb, 0, 255);
     this.cr = ImageMaths.Clamp(cr, 0, 255);
 }
Beispiel #14
0
        /// <summary>
        /// Applies the halftone filter.
        /// </summary>
        /// <param name="source">
        /// The <see cref="Bitmap"/> to apply the filter to.
        /// </param>
        /// <returns>
        /// The <see cref="Bitmap"/> with the filter applied.
        /// </returns>
        public Bitmap ApplyFilter(Bitmap source)
        {
            // TODO: Make this class implement an interface?
            Bitmap cyan     = null;
            Bitmap magenta  = null;
            Bitmap yellow   = null;
            Bitmap keyline  = null;
            Bitmap newImage = null;

            try
            {
                int width  = source.Width;
                int height = source.Height;

                // Calculate min and max widths/heights.
                Rectangle rotatedBounds = this.GetBoundingRectangle(width, height);
                int       minY          = -(rotatedBounds.Height + height);
                int       maxY          = rotatedBounds.Height + height;
                int       minX          = -(rotatedBounds.Width + width);
                int       maxX          = rotatedBounds.Width + width;
                Point     center        = Point.Empty;

                // Yellow oversaturates the output.
                const float YellowMultiplier = 4;
                float       multiplier       = YellowMultiplier * (float)Math.Sqrt(2);

                float max = this.distance;

                // Bump up the keyline max so that black looks black.
                float keylineMax = max + ((float)Math.Sqrt(2) * 1.44f);

                // Color sampled process colours from Wikipedia pages.
                // Keyline brush is declared separately.
                Brush cyanBrush    = new SolidBrush(Color.FromArgb(0, 183, 235));
                Brush magentaBrush = new SolidBrush(Color.FromArgb(255, 0, 144));
                Brush yellowBrush  = new SolidBrush(Color.FromArgb(255, 239, 0));

                // Create our images.
                cyan     = new Bitmap(width, height);
                magenta  = new Bitmap(width, height);
                yellow   = new Bitmap(width, height);
                keyline  = new Bitmap(width, height);
                newImage = new Bitmap(width, height);

                // Ensure the correct resolution is set.
                cyan.SetResolution(source.HorizontalResolution, source.VerticalResolution);
                magenta.SetResolution(source.HorizontalResolution, source.VerticalResolution);
                yellow.SetResolution(source.HorizontalResolution, source.VerticalResolution);
                keyline.SetResolution(source.HorizontalResolution, source.VerticalResolution);
                newImage.SetResolution(source.HorizontalResolution, source.VerticalResolution);

                // Check bounds against this.
                Rectangle rectangle = new Rectangle(0, 0, width, height);

                using (Graphics graphicsCyan = Graphics.FromImage(cyan))
                    using (Graphics graphicsMagenta = Graphics.FromImage(magenta))
                        using (Graphics graphicsYellow = Graphics.FromImage(yellow))
                            using (Graphics graphicsKeyline = Graphics.FromImage(keyline))
                            {
                                // Set the quality properties.
                                graphicsCyan.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                                graphicsMagenta.PixelOffsetMode = PixelOffsetMode.HighQuality;
                                graphicsYellow.PixelOffsetMode  = PixelOffsetMode.HighQuality;
                                graphicsKeyline.PixelOffsetMode = PixelOffsetMode.HighQuality;

                                // Set up the canvas.
                                graphicsCyan.Clear(Color.Transparent);
                                graphicsMagenta.Clear(Color.Transparent);
                                graphicsYellow.Clear(Color.Transparent);
                                graphicsKeyline.Clear(Color.Transparent);

                                int d = this.distance;

                                // This is too slow. The graphics object can't be called within a parallel
                                // loop so we have to do it old school. :(
                                using (FastBitmap sourceBitmap = new FastBitmap(source))
                                {
                                    for (int y = minY; y < maxY; y += d)
                                    {
                                        for (int x = minX; x < maxX; x += d)
                                        {
                                            Color     color;
                                            CmykColor cmykColor;
                                            float     brushWidth;
                                            int       offsetX = x - (d >> 1);
                                            int       offsetY = y - (d >> 1);

                                            // Cyan
                                            Point rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.cyanAngle, center);
                                            int   angledX      = rotatedPoint.X;
                                            int   angledY      = rotatedPoint.Y;
                                            if (rectangle.Contains(new Point(angledX, angledY)))
                                            {
                                                color      = sourceBitmap.GetPixel(angledX, angledY);
                                                cmykColor  = color;
                                                brushWidth = ImageMaths.Clamp(d * (cmykColor.C / 255f) * multiplier, 0, max);
                                                graphicsCyan.FillEllipse(cyanBrush, angledX, angledY, brushWidth, brushWidth);
                                            }

                                            // Magenta
                                            rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.magentaAngle, center);
                                            angledX      = rotatedPoint.X;
                                            angledY      = rotatedPoint.Y;
                                            if (rectangle.Contains(new Point(angledX, angledY)))
                                            {
                                                color      = sourceBitmap.GetPixel(angledX, angledY);
                                                cmykColor  = color;
                                                brushWidth = ImageMaths.Clamp(d * (cmykColor.M / 255f) * multiplier, 0, max);
                                                graphicsMagenta.FillEllipse(magentaBrush, angledX, angledY, brushWidth, brushWidth);
                                            }

                                            // Yellow
                                            rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.yellowAngle, center);
                                            angledX      = rotatedPoint.X;
                                            angledY      = rotatedPoint.Y;
                                            if (rectangle.Contains(new Point(angledX, angledY)))
                                            {
                                                color      = sourceBitmap.GetPixel(angledX, angledY);
                                                cmykColor  = color;
                                                brushWidth = ImageMaths.Clamp(d * (cmykColor.Y / 255f) * YellowMultiplier, 0, max);
                                                graphicsYellow.FillEllipse(yellowBrush, angledX, angledY, brushWidth, brushWidth);
                                            }

                                            // Keyline
                                            rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.keylineAngle, center);
                                            angledX      = rotatedPoint.X;
                                            angledY      = rotatedPoint.Y;
                                            if (rectangle.Contains(new Point(angledX, angledY)))
                                            {
                                                color      = sourceBitmap.GetPixel(angledX, angledY);
                                                cmykColor  = color;
                                                brushWidth = ImageMaths.Clamp(d * (cmykColor.K / 255f) * multiplier, 0, keylineMax);

                                                // Just using black is too dark.
                                                Brush keylineBrush = new SolidBrush(CmykColor.FromCmykColor(0, 0, 0, cmykColor.K));
                                                graphicsKeyline.FillEllipse(keylineBrush, angledX, angledY, brushWidth, brushWidth);
                                            }
                                        }
                                    }
                                }

                                // Set our white background.
                                using (Graphics graphics = Graphics.FromImage(newImage))
                                {
                                    graphics.Clear(Color.White);
                                }

                                // Blend the colors now to mimic adaptive blending.
                                using (FastBitmap cyanBitmap = new FastBitmap(cyan))
                                    using (FastBitmap magentaBitmap = new FastBitmap(magenta))
                                        using (FastBitmap yellowBitmap = new FastBitmap(yellow))
                                            using (FastBitmap keylineBitmap = new FastBitmap(keyline))
                                                using (FastBitmap destinationBitmap = new FastBitmap(newImage))
                                                {
                                                    Parallel.For(
                                                        0,
                                                        height,
                                                        y =>
                                                    {
                                                        for (int x = 0; x < width; x++)
                                                        {
                                                            // ReSharper disable AccessToDisposedClosure
                                                            Color cyanPixel    = cyanBitmap.GetPixel(x, y);
                                                            Color magentaPixel = magentaBitmap.GetPixel(x, y);
                                                            Color yellowPixel  = yellowBitmap.GetPixel(x, y);
                                                            Color keylinePixel = keylineBitmap.GetPixel(x, y);

                                                            CmykColor blended = cyanPixel.AddAsCmykColor(magentaPixel, yellowPixel, keylinePixel);
                                                            if (rectangle.Contains(new Point(x, y)))
                                                            {
                                                                destinationBitmap.SetPixel(x, y, blended);
                                                            }
                                                            // ReSharper restore AccessToDisposedClosure
                                                        }
                                                    });
                                                }
                            }

                cyan.Dispose();
                magenta.Dispose();
                yellow.Dispose();
                keyline.Dispose();
                source.Dispose();
                source = newImage;
            }
            catch
            {
                if (cyan != null)
                {
                    cyan.Dispose();
                }

                if (magenta != null)
                {
                    magenta.Dispose();
                }

                if (yellow != null)
                {
                    yellow.Dispose();
                }

                if (keyline != null)
                {
                    keyline.Dispose();
                }

                if (newImage != null)
                {
                    newImage.Dispose();
                }
            }

            return(source);
        }
Beispiel #15
0
 /// <summary>
 /// Converts an <see cref="T:System.Float"/> value into a valid <see cref="T:System.Byte"/>.
 /// <remarks>
 /// If the value given is less than 0 or greater than 255, the value will be constrained into
 /// those restricted ranges.
 /// </remarks>
 /// </summary>
 /// <param name="value">
 /// The <see cref="T:System.Float"/> to convert.
 /// </param>
 /// <returns>
 /// The <see cref="T:System.Byte"/>.
 /// </returns>
 public static byte ToByte(this float value) => Convert.ToByte(ImageMaths.Clamp(value, byte.MinValue, byte.MaxValue));