none
Why is red pixel appering at the end of every line? RRS feed

  • Question

  • I want to encode a file into an image and this is how I do it:

    Bitmap image = new Bitmap("empty.png", true); int colorcount = 1; int x = 0; int y = 0; foreach(string message in messagenums) { if (x == image.Width-1) { x = 0; y++; } else { if (colorcount == 4) { colorcount = 1; x++; } if (colorcount == 1) { image.SetPixel(x, y, Color.FromArgb(int.Parse(message), image.GetPixel(x, y).G, image.GetPixel(x, y).B)); } if (colorcount == 2) { image.SetPixel(x, y, Color.FromArgb(image.GetPixel(x, y).R, int.Parse(message), image.GetPixel(x, y).B)); } if (colorcount == 3) { image.SetPixel(x, y, Color.FromArgb(image.GetPixel(x, y).R, image.GetPixel(x, y).G, int.Parse(message))); } colorcount++; } }

                image.Save("Filled.png");
                Console.WriteLine("Saved");

    messagenums is just an array of numbers here is exapmle array:https://pastebin.com/raw/xpB5QrMp

    When you open image last pixel always has only red channel why?

    Thursday, June 20, 2019 3:57 PM

All replies

  • Maybe you should try a different loop:

     

    foreach(string message in messagenums)

    {

       if (colorcount == 1)

       {

          . . .

       }

       else if (colorcount == 2)

       {

          . . .

       }

       else

       {

          . . .

       }

     

       if( ++colorcount > 3) colorcount = 1;

       if( ++x >= image.Width)

       {

          x = 0;

          ++y;

       }

    }



    • Edited by Viorel_MVP Thursday, June 20, 2019 5:07 PM
    • Marked as answer by BataBo Jokviu Thursday, June 20, 2019 5:23 PM
    • Unmarked as answer by BataBo Jokviu Thursday, June 20, 2019 5:35 PM
    Thursday, June 20, 2019 5:03 PM
  • Maybe you should try a different loop:

     

    foreach(string message in messagenums)

    {

       if (colorcount == 1)

       {

          . . .

       }

       else if (colorcount == 2)

       {

          . . .

       }

       else

       {

          . . .

       }

     

       if( ++colorcount > 3) colorcount = 1;

       if( ++x >= image.Width)

       {

          x = 0;

          ++y;

       }

    }




    It paints first pixel red second green third blue I want it to apply all 3 channel to 1 pixel my previous code did exactly that,only it applied only red channel to last pixel
    Thursday, June 20, 2019 5:38 PM
  • Your first 'if' is causing the loop to skip numbers.

                        // Don't have an 'else' after this 'if'. Set the next colour channel even if it's true.
                        if (x == image.Width-1)
                        {
                            x = 0;
                            y++;
                        }
    
    
                        if (colorcount == 4)
                        {
                             colorcount = 1;
                             x++;
                        }
    
                        // Etc. etc., the rest of your code follows.
                            
    

    Thursday, June 20, 2019 11:25 PM
  • SetPixel and GetPixel are expensive operations.  Your task would actually be easier if you used LockBits to fetch a pointer to the bytes of the image, then copy your new values into the array, then copy the modified bytes back to the bitmap.  The LockBits documentation page describes this:

      https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.lockbits

    Even without that, your code would much faster if you gathered up 3 values at a time, then did a single SetPixel call.  After all, you don't really care what the old pixel value was.  You're going to overwrite the whole thing anyway, except for the very last pixel if the length of messagenums is not a multiple of 3.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Friday, June 21, 2019 8:26 PM