tags:

views:

65

answers:

2

I start out with a 128 x 128 array of doubles and turn that into a 1D array of bytes with proportional values for each double.

I then take this array of bytes and turn it into a memory stream (dataStream below) and try and put that into a BitmapImage like so:

imgScan.Width = 128;
imgScan.Height = 128;
BitmapImage bi = new BitmapImage();
bi.SourceRect = new Int32Rect(0, 0, width, height);
bi.StreamSource = dataStream;
imgScan.Source = bi;

Here imgScan is a System.Windows.Controls.Image

This doesn't produce the expected image (I just get a white square).

How should I be going about this?

A: 

Use a Bitmap(Stream) constructor

ULysses
Surely this loads a bitmap file, not a block of data?
Will Dean
new Bitmap(new MemoryStream(bytes))
consultutah
@Will Dean: cmon, have you even followed the link? There is an example with the stream being a network stream. @consultutah is absolutely correct.
ULysses
Thanks Ulysses, but I need to use this in a `System.Windows.Controls.Image`, which doesn't take a `System.Drawing.Bitmap` as far as I can figure out.
Matt Ellen
@Ulysses - Yes, but in that example, the network stream is a stream of bytes representing a .GIF file, NOT a stream of bytes representing a block of pixels. If you pass a raw stream of bytes into a Bitmap object, how would it know a. the pixel format, b. the width of the bitmap?
Will Dean
+1  A: 

I think you'll find that in your code, the stream should contain a complete image file, not a raw block of data. Here's making a Bitmap from a block of data (it's not greyscale, but you might get the idea):

const int bytesPerPixel = 4;
int stride = bytesPerPixel * pixelsPerLine;
UInt32[] pixelBytes = new uint[lineCount * pixelsPerLine];

for (int y = 0; y < lineCount; y++)
{
    int destinationLineStart = y * pixelsPerLine;
    int sourceLineStart = y * pixelsPerLine;
    for (int x = 0; x < pixelsPerLine; x++)
    {
        pixelBytes[x] = _rgbPixels[x].Pbgr32;
    }
}
var bmp = BitmapSource.Create(pixelsPerLine, lineCount, 96, 96, PixelFormats.Pbgra32, null, pixelBytes, stride);
bmp.Freeze();
return bmp;

You've already done the bit in the nested loops (making the byte array), but I left it in so you can see what comes before the Create

Will Dean
Thanks, Will. One more question: what does stride mean? I can see you've set it to `bytesPerPixel * pixelsPerLine`, but I'm not familiar with the term.
Matt Ellen
Stride is the number of bytes it takes to get from the start of one line to the start of the next in your data block. In your case, it will be the width of your byte block, but in a case where, for example, you had three byte pixels (RGB888 perhaps), then the stride is often going to be a multiple of four bytes even if (3xnumber of pixels) is not a multiple of four itself. It's so that lines always start on a nicely aligned memory address, and is really a hangover from the days when people cared a lot about perf details like this.
Will Dean
Brilliant. Thanks, Will.
Matt Ellen