1

I am trying to convert some Java code into C# for an application. I can't seem to find the exact equivalent of setPixels method in android.Graphics.Bitmap in C# .NET.

Here is the Java code:

    BitMatrix result =  some code ..... 

    int w = result.getWidth();
    int h = result.getHeight();
    int[] pixels = new int[w * h];

    for (int y = 0; y < h; y++) {

        int offset = y * w;

        for (int x = 0; x < w; x++) {
            pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
        }

    }

    Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    bitmap.setPixels(pixels, 0, 480, 0, 0, w, h);

Here is my attempt at converting it into C#:

    int w = result.Width;
    int h = result.Height;
    int[] pixels = new int[w * h];

    for (int y = 0; y < h; y++)
    {

        int offset = y * w;

        for (int x = 0; x < w; x++)
        {
            pixels[offset + x] = result[x, y] ? Color.Black.ToArgb() : Color.White.ToArgb();    
        }

    }

    Bitmap bitmap = new Bitmap(w, h);

    // how to convert the line below 

    bitmap.setPixels(pixels, 0, 480, 0, 0, w, h);
    

How should I go about converting the last line into C#. Any suggestions?

Kafka
  • 21
  • 2
  • Have you seen [Bitmap.SetPixel](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.setpixel?view=net-5.0) ? If you want to set multiple pixels, see [fast work with bitmaps](https://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp) – JonasH Aug 20 '21 at 16:56
  • Also, [WriteableBitmap.WritePixels](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.writeablebitmap.writepixels?view=net-5.0) for a more modern alternative. – JonasH Aug 20 '21 at 17:06
  • @JonasH I did see Bitmap.SetPixel but was not sure how to use it. After some further thinking: ` for (int Xcount = 0; Xcount < bitmap.Width; Xcount++) { for (int Ycount = 0; Ycount < bitmap.Height; Ycount++) { bitmap.SetPixel(Xcount, Ycount, Color.FromArgb(pixels[Xcount])); } }` – Kafka Aug 20 '21 at 17:55
  • But I am not sure whether I should put **pixels[Xcount]** or **pixels[Ycount]** ? – Kafka Aug 20 '21 at 18:01

1 Answers1

0

The simplest solution is to replace

pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;

with

bitmap.SetPixel(x, y, result[x, y] ? Color.Black : Color.White);

This will be rather slow, since it will take some locks for each pixel set. You will also need to create the bitmap first.

A faster way would be to use unsafe code to get a pointer to the bitmap data. See fast work with bitmaps. Assuming an Argb color bitmap

    var bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
    byte* scan0 = (int*)bData.Scan0.ToPointer();

    for (int y = 0; y < bData.Height; ++y)
    {
        var rowPtr = scan0 + y * bData.Stride * 4; 
        for (int x = 0; x < bData.Width; ++x)
        {
             rowPtr[x] = result[x, y] ? Color.Black.ToArgb() : Color.White.ToArgb();  
        }
    }
JonasH
  • 28,608
  • 2
  • 10
  • 23
  • You can perfectly use `LockBits` without unsafe operations by using the `Marshal` class to copy the data. – Nyerguds Sep 08 '21 at 13:34