Search code examples
c#.net-coresystem.drawing

Color channel not saved when saving PNG


I'm trying to make an application that extracts colors from a PNG and puts them into a look-up texture, then saved a copy of the original PNG that uses the color channels to store location for the LUT. This works fine for a 1D LUT, but won't save the extra channel for a 2D LUT.

After the image is output I load it up in Photoshop to check the channels, and the Red channel saved correctly but not the Green channel.

It doesn't seem to matter which channel, for some reason it won't save anything but 0 for foundRow, even though when stepping through in the debugger I can verify that foundRow goes up to at least 3 for this particular image.

private static bool ProcessImage(string filePath, string newPath, Color[,] colors, ref int colorsColumnIndex, ref int colorsRowIndex)
        {
            Console.WriteLine($"Processing file: {filePath}");

            var bmp = new Bitmap(filePath);

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    var pixel = bmp.GetPixel(x, y);
                    var lutPixel = Color.FromArgb(pixel.R, pixel.G, pixel.B);

                    int foundColumn;
                    int foundRow;
                    GetColorIndexes(colors, lutPixel, out foundColumn, out foundRow);

                    if (foundColumn < 0 || foundRow < 0)
                    {
                        foundColumn = colorsColumnIndex;
                        foundRow = colorsRowIndex;

                        colors[foundColumn, foundRow] = lutPixel;

                        colorsColumnIndex++;
                        if (colorsColumnIndex >= 256)
                        {
                            colorsColumnIndex = 0;
                            colorsRowIndex++;
                        }
                    }

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

                    //if (foundRow != 0)
                        //Console.Write($"Setting pixel at {x}, {y} to R: {foundColumn}, G: {foundRow}");

                    var newPixel = Color.FromArgb(255, foundColumn, foundRow, 0);
                    bmp.SetPixel(x, y, newPixel);
                }
            }

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

            return true;
        }

At these lines:

var newPixel = Color.FromArgb(255, foundColumn, foundRow, 0);
bmp.SetPixel(x, y, newPixel);

If newPixel is ARGB(255, 1, 1, 0) the actual saved file results in ARGB(255, 1, 0, 0) for some reason


Solution

  • Found the issue! Turns out the code I originally posted does work correctly, but I was accidentally saving black into some parts of the LUT that I shouldn't have. The fix is at line 62 here if anyone is interested.