title: C# Creating PixelFormat.Format32bppArgb skewing image
body: <p>I am trying to combine 3 grayscale bitmaps into one color bitmap.  All three grayscale images are the same size (this is based off of data from the Hubble).  My logic is:
  Load "blue" image and convert to <code>PixelFormat.Format24bppRgb</code>.  Based off of that create a new byte array that is 4 times as large as the blue data array length/3 (so it will be one byte for blue, one byte for green, one byte for red, one byte for alpha per pixel since my system is little endian).  Populate the "blue" bytes of the array from the "blue" bytes of the blue image (and in this first loop set the alpha byte to 255).  I then load the green and red bitmaps, convert them to <code>PixelFormat.Format24bppRgb</code>, and pull the g/r value and add it to the correct place in the data array.  The final data array then has the bgra bytes set correctly from what I can tell.</p>
  
  <p>When I have the data array populated, I have used it to: </p>
  
  <p>Create a <code>PixelFormats.Bgra32 BitmapSource</code> then convert that to a Bitmap.</p>
  
  <p>Create a <code>PixelFormat.Format32bppArgb</code> Bitmap using the Bitmap constructor (width, height, stride, PixelForma, IntPtr)</p>
  
  <p>Create a <code>PixelFormat.Format32bppArgb</code> Bitmap using pointers</p>
  
  <p>All three ways of creating a return bitmap result in the image being "skewed" (sorry, I don't know of a better word).</p>
  
  <p>The actual output (of all three ways of generating the final bitmap) is: <a href="http://wierdling.longboys.net/soBitmap/output.png" rel="nofollow">Actual output</a></p>
  
  <p>The desired output is something like (this was done in photoshop so it is slightly different): <a href="http://wierdling.longboys.net/soBitmap/desiredOutput.png" rel="nofollow">Desired output</a></p>
  
  <p>The three file names (<code>_blueFileName, _greenFileName, _redFileName</code>) are set in the constructor and I check to make sure the files exist before creating the class.  I can post that code if anyone wants it.</p>
  
  <p>Can anyone tell me what I am doing wrong?  I am guessing that is is due to the stride or something like that?</p>
  
  <p>Note:  I can't post the links to the images I am using as input as I don't have 10 reputation points.  Maybe I could send the links via email or something if someone wants them as well.</p>
  
  <p>Here is my code (with some stuff commented out, the comments describe what happens if each commented out block is used instead):</p>
  
  <pre><code>    public Bitmap Merge()
      {
          //  Load original "blue" bitmap.
          Bitmap tblueBitmap = (Bitmap)Image.FromFile(_blueFileName);
          int width = tblueBitmap.Width;
          int height = tblueBitmap.Height;
          //  Convert to 24 bpp rgb (which is bgr on little endian machines)
          Bitmap blueBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
          using (Graphics gr = Graphics.FromImage(blueBitmap))
          {
              gr.DrawImage(tblueBitmap, 0, 0, width, height);
          }
          tblueBitmap.Dispose();
          //  Lock and copy to byte array.
          BitmapData blueData = blueBitmap.LockBits(new Rectangle(0, 0, blueBitmap.Width, blueBitmap.Height), ImageLockMode.ReadOnly,
              blueBitmap.PixelFormat);
          int numbBytes = blueData.Stride*blueBitmap.Height;
          byte[] blueBytes = new byte[numbBytes];
          Marshal.Copy(blueData.Scan0, blueBytes, 0, numbBytes);
          blueBitmap.UnlockBits(blueData);
          blueData = null;
          blueBitmap.Dispose();
          int mult = 4;
          byte[] data = new byte[(numbBytes/3)*mult];
          int count = 0;
          //  Copy every third byte starting at 0 to the final data array (data).
          for (int i = 0; i &lt; data.Length / mult; i++)
          {
              //  Check for overflow
              if (blueBytes.Length &lt;= count*3 + 2)
              {
                  continue;
              }
              //  First pass, set Alpha channel.
              data[i * mult + 3] = 255;
              //  Set blue byte.
              data[i*mult] = blueBytes[count*3];
              count++;
          }
          //  Cleanup.
          blueBytes = null;
          int generation = GC.GetGeneration(this);
          GC.Collect(generation);
  
          Bitmap tgreenBitmap = (Bitmap)Image.FromFile(_greenFileName);
          Bitmap greenBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
          using (Graphics gr = Graphics.FromImage(greenBitmap))
          {
              gr.DrawImage(tgreenBitmap, 0, 0, width, height);
          }
          tgreenBitmap.Dispose();
          BitmapData greenData = greenBitmap.LockBits(new Rectangle(0, 0, greenBitmap.Width, greenBitmap.Height), ImageLockMode.ReadOnly,
              greenBitmap.PixelFormat);
          numbBytes = greenData.Stride * greenBitmap.Height;
          byte[] greenBytes = new byte[numbBytes];
          Marshal.Copy(greenData.Scan0, greenBytes, 0, numbBytes);
          greenBitmap.UnlockBits(greenData);
          greenData = null;
          greenBitmap.Dispose();
          count = 0;
          for (int i = 0; i &lt; data.Length / mult; i++)
          {
              if (greenBytes.Length &lt;= count * 3 + 1)
              {
                  continue;
              }
              //  Set green byte
              data[i * mult + 1] = greenBytes[count * 3 + 1];
              count++;
          }
          greenBytes = null;
          generation = GC.GetGeneration(this);
          GC.Collect(generation);
  
          Bitmap tredBitmap = (Bitmap)Image.FromFile(_redFileName);
          Bitmap redBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
          using (Graphics gr = Graphics.FromImage(redBitmap))
          {
              gr.DrawImage(tredBitmap, 0, 0, width, height);
          }
          tredBitmap.Dispose();
          BitmapData redData = redBitmap.LockBits(new Rectangle(0, 0, redBitmap.Width, redBitmap.Height), ImageLockMode.ReadOnly,
              redBitmap.PixelFormat);
          numbBytes = redData.Stride * redBitmap.Height;
          byte[] redBytes = new byte[numbBytes];
          Marshal.Copy(redData.Scan0, redBytes, 0, numbBytes);
          redBitmap.UnlockBits(redData);
          redData = null;
          redBitmap.Dispose();
          count = 0;
          for (int i = 0; i &lt; data.Length / mult; i++)
          {
              if (redBytes.Length &lt;= count * 3+2)
              {
                  count++;
                  continue;
              }
              // set red byte
              data[i * mult + 2] = redBytes[count * 3 + 2];
              count++;
          }
          redBytes = null;
          generation = GC.GetGeneration(this);
          GC.Collect(generation);
          int stride = (width*32 + 7)/8;
          var bi = BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgra32, null, data, stride);
          //  uncomment out below to see what a bitmap source to bitmap does.  So far, it is exactly the same as 
          //  the uncommented out lines below.
          //  ---------------------------------------------------------------------------------------------------
          //return BitmapImage2Bitmap(bi);
          unsafe
          {
              fixed (byte* p = data)
              {
                  IntPtr ptr = (IntPtr)p;
                  //  Trying the commented out lines returns the same bitmap as the uncommented out lines.
                  //  ------------------------------------------------------------------------------------
                  byte* p2 = (byte*)ptr;
                  Bitmap retBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                  BitmapData fData = retBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,
                      PixelFormat.Format32bppArgb);
                  unsafe
                  {
                      for (int i = 0; i &lt; fData.Height; i++)
                      {
                          byte* imgPtr = (byte*)(fData.Scan0 + (fData.Stride * i));
                          for (int x = 0; x &lt; fData.Width; x++)
                          {
                              for (int ii = 0; ii &lt; 4; ii++)
                              {
                                  *imgPtr++ = *p2++;
                              }
                              //*imgPtr++ = 255;
                          }
                      }
                  }
                  retBitmap.UnlockBits(fData);
                  //Bitmap retBitmap = new Bitmap(width, height, GetStride(width, PixelFormat.Format32bppArgb),
                  //    PixelFormat.Format32bppArgb, ptr);
                  return retBitmap;
              }
          }
  
      }
  
      private Bitmap BitmapImage2Bitmap(BitmapSource bitmapSrc)
      {
          using (MemoryStream outStream = new MemoryStream())
          {
              BitmapEncoder enc = new BmpBitmapEncoder();
              enc.Frames.Add(BitmapFrame.Create(bitmapSrc));
              enc.Save(outStream);
              Bitmap bitmap = new Bitmap(outStream);
              return new Bitmap(bitmap);
          }
      }
  
      private int GetStride(int width, PixelFormat pxFormat)
      {
          int bitsPerPixel = ((int)pxFormat &gt;&gt; 8) &amp; 0xFF;
          int validBitsPerLine = width * bitsPerPixel;
          int stride = ((validBitsPerLine + 31) / 32) * 4;
          return stride;
      }
  </code></pre>