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. Graphics
  4. SetPixel() too slow?

SetPixel() too slow?

Scheduled Pinned Locked Moved Graphics
data-structuresquestion
5 Posts 3 Posters 1 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.
  • N Offline
    N Offline
    Naturality
    wrote on last edited by
    #1

    Hi, I wasn't sure where to put this, but this seems the most appropriate place. I'm trying to load an image from a 2 Dimensional array into the main screen DC, like so.

    for(int y = 0; y < height; y++){
    for(int x = 0; x < width; x++){
    SetPixel(imgDC, x, y, RGB(imgarray[x][y], imgarray[x][y], imgarray[x][y]));
    }
    }

    StretchBlt(hdc, 0,0, 640, 480, imgDC, 0, 0, width, height, SRCCOPY);

    But this becomes too slow for my needs if the image if larger than about 256x256. I have also tried using do while loops, which were a fraction faster. Is there a better way to do this?

    "Sir, I protest. I am NOT a merry man!"

    M 1 Reply Last reply
    0
    • N Naturality

      Hi, I wasn't sure where to put this, but this seems the most appropriate place. I'm trying to load an image from a 2 Dimensional array into the main screen DC, like so.

      for(int y = 0; y < height; y++){
      for(int x = 0; x < width; x++){
      SetPixel(imgDC, x, y, RGB(imgarray[x][y], imgarray[x][y], imgarray[x][y]));
      }
      }

      StretchBlt(hdc, 0,0, 640, 480, imgDC, 0, 0, width, height, SRCCOPY);

      But this becomes too slow for my needs if the image if larger than about 256x256. I have also tried using do while loops, which were a fraction faster. Is there a better way to do this?

      "Sir, I protest. I am NOT a merry man!"

      M Offline
      M Offline
      Matthew Butler 0
      wrote on last edited by
      #2

      There is an incredibly fast way of doing this... LockBits; the first time I needed to do something like this it took me a while to get the indexing right... but it pays off in the end. The MSDN page on it... http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^] A good example... http://blog.paranoidferret.com/index.php/2007/08/31/csharp-tutorial-convert-a-color-image-to-greyscale/[^]

      Bitmap image = (Bitmap)oldimage.Clone();
      BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
      unsafe
      {
      byte* ptr = (byte*)bmpData.Scan0.ToPointer();
      for (int Y = 0; Y < image.Height; Y++)
      {
      for (int X = 0; X < image.Width; X++)
      {
      // alter the colours here
      *ptr++ = 0; // blue
      *ptr++ = 0; // green
      *ptr++ = 0; // red
      }
      ptr += bmpData.Stride - image.Width * 3;
      }
      }
      image.UnlockBits(bmpData);

      *ptr++ is the current byte representing a 'sub-pixel' of the current pixel at image position [x, y]: the reason why the pointer is incremented three times. Hope this helps.

      Matthew Butler

      N 1 Reply Last reply
      0
      • M Matthew Butler 0

        There is an incredibly fast way of doing this... LockBits; the first time I needed to do something like this it took me a while to get the indexing right... but it pays off in the end. The MSDN page on it... http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^] A good example... http://blog.paranoidferret.com/index.php/2007/08/31/csharp-tutorial-convert-a-color-image-to-greyscale/[^]

        Bitmap image = (Bitmap)oldimage.Clone();
        BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        unsafe
        {
        byte* ptr = (byte*)bmpData.Scan0.ToPointer();
        for (int Y = 0; Y < image.Height; Y++)
        {
        for (int X = 0; X < image.Width; X++)
        {
        // alter the colours here
        *ptr++ = 0; // blue
        *ptr++ = 0; // green
        *ptr++ = 0; // red
        }
        ptr += bmpData.Stride - image.Width * 3;
        }
        }
        image.UnlockBits(bmpData);

        *ptr++ is the current byte representing a 'sub-pixel' of the current pixel at image position [x, y]: the reason why the pointer is incremented three times. Hope this helps.

        Matthew Butler

        N Offline
        N Offline
        Naturality
        wrote on last edited by
        #3

        Hi, thanks for your reply. Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?

        "Sir, I protest. I am NOT a merry man!"

        M 1 Reply Last reply
        0
        • N Naturality

          Hi, thanks for your reply. Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?

          "Sir, I protest. I am NOT a merry man!"

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          Naturality wrote:

          Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?

          LockBits is GDI+ and works great. In addition to that... With GDI, a DIBsection gives you a bitmap you can use like a DDB but with a pointer to the pixel bits array. See CreateDIBSection(). A DIBSection (like a GDI+ Bitmap object) is also more flexible than a DDB, since it can be created it with the same pixel format as your data and still be selected into into a memory DC that is not the same format as the screen. Mark

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          N 1 Reply Last reply
          0
          • M Mark Salsbery

            Naturality wrote:

            Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?

            LockBits is GDI+ and works great. In addition to that... With GDI, a DIBsection gives you a bitmap you can use like a DDB but with a pointer to the pixel bits array. See CreateDIBSection(). A DIBSection (like a GDI+ Bitmap object) is also more flexible than a DDB, since it can be created it with the same pixel format as your data and still be selected into into a memory DC that is not the same format as the screen. Mark

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            N Offline
            N Offline
            Naturality
            wrote on last edited by
            #5

            Thanks, I've been looking into it and it seems like it's the answer for me :-D

            "Sir, I protest. I am NOT a merry man!"

            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