示例#1
0
        /// <summary>
        /// Rotates the image 270 degrees clockwise at the centre point.
        /// </summary>
        /// <param name="target">The target image.</param>
        /// <param name="source">The source image.</param>
        private void Rotate270(ImageBase <T, TP> target, ImageBase <T, TP> source)
        {
            int           width  = source.Width;
            int           height = source.Height;
            Image <T, TP> temp   = new Image <T, TP>(height, width);

            using (IPixelAccessor <T, TP> sourcePixels = source.Lock())
                using (IPixelAccessor <T, TP> tempPixels = temp.Lock())
                {
                    Parallel.For(
                        0,
                        height,
                        this.ParallelOptions,
                        y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            int newX = height - y - 1;
                            newX     = height - newX - 1;
                            int newY = width - x - 1;
                            tempPixels[newX, newY] = sourcePixels[x, y];
                        }

                        this.OnRowProcessed();
                    });
                }

            target.SetPixels(height, width, temp.Pixels);
        }
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            if (source.Bounds == target.Bounds)
            {
                target.SetPixels(target.Width, target.Height, source.Pixels);
                return;
            }

            int targetY = this.cropRectangle.Y;
            int startX = targetRectangle.X;
            int targetX = this.cropRectangle.X;
            int endX = this.cropRectangle.Width;
            int maxX = endX - 1;
            int maxY = this.cropRectangle.Bottom - 1;

            Parallel.For(
            startY,
            endY,
            y =>
            {
                for (int x = startX; x < endX; x++)
                {
                    int offsetY = y + targetY;
                    offsetY = offsetY.Clamp(0, maxY);

                    int offsetX = x + targetX;
                    offsetX = offsetX.Clamp(0, maxX);

                    target[x, y] = source[offsetX, offsetY];
                }
                this.OnRowProcessed();
            });
        }
        public virtual void Sample(ImageBase source, ImageBase target, int width, int height)
        {
            byte[] pixels = new byte[width * height * 4];

            if (Parallelism > 1)
            {
                int partitionCount = Parallelism;

                Task[] tasks = new Task[partitionCount];

                for (int p = 0; p < partitionCount; p++)
                {
                    int current = p;
                    tasks[p] = Task.Run(() =>
                    {
                        int batchSize = height / partitionCount;
                        int yBegin    = current * batchSize;
                        int yEnd      = (current == partitionCount - 1 ? height : yBegin + batchSize);

                        Sample(source, width, height, yBegin, yEnd, pixels);
                    });
                }

                Task.WaitAll(tasks);
            }
            else
            {
                Sample(source, width, height, 0, height, pixels);
            }

            target.SetPixels(width, height, pixels);
        }
示例#4
0
        /// <summary>
        /// Creates a new target to contain the results of the matrix transform.
        /// </summary>
        /// <param name="target">Target image to apply the process to.</param>
        /// <param name="sourceRectangle">The source rectangle.</param>
        /// <param name="processMatrix">The processing matrix.</param>
        protected static void CreateNewTarget(ImageBase <TColor, TPacked> target, Rectangle sourceRectangle, Matrix3x2 processMatrix)
        {
            Matrix3x2 sizeMatrix;

            if (Matrix3x2.Invert(processMatrix, out sizeMatrix))
            {
                Rectangle rectangle = ImageMaths.GetBoundingRectangle(sourceRectangle, sizeMatrix);
                target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]);
            }
        }
        public void Resize(ImageBase source, ImageBase target, int width, int height)
        {
            byte[] newPixels = new byte[width * height * 4];

            double xFactor = (double)source.PixelWidth / width;
            double yFactor = (double)source.PixelHeight / height;

            int dstOffsetLine = 0;
            int dstOffset = 0;

            int srcOffsetLine = 0;
            int srcOffset = 0;

            byte[] sourcePixels = source.Pixels;

            for (int y = 0; y < height; y++)
            {
                dstOffsetLine = 4 * width * y;

                // Calculate the line offset at the source image, where the pixels should be get from.
                srcOffsetLine = 4 * source.PixelWidth * (int)(y * yFactor);

                for (int x = 0; x < width; x++)
                {
                    dstOffset = dstOffsetLine + 4 * x;
                    srcOffset = srcOffsetLine + 4 * (int)(x * xFactor);

                    newPixels[dstOffset + 0] = sourcePixels[srcOffset + 0];
                    newPixels[dstOffset + 1] = sourcePixels[srcOffset + 1];
                    newPixels[dstOffset + 2] = sourcePixels[srcOffset + 2];
                    newPixels[dstOffset + 3] = sourcePixels[srcOffset + 3];
                }
            }

            target.SetPixels(width, height, newPixels);
        }
示例#6
0
 private void ConvertFromYCbCr(int imageWidth, int imageHeight, ImageBase image)
 {
     int scale = comp[0].h/comp[1].h;
     Color2[] pixels = new Color2[imageWidth*imageHeight];
     Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{
         int yo = ycbcrImage.get_row_y_offset(y);
         int co = ycbcrImage.get_row_c_offset(y);
         for (int x = 0; x < imageWidth; x++){
             byte yy = ycbcrImage.pix_y[yo + x];
             byte cb = ycbcrImage.pix_cb[co + (x/scale)];
             byte cr = ycbcrImage.pix_cr[co + (x/scale)];
             int index = y*imageWidth + x;
             Color2 color = new YCbCr2(yy, cb, cr);
             Color2 packed = Color2.FromArgb(color.A, color.R, color.G, color.B);
             pixels[index] = packed;
         }
     });
     image.SetPixels(imageWidth, imageHeight, pixels);
     AssignResolution(image);
 }
示例#7
0
 private void ConvertFromRgb(int imageWidth, int imageHeight, ImageBase image)
 {
     int scale = comp[0].h/comp[1].h;
     Color2[] pixels = new Color2[imageWidth*imageHeight];
     Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{
         int yo = ycbcrImage.get_row_y_offset(y);
         int co = ycbcrImage.get_row_c_offset(y);
         for (int x = 0; x < imageWidth; x++){
             byte red = ycbcrImage.pix_y[yo + x];
             byte green = ycbcrImage.pix_cb[co + (x/scale)];
             byte blue = ycbcrImage.pix_cr[co + (x/scale)];
             int index = (y*imageWidth) + x;
             Color2 packed = Color2.FromArgb(red, green, blue);
             pixels[index] = packed;
         }
     });
     image.SetPixels(imageWidth, imageHeight, pixels);
     AssignResolution(image);
 }
示例#8
0
 private void ConvertFromGrayScale(int imageWidth, int imageHeight, ImageBase image)
 {
     Color2[] pixels = new Color2[imageWidth*imageHeight];
     Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{
         int yoff = grayImage.GetRowOffset(y);
         for (int x = 0; x < imageWidth; x++){
             int offset = (y*imageWidth) + x;
             byte rgb = grayImage.pixels[yoff + x];
             Color2 packed = Color2.FromArgb(rgb, rgb, rgb);
             pixels[offset] = packed;
         }
     });
     image.SetPixels(imageWidth, imageHeight, pixels);
     AssignResolution(image);
 }
        /// <inheritdoc/>
        protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
        {
            ImageBase temp = new Image(source.Width, source.Height);

            // Detect the edges.
            new Sobel().Apply(temp, source, sourceRectangle);

            // Apply threshold binarization filter.
            new Threshold(.5f).Apply(temp, temp, sourceRectangle);

            // Search for the first white pixels
            Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0);

            // Reset the target pixel to the correct size.
            target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]);
            this.cropRectangle = rectangle;
        }
        public void Resize(ImageBase source, ImageBase target, int width, int height)
        {
            byte[] newPixels = new byte[width * height * 4];

            byte[] sourcePixels = source.Pixels;

            var GetColor = new Func<double, double, int, byte>((x, y, offset) => sourcePixels[(int)((y * source.PixelWidth + x) * 4 + offset)]);

            double factorX = (double)source.PixelWidth  / width;
            double factorY = (double)source.PixelHeight / height;

            double fractionX, oneMinusX, l, r;
            double fractionY, oneMinusY, t, b;

            byte c1, c2, c3, c4, b1, b2;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int dstOffset = (y * width + x) * 4;

                    l = (int)Math.Floor(x * factorX);
                    t = (int)Math.Floor(y * factorY);

                    r = l + 1;
                    b = t + 1;

                    if (r >= source.PixelWidth)
                    {
                        r = l;
                    }

                    if (b >= source.PixelHeight)
                    {
                        b = t;
                    }

                    fractionX = x * factorX - l;
                    fractionY = y * factorY - t;

                    oneMinusX = 1.0 - fractionX;
                    oneMinusY = 1.0 - fractionY;

                    var function = new Func<int, byte>(offset => 
                        {
                            c1 = GetColor(l, t, offset);
                            c2 = GetColor(r, t, offset);
                            c3 = GetColor(l, b, offset);
                            c4 = GetColor(r, b, offset);

                            b1 = (byte)(oneMinusX * c1 + fractionX * c2);
                            b2 = (byte)(oneMinusX * c3 + fractionX * c4);

                            return (byte)(oneMinusY * b1 + fractionY * b2);
                        });

                    newPixels[dstOffset + 0] = function(0);
                    newPixels[dstOffset + 1] = function(1);
                    newPixels[dstOffset + 2] = function(2);
                    newPixels[dstOffset + 3] = 255;
                }
            }

            target.SetPixels(width, height, newPixels);
        }
示例#11
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TColor, TPacked> source, Rectangle sourceRectangle)
        {
            float[][] kernelX      = this.KernelXY;
            int       kernelLength = kernelX.GetLength(0);
            int       radius       = kernelLength >> 1;

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int maxY   = endY - 1;
            int maxX   = endX - 1;

            TColor[] target = new TColor[source.Width * source.Height];
            using (PixelAccessor <TColor, TPacked> sourcePixels = source.Lock())
                using (PixelAccessor <TColor, TPacked> targetPixels = target.Lock <TColor, TPacked>(source.Width, source.Height))
                {
                    Parallel.For(
                        startY,
                        endY,
                        this.ParallelOptions,
                        y =>
                    {
                        for (int x = startX; x < endX; x++)
                        {
                            float rX = 0;
                            float gX = 0;
                            float bX = 0;

                            // Apply each matrix multiplier to the color components for each pixel.
                            for (int fy = 0; fy < kernelLength; fy++)
                            {
                                int fyr     = fy - radius;
                                int offsetY = y + fyr;

                                offsetY = offsetY.Clamp(0, maxY);

                                for (int fx = 0; fx < kernelLength; fx++)
                                {
                                    int fxr     = fx - radius;
                                    int offsetX = x + fxr;

                                    offsetX = offsetX.Clamp(0, maxX);

                                    Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
                                    float r = currentColor.X;
                                    float g = currentColor.Y;
                                    float b = currentColor.Z;

                                    rX += kernelX[fy][fx] * r;
                                    gX += kernelX[fy][fx] * g;
                                    bX += kernelX[fy][fx] * b;
                                }
                            }

                            float red   = rX;
                            float green = gX;
                            float blue  = bX;

                            TColor packed = default(TColor);
                            packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W));
                            targetPixels[x, y] = packed;
                        }
                    });
                }

            source.SetPixels(source.Width, source.Height, target);
        }