2

I'm trying to convert a JPG image to a (double) 2d array. Using:

Image image = Image.FromFile("image.jpg");

I get a 500 x 500 image (according to image.Size.Height(Width)). But when I try to convert this to a byte array using

byte[] arr;
using (MemoryStream ms = new MemoryStream())
{
    image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    arr = ms.ToArray();
}

I get arr.GetLength(0)=35640, which is smaller than 500*500=250000. I'll convert the 1d array arr to a 2d array after that. Am I missing something?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Ryan
  • 129
  • 2
  • 8
  • 1
    JPEG is a lossy-compression-based file format. A 500x500 pixel JPEG file can take up a different amount of memory depending on the contents of image - a pure single color would be very small, while a photograph would be much larger, even though they have the same number of pixels. – DGH Jul 12 '12 at 23:01

2 Answers2

2

You are not saving a pixel representation.. you are saving the bytes of a JPEG file. If you want actual pixels you need to loop over the pixels.

Also be aware that each pixel has a minimum of 3 components: Red, Green, Blue.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
  • OK. How do I loop over the pixels? I see a GetPixel method, but only for bitmaps. This JPG is actually converted from a FITS file. It should be grayscale (or at least I want it to be, that is, just one value per pixel, not 3). I tried CSharpFITS, but couldn't get it to load properly as a reference... – Ryan Jul 12 '12 at 23:09
  • See the discussion under dthorpe's answer. – Sam Axe Jul 12 '12 at 23:26
1

If you save the image in JPEG format, the pixels written to the stream will be compressed.

If you're wanting to manipulate the pixels of the image, you should probably load the image into a Bitmap and then call Bitmap.LockBits to get at the raw pixels in memory.

dthorpe
  • 35,318
  • 5
  • 75
  • 119
  • 1
    BMP format will still include the BMP header data and will not yield a 250000 element array. – Sam Axe Jul 12 '12 at 22:52
  • You'll need to pay attention to the pixel format to correctly walk through the raw pixel memory. If you don't care about speed, there's also Bitmap.GetPixel(x,y) which will return the color of the pixel at that x,y location. It's really slow but really easy to use. – dthorpe Jul 12 '12 at 23:18
  • OK. It looks like I need to convert the resulting color (RGB structure) to a single pixel value. Still trying. Correct me if I'm wrong (original goal is to go from bitmap -> 500x500 double array). Thanks for the advice. – Ryan Jul 12 '12 at 23:45
  • Got it. Followed Greg's answer [here](http://stackoverflow.com/questions/359612/how-to-change-rgb-color-to-hsv)...thanks. – Ryan Jul 12 '12 at 23:56