示例#1
0
        public void Init(Rgba32[,] avgsMaster, Size outputSize,
                         List <Tile> tileImageList, Size tileSize, int tX, int tY)
        {
            _avgsMaster    = avgsMaster;
            _tileImageList = tileImageList;
            _tileSize      = tileSize;
            _tX            = tX;
            _tY            = tY;

            _outputImage = new Image <Rgba32>(tileSize.Width * _tX, tileSize.Height * _tY);
        }
示例#2
0
        /// <summary>
        /// Converts an array's RGB values into int lightness values
        /// </summary>
        /// <param name="pixelBuffer"></param>
        private static void ConvertRGBAToLightnessValues(Rgba32[,] pixelBuffer, Image <Rgba32> imageInput)
        {
            pixelLightnessBuffer = new int[imageInput.Width, imageInput.Height];

            for (int y = 0; y < imageInput.Height; y++)
            {
                for (int x = 0; x < imageInput.Width; x++)
                {
                    pixelLightnessBuffer[x, y] = (pixelBuffer[x, y].R + pixelBuffer[x, y].G + pixelBuffer[x, y].B) / 3;
                }
            }
        }
示例#3
0
        // TODO: Load Pixel Data
        public static Image <Rgba32> ToBitmap(Rgba32[,] colorArray)
        {
            var bitmap = new Image <Rgba32>(colorArray.GetLength(0), colorArray.GetLength(1));

            for (var x = 0; x < bitmap.Width; x++)
            {
                for (var y = 0; y < bitmap.Height; y++)
                {
                    bitmap[x, y] = colorArray[x, y];
                }
            }
            return(bitmap);
        }
示例#4
0
        private static bool ProcessImage(string filePath, string newPath, Rgba32[,] colors, ref int colorsColumnIndex, ref int colorsRowIndex)
        {
            Console.WriteLine($"Processing file: {filePath}");

            var bmp = Image.Load <Rgba32>(filePath);

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    var pixel    = bmp[x, y];
                    var lutPixel = new Rgba32(pixel.R, pixel.G, pixel.B);

                    // Find existing color in LUT buffer
                    GetColorIndexes(colors, lutPixel, out int foundColumn, out int foundRow);

                    // Color does not exist in LUT buffer, add it
                    if (foundColumn < 0 || foundRow < 0)
                    {
                        foundColumn = colorsColumnIndex;
                        foundRow    = colorsRowIndex;

                        colors[foundColumn, foundRow] = lutPixel;

                        // Increment index, wrapping onto next line if needed (2D LUT will be created)
                        colorsColumnIndex++;
                        if (colorsColumnIndex >= LUT_WIDTH)
                        {
                            colorsColumnIndex = 0;
                            colorsRowIndex++;
                        }
                    }

                    if (colorsRowIndex >= LUT_HEIGHT)
                    {
                        Console.WriteLine($"ERROR: More than {LUT_WIDTH * LUT_HEIGHT} colors found!");
                        return(false);
                    }

                    // Encode LUT UV coordinates for pixel into image
                    bmp[x, y] = new Rgba32((float)foundColumn / LUT_WIDTH, (float)foundRow / LUT_HEIGHT, 0, pixel.A);
                }
            }

            bmp.Save(newPath);
            bmp.Dispose();
            Console.WriteLine($"Saved {newPath}");

            return(true);
        }
示例#5
0
        /// <summary>
        /// Create a 2D array of pixel RGBA32 values for the given image input
        /// </summary>
        private static void MapPixelsToArray(Image <Rgba32> imageInput)
        {
            pixelBuffer = new Rgba32[imageInput.Width, imageInput.Height];


            for (int yHeight = 0; yHeight < imageInput.Height; yHeight++)
            {
                Span <Rgba32> pixelRowSpan = imageInput.GetPixelRowSpan(yHeight);
                for (int xWidth = 0; xWidth < imageInput.Width; xWidth++)
                {
                    // get pixel data as a tuple (no need for a 3D array as tuple is self contained)
                    pixelBuffer[xWidth, yHeight] = pixelRowSpan[xWidth];
                    //  Console.WriteLine($"Value of pixel Y {yHeight}, X {xWidth} is {pixelBuffer[xWidth, yHeight]}");
                }
            }
        }
示例#6
0
        private void Test(string name, Rgba32 background, IBrush <Rgba32> brush, Rgba32[,] expectedPattern)
        {
            string path = this.CreateOutputDirectory("Fill", "PatternBrush");

            using (Image image = new Image(20, 20))
            {
                image
                .Fill(background)
                .Fill(brush);

                using (FileStream output = File.OpenWrite($"{path}/{name}.png"))
                {
                    image.Save(output);
                }

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    // lets pick random spots to start checking
                    Random r = new Random();
                    Fast2DArray <Rgba32> expectedPatternFast = new Fast2DArray <Rgba32>(expectedPattern);
                    int xStride = expectedPatternFast.Width;
                    int yStride = expectedPatternFast.Height;
                    int offsetX = r.Next(image.Width / xStride) * xStride;
                    int offsetY = r.Next(image.Height / yStride) * yStride;
                    for (int x = 0; x < xStride; x++)
                    {
                        for (int y = 0; y < yStride; y++)
                        {
                            int    actualX  = x + offsetX;
                            int    actualY  = y + offsetY;
                            Rgba32 expected = expectedPatternFast[y, x]; // inverted pattern
                            Rgba32 actual   = sourcePixels[actualX, actualY];
                            if (expected != actual)
                            {
                                Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
                            }
                        }
                    }
                }
                using (FileStream output = File.OpenWrite($"{path}/{name}x4.png"))
                {
                    image.Resize(80, 80).Save(output);
                }
            }
        }
示例#7
0
        private static void SaveLUT(string lutPath, Rgba32[,] colors, int lastColumnIndex, int lastRowIndex)
        {
            // Only creat 1D LUT if we can, otherwise create a 2D LUT
            Image <Rgba32> lut;

            if (lastRowIndex <= 0)
            {
                lut = new Image <Rgba32>(LUT_WIDTH, 1);
                for (int i = 0; i < LUT_WIDTH; i++)
                {
                    // Fill LUT with color palette, using black for extra pixels
                    lut[i, 0] = i <= lastColumnIndex ? colors[i, 0] : Rgba32.Black;
                }
            }
            else
            {
                lut = new Image <Rgba32>(LUT_WIDTH, LUT_HEIGHT);
                for (int y = 0; y < LUT_WIDTH; y++)
                {
                    for (int x = 0; x < LUT_HEIGHT; x++)
                    {
                        // Fill LUT with color palette, using black for extra pixels
                        Rgba32 color;
                        if (x > lastRowIndex || (x == lastRowIndex && y > lastColumnIndex))
                        {
                            color = Rgba32.Black;
                        }
                        else
                        {
                            color = colors[y, x];
                        }

                        lut[y, x] = color;
                    }
                }
            }

            lut.Save(lutPath);
            lut.Dispose();
            Console.WriteLine($"Saved {lutPath}");
        }
示例#8
0
        private static void GetColorIndexes(Rgba32[,] colors, Rgba32 color, out int columnIndex, out int rowIndex)
        {
            // Find color in buffer
            for (int y = 0; y < colors.GetLength(0); y++)
            {
                for (int x = 0; x < colors.GetLength(1); x++)
                {
                    if (colors[y, x] == color)
                    {
                        columnIndex = y;
                        rowIndex    = x;
                        return;
                    }
                }
            }

            // Color was not found
            columnIndex = -1;
            rowIndex    = -1;
            return;
        }
示例#9
0
    public void Verify_DispatchAsPixelShader(Device device)
    {
        using ReadWriteTexture2D <Rgba32, float4> texture = device.Get().AllocateReadWriteTexture2D <Rgba32, float4>(256, 256);

        device.Get().ForEach <DispatchPixelShader, float4>(texture);

        Rgba32[,] data = texture.ToArray();

        for (int y = 0; y < texture.Height; y++)
        {
            for (int x = 0; x < texture.Width; x++)
            {
                Rgba32 pixel = data[y, x];

                Assert.AreEqual((float)pixel.R / 255, (float)x / texture.Width, 0.1f);
                Assert.AreEqual((float)pixel.G / 255, (float)y / texture.Height, 0.1f);
                Assert.AreEqual(pixel.B, 255);
                Assert.AreEqual(pixel.A, 255);
            }
        }
    }
示例#10
0
        private void Test(string name, Rgba32 background, IBrush <Rgba32> brush, Rgba32[,] expectedPattern)
        {
            string path = TestEnvironment.CreateOutputDirectory("Fill", "PatternBrush");

            using (var image = new Image <Rgba32>(20, 20))
            {
                image.Mutate(x => x
                             .Fill(background)
                             .Fill(brush));

                image.Save($"{path}/{name}.png");

                using (PixelAccessor <Rgba32> sourcePixels = image.Lock())
                {
                    // lets pick random spots to start checking
                    var r = new Random();
                    var expectedPatternFast = new DenseMatrix <Rgba32>(expectedPattern);
                    int xStride             = expectedPatternFast.Columns;
                    int yStride             = expectedPatternFast.Rows;
                    int offsetX             = r.Next(image.Width / xStride) * xStride;
                    int offsetY             = r.Next(image.Height / yStride) * yStride;
                    for (var x = 0; x < xStride; x++)
                    {
                        for (var y = 0; y < yStride; y++)
                        {
                            int    actualX  = x + offsetX;
                            int    actualY  = y + offsetY;
                            Rgba32 expected = expectedPatternFast[y, x]; // inverted pattern
                            Rgba32 actual   = sourcePixels[actualX, actualY];
                            if (expected != actual)
                            {
                                Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
                            }
                        }
                    }
                }
                image.Mutate(x => x.Resize(80, 80));
                image.Save($"{path}/{name}x4.png");
            }
        }
示例#11
0
        private async Task <Result <Image <Rgba32> > > GenerateMosaic(Size outputSize, Image <Rgba32> resizedMasterImage, Size tileSize, MosaicTypeEnum selectedMosaicType)
        {
            _tileSize   = tileSize;
            _tX         = resizedMasterImage.Width / tileSize.Width;
            _tY         = resizedMasterImage.Height / tileSize.Height;
            _avgsMaster = new Rgba32[_tX, _tY];

            GetTilesAverage(resizedMasterImage);

            if (selectedMosaicType != MosaicTypeEnum.PlainColor)
            {
                await LoadTilesAndResize();
            }

            _searchAndReplaceService = _searchAndReplaceServiceFactory.Create(selectedMosaicType);
            _searchAndReplaceService.Init(_avgsMaster, outputSize, _tileImageList, tileSize, _tX, _tY);

            var finalImage = _searchAndReplaceService.SearchAndReplace();

            Dispose();

            return(Result.Ok(finalImage));
        }
示例#12
0
    public unsafe void PixelShader_EarlyReturn(Device device)
    {
        using ReadWriteTexture2D <Rgba32, float4> texture = device.Get().AllocateReadWriteTexture2D <Rgba32, float4>(128, 128);

        device.Get().ForEach <EarlyReturnShader, float4>(texture);

        Rgba32[,] result = texture.ToArray();

        for (int i = 0; i < texture.Height; i++)
        {
            for (int j = 0; j < texture.Width; j++)
            {
                if (j % 2 == 0)
                {
                    Assert.AreEqual(result[i, j], new Rgba32(255, 0, 0, 0));
                }
                else
                {
                    Assert.AreEqual(result[i, j], new Rgba32(0, 255, 0, 0));
                }
            }
        }
    }
示例#13
0
        private static bool ProcessImages(string rootPath, string outputDir, string[] files, Rgba32[,] colors, ref int colorsColumnIndex, ref int colorsRowIndex)
        {
            foreach (var file in files)
            {
                // Preserve folder structure when creating encoded copies
                string newPath = GetFilePathRelative(rootPath, file, outputDir);

                // Keep processing images unless and error is detected
                if (!ProcessImage(file, newPath, colors, ref colorsColumnIndex, ref colorsRowIndex))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#14
0
        /// <summary>
        /// Generates a new <see cref="DrawablesOutput"/> for this <see cref="Image"/>, using all the set properties.
        /// </summary>
        /// <returns>DrawablesOutput containing the Drawables for this image.</returns>
        public DrawablesOutput Generate()
        {
            if (Image == null)
            {
                throw new DrawableException("Attempted to generate drawables for a disposed image object.");
            }

            Rgba32?ignore = IgnoreColor;

            Image <Rgba32> b = _image.Clone();

            if (FlipY)
            {
                b.Mutate(x => x.Flip(SixLabors.ImageSharp.Processing.FlipType.Vertical));
            }

            Point frameCount = new Point(
                (int)Math.Ceiling((decimal)b.Width / DrawableWidth),
                (int)Math.Ceiling((decimal)b.Height / DrawableHeight));

            Drawable[,] drawables = new Drawable[frameCount.X, frameCount.Y];

            Rgba32[,] template = GetTemplate();

            Point imagePixel = new Point(0, 0);

            // Add a drawable for every signplaceholder needed.
            for (int frameWidth = 0; frameWidth < frameCount.X; frameWidth++)
            {
                for (int frameHeight = 0; frameHeight < frameCount.Y; frameHeight++)
                {
                    imagePixel.X = frameWidth * DrawableWidth;
                    imagePixel.Y = frameHeight * DrawableHeight;

                    bool containsPixels = false;

                    StringBuilder directives = new StringBuilder("?replace");

                    for (int i = 0; i < DrawableWidth; i++)
                    {
                        for (int j = 0; j < DrawableHeight; j++)
                        {
                            int x = imagePixel.X,
                                y = imagePixel.Y++;

                            // Pixel falls within template but is outside of the supplied image.
                            if ((x > b.Width - 1 || y > b.Height - 1))
                            {
                                continue;
                            }

                            Rgba32 imageColor = b[Convert.ToInt32(x), Convert.ToInt32(y)];

                            // Pixel color is invisible or ignored.
                            if ((ignore.HasValue && imageColor.Equals(ignore)) || (imageColor.A == 0 && !ReplaceBlank))
                            {
                                continue;
                            }
                            else if (ReplaceWhite && imageColor.ToRGBAHexString() == "FFFFFFFF")
                            {
                                imageColor = new Rgba32(254, 254, 254, 255);
                            }

                            Rgba32 templateColor = template[i, j];

                            directives.AppendFormat(";{0}={1}", templateColor.ToRGBAHexString(), imageColor.ToRGBAHexString());

                            if (imageColor.A > 1)
                            {
                                containsPixels = true;
                            }
                        }

                        imagePixel.X++;
                        imagePixel.Y = frameHeight * DrawableHeight;
                    }

                    int xb = Convert.ToInt32(frameWidth * DrawableWidth),
                        yb = Convert.ToInt32(frameHeight * DrawableHeight);

                    if (containsPixels)
                    {
                        drawables[frameWidth, frameHeight] = new Drawable(directives.ToString(), xb, yb, DrawableTexture);
                    }
                }
            }

            return(new DrawablesOutput(drawables, Image.Width, Image.Height, OffsetX, OffsetY));
        }