Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Reading a Bitmap in Unsafe vs InteropServices.Marshall

Reading a Bitmap in Unsafe vs InteropServices.Marshall

Scheduled Pinned Locked Moved C#
visual-studiographicsdata-structuresdebuggingcareer
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    PhilDanger
    wrote on last edited by
    #1

    Hi, I've got the following code which reads from an image that has information encoded in as pixels. My job is to scan through the image, and set the value of an array to true if a pixel is black, and false if it is any other color. I have the following bit of unsafe code that performs it:

                BitmapData bmpdata = AOIImg.LockBits(new Rectangle(0, 0, WIDTH, HEIGHT), ImageLockMode.ReadOnly, AOIImg.PixelFormat);
                IntPtr scan0 = bmpdata.Scan0;
                int stride = bmpdata.Stride;
                int imgOffs;
                try
                {
                    //loop through the image and set the main AOI mask
                    unsafe
                    {
                        byte* imgPtr;
                        for (int y = 0; y < HEIGHT; ++y)
                        {
                            imgOffs = y * stride;
                            imgPtr = &((byte*)scan0)[imgOffs];
                            for (int x = 0; x < WIDTH; ++x)
                            {
                                //checks the blue, green, and red values of the pixel to see if it's black
                                if (imgPtr[0] == 0 && imgPtr[1] == 0 && imgPtr[2] == 0)
                                { //pixel is black -- exclude from aoi mask
                                    AOIMask[y * WIDTH + x] = true;
                                }
                                else //no feature
                                {
                                    AOIMask[y * WIDTH + x] = false;
                                }
                                imgPtr += 3; //advance ptr by 3 bytes (one pixel)
                            }
    
                        }
                    }
                }
                finally 
                {
                    AOIImg.UnlockBits(bmpdata);
    #if DEBUG
                    //TODO -- remove
                    AOIImg.Save(@"C:\temp.png", ImageFormat.Png);
    #endif
                    AOIImg.Dispose();
                }
    

    However, I was wondering if I could turn this into managed code using InteropsServices.Marshall to copy the pixel data to an array and read through it in a safe context. I was wondering if anyone had any warnings about using this method, such as the stride not being correctly accounted for in the marshalled array (I'm not sure if I have to do this manually or not at all!). Thanks in advance, Phil

    J 1 Reply Last reply
    0
    • P PhilDanger

      Hi, I've got the following code which reads from an image that has information encoded in as pixels. My job is to scan through the image, and set the value of an array to true if a pixel is black, and false if it is any other color. I have the following bit of unsafe code that performs it:

                  BitmapData bmpdata = AOIImg.LockBits(new Rectangle(0, 0, WIDTH, HEIGHT), ImageLockMode.ReadOnly, AOIImg.PixelFormat);
                  IntPtr scan0 = bmpdata.Scan0;
                  int stride = bmpdata.Stride;
                  int imgOffs;
                  try
                  {
                      //loop through the image and set the main AOI mask
                      unsafe
                      {
                          byte* imgPtr;
                          for (int y = 0; y < HEIGHT; ++y)
                          {
                              imgOffs = y * stride;
                              imgPtr = &((byte*)scan0)[imgOffs];
                              for (int x = 0; x < WIDTH; ++x)
                              {
                                  //checks the blue, green, and red values of the pixel to see if it's black
                                  if (imgPtr[0] == 0 && imgPtr[1] == 0 && imgPtr[2] == 0)
                                  { //pixel is black -- exclude from aoi mask
                                      AOIMask[y * WIDTH + x] = true;
                                  }
                                  else //no feature
                                  {
                                      AOIMask[y * WIDTH + x] = false;
                                  }
                                  imgPtr += 3; //advance ptr by 3 bytes (one pixel)
                              }
      
                          }
                      }
                  }
                  finally 
                  {
                      AOIImg.UnlockBits(bmpdata);
      #if DEBUG
                      //TODO -- remove
                      AOIImg.Save(@"C:\temp.png", ImageFormat.Png);
      #endif
                      AOIImg.Dispose();
                  }
      

      However, I was wondering if I could turn this into managed code using InteropsServices.Marshall to copy the pixel data to an array and read through it in a safe context. I was wondering if anyone had any warnings about using this method, such as the stride not being correctly accounted for in the marshalled array (I'm not sure if I have to do this manually or not at all!). Thanks in advance, Phil

      J Offline
      J Offline
      Jon Hulatt
      wrote on last edited by
      #2

      You'll have to account for stride manually, but there is nothing to this. The Marshal.Copy() method just copy blocks of data. If Stride and (Width * BytesPerPixel) are not equal, then the data at the end of each image row is padded with zeros. This doesn't matter. Make sure you allocate a byte [] array of size = height * stride, and use marshal.copy to fill it. Use nested loops to avoid any stride difference:-

      for (y=0; y

      using System.Beer;

      P 1 Reply Last reply
      0
      • J Jon Hulatt

        You'll have to account for stride manually, but there is nothing to this. The Marshal.Copy() method just copy blocks of data. If Stride and (Width * BytesPerPixel) are not equal, then the data at the end of each image row is padded with zeros. This doesn't matter. Make sure you allocate a byte [] array of size = height * stride, and use marshal.copy to fill it. Use nested loops to avoid any stride difference:-

        for (y=0; y

        using System.Beer;

        P Offline
        P Offline
        PhilDanger
        wrote on last edited by
        #3

        Thanks, This will be double the memory usage of the unsafe version, correct? -Phil

        L 1 Reply Last reply
        0
        • P PhilDanger

          Thanks, This will be double the memory usage of the unsafe version, correct? -Phil

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Sure, twice the memory, and a lot slower if you dont use a pointer... :)

          Luc Pattyn [My Articles] [Forum Guidelines]

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups