0

I have a Bitmap from a resource and need to put it in a byte array. I have a SetPixel Methode for manipulating pixels in my Byte Array. That works all well. What I want to do, is to load first a picture in the array that I can manipulate it later.

I tried quite a lot to acomplish that. First what I have:

var resources = new ComponentResourceManager(typeof(Game));
var bmp = (Bitmap)(resources.GetObject("imgBall.Image"));

the only so far not giving me an error message (but displaying the picutre wrong) is this:

width = (int)bmp.Width;
height = (int)bmp.Height;
System.Windows.Media.PixelFormat pf = PixelFormats.Rgb24;
rawStride = (width * pf.BitsPerPixel + 7) / 8;
byte[] pixelData = new byte[rawStride * height];    

MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
pixelData = ms.GetBuffer();

then I tried solutions I could find in stack overflow already:

ImageConverter imgConverter = new ImageConverter();
pixelData = (System.Byte[])imgConverter.ConvertTo(bmp, Type.GetType("System.Byte[]"));

This changes the size of pixelData, so that I cannot use it anymore...

using (MemoryStream memory = new MemoryStream())
            {
                bmp.Save(memory, ImageFormat.Bmp);
                memory.Position = 0;
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                memory.Seek(0, SeekOrigin.Begin);
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                int stride = width * ((bitmapImage.Format.BitsPerPixel + 7) / 8);                                

                bitmapImage.CopyPixels(pixelData, stride, 0);                
            }

here at the CopyPixels line I am confused: when I take rawStride from above (84) I get an error message it needs to be at lease 112. When I calculate stride for bitmapImage (112) it complains it needs to be minimum 3136. I even tried to enter the number of stride manually it compains allways it needs to be bigger.

I have the feeling that I understand something completely wrong here.

DaRula
  • 33
  • 1
  • 7
  • I know you've said you already have a SetPixel method working but I have to ask why you aren't just using the SetPixel method that Bitmap has already? It seems that this would remove the complexity of what you are having problems with here... – Chris Mar 13 '14 at 12:23
  • http://stackoverflow.com/questions/17350058/converting-a-thresholded-image-into-a-byte-array/17350164#17350164 – Dmitry Bychenko Mar 13 '14 at 12:27
  • Also for setting the bytes it might be easier (and clearer for you) to just loop through the pixels getting the byte data manually. I would imagine that the reason for failure on many of your attempts may be that when converting a `Bitmap` to a memorystream or similar that it will create metadata about the format that you don't actually want.; – Chris Mar 13 '14 at 12:27
  • The SetPixel method of Bitmap is not working for windows phone. I should have written that I will need to use it later on windows phone aswell. – DaRula Mar 13 '14 at 12:27
  • dmitry, that solution works with lockbits. That was reporter very slow. But if everything else fails I will give it a try, thanks for the link. Chris, I will try that with looping through the pixels and post my results, thanks. – DaRula Mar 13 '14 at 12:32
  • Dmitry, I tried your solution with the same result as my first try - it runs without error but the image isn't displayed correctly. I now found out that it's a problem of the color palette. So I currently working in that direction. – DaRula Mar 13 '14 at 16:55

1 Answers1

0
public string BitmapToBase64(BitmapImage bi)
{
  MemoryStream ms = new MemoryStream();
  PngBitmapEncoder encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bi));
  encoder.Save(ms);
  byte[] bitmapdata = ms.ToArray();

  return Convert.ToBase64String(bitmapdata);
}

This should do the thing. Just return the byteArray if that is what you want.

Max Mazur
  • 1,188
  • 1
  • 13
  • 22
  • Max, i tried your solution with the change that i don't return a string, but the array itself. The problem seems to be that the byte array pixelData has initially the size of 2352 but the array returned from your methode has only 285, similarly to the try with the ImageConverter. – DaRula Mar 13 '14 at 14:41
  • Hmm. I see, hadn't tried it myself. I use this method, for transforming and saving bitmaps/pictures into xml with a Base64 string. – Max Mazur Mar 13 '14 at 14:44