0

I'm trying to write a program in c# to send a frame via ethernet.

Currently I have .jpg test images in 1920x1080 resolution and very different sizes in bytes.

I am trying to convert a .jpg image to a byte array, I looked for similar answers but when I tried them I got byte arrays including 437, 1030, 1013 bytes for each image. Considering that the images are in HD resolution, this does not make sense. How can I convert an image file to form a 1920*1080*3 (RGB) byte array? Please keep in mind that I am trying to develop a real time application that should be able to send frames at a high rate so this code cannot be slow.

Thanks in advance. Tunc

talkanat
  • 329
  • 1
  • 3
  • 7
  • 1
    What have you tried? can you post some code ? http://stackoverflow.com/help/how-to-ask – Mark Broadhurst Jul 17 '13 at 11:16
  • "so this code cannot be slow" - but your final version won't be using your test images as source, and so won't have to decode JPEGs will it? – Rup Jul 17 '13 at 11:20
  • Here someone explains how to create a byte array from an image. That might help. http://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array-in-c – Kai Hartmann Jul 17 '13 at 11:26
  • If you're after a pixel per index.. that isn't possible with a `byte` array. One channel can be stored in a `byte`.. not all three. You'll need an `int` array for that.. – Simon Whitehead Jul 17 '13 at 11:26
  • 2
    Not to rain on the parade, but if you're going to be passing JPEGs over ethernet, you will get far better results sending the raw file bytes of the compressed JPEG, rather than decoding it, reading to byte array and sending a (much much larger) volume of data over ethernet. – Rotem Jul 17 '13 at 11:27
  • @Simon he said 1920x1080x3, so I think it's one colour channel per index. But ultimately he won't care about the C# format as long as he can dump it to the wire one byte per channel per pixel. – Rup Jul 17 '13 at 11:30
  • @Rup I wasn't sure.. so I thought I may as well mention it anyway. Besides.. Rotem is 100% correct about this, so it's kinda silly. – Simon Whitehead Jul 17 '13 at 11:31

2 Answers2

1

to read Image bytes to byte array:

                Image image = ...;
                MemoryStream ms = new MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

                if (ms.Length == 0)
                {
                    ms.Close();
                    throw new Exception("Bad Image File");
                }

                ms.Position = 0;
                byte[] baImageBytes = new byte[ms.Length];
                ms.Read(baImageBytes , 0, (int)ms.Length);
                ms.Close();

to create image from byte array:

byte[] baImageBytes =...
Image myImage = Image.FromStream(new MemoryStream(baImageBytes ));
coder
  • 3,195
  • 2
  • 19
  • 28
  • I don't think either of those are what he wants. He wants to make an Image from a JPEG file and then construct a byte array with three bytes per rendered pixel, one for each of RGB. – Rup Jul 17 '13 at 11:27
0

JPG is a compressed format, that's why its size (and size of the corresponding Byte array) will be usually far less than 1920*1080*3. In order to get Byte array from JPG you can use streams:

  Image myImage; 
  ...
  byte[] result;

  using (MemoryStream ms = new MemoryStream()) {
    myImage.Save(ms, ImageFormat.Jpeg); 

    result = ms.ToArray();
  }

If all you want are pixels in a form of Byte array you have to convert your JPG into BMP (or other raw, uncompressed format)

  Bitmap myImage;
  ... 
  byte[] rgbValues = null;

  BitmapData data = myImage.LockBits(new Rectangle(0, 0, myImage.Width, myImage.Height), ImageLockMode.ReadOnly, value.PixelFormat);

  try {
    IntPtr ptr = data.Scan0;
    int bytes = Math.Abs(data.Stride) * myImage.Height;
    rgbValues = new byte[bytes];
    Marshal.Copy(ptr, rgbValues, 0, bytes);
  }
  finally {
    myImage.UnlockBits(data);
  }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215