Question

Please see my code below.

I want to create a Byte array with data that I can convert into a real image. When I try to run this code I get an argumentException. What do I need to do in the For loop in order to create a legitimate Byte array that will hold data of an image? I don't want to use a real image and convert it to byte array, I want to create an image form random numbers.

    Random Rnd = new Random();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Byte[] ByteArray = new Byte[1000];

        for (int i = 0; i < 1000; i++)
        {
            ByteArray[i] = Convert.ToByte(Rnd.Next(9));                
        }
        ImageConverter Convertor = new ImageConverter();
        BitmapImage image = (BitmapImage)Convertor.ConvertFrom(ByteArray);
        MyImage.Source = image;
    }

Notice please that I don't want to work with WinForms types or libraries like system.drawing / bitmap - I only want to use WPF technology.

Was it helpful?

Solution

This is the solution you are looking for, using only WPF technology.

Note that the constant value of 16 used in the stride parameter calculation comes directly from the fact that I am using a 16-bit pixel format.

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Random rnd = new Random();

        Byte[] ByteArray = new Byte[(int)MyImage.Width * (int)MyImage.Height * 3];

        rnd.NextBytes(ByteArray);

        var image = BitmapSource.Create((int) MyImage.Width, (int) MyImage.Height, 72, 72,
            PixelFormats.Bgr565, null, ByteArray, (4*((int)MyImage.Width * 16 + 31)/32));

        MyImage.Source = image;
    }

OTHER TIPS

This just might do the trick for you:

    private static Bitmap GenBitmap(int width, int height) {

        int ch = 3; //number of channels (ie. assuming 24 bit RGB in this case)
        Random rnd = new Random();

        int imageByteSize = width * height * ch;

        byte[] imageData = new byte[imageByteSize]; //your image data buffer
        rnd.NextBytes(imageData);       //Fill with random bytes;

        Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);

        BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
        IntPtr pNative = bmData.Scan0;
        Marshal.Copy(imageData, 0, pNative, imageByteSize);
        bitmap.UnlockBits(bmData);
        return bitmap;

    }

I'm not sure how Converter.ConvertFrom works but I prefer to do my bitmaps the lower-level way with Bitmap.LockBits() and a little Marshal.Copy().

See this method:

    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;

    static Bitmap CreateRandomBitmap(Size size)
    {
        // Create a new bitmap for the size requested.
        var bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);

        // Lock the entire bitmap for write-only acccess.
        var rect = new Rectangle(0, 0, size.Width, size.Height);
        var bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

        // Calculate the number of bytes required and allocate them.
        var numberOfBytes = bitmapData.Stride * size.Height;
        var bitmapBytes = new byte[numberOfBytes];

        // Fill the bitmap bytes with random data.
        var random = new Random();
        for (int x = 0; x < size.Width; x++)
        {
            for (int y = 0; y < size.Height; y++)
            {
                // Get the index of the byte for this pixel (x/y).
                var i = ((y * size.Width) + x) * 4; // 32bpp

                // Generate the next random pixel color value.
                var value = (byte)random.Next(9);

                bitmapBytes[i] = value;         // BLUE
                bitmapBytes[i + 1] = value;     // GREEN
                bitmapBytes[i + 2] = value;     // RED
                bitmapBytes[i + 3] = 0xFF;      // ALPHA
            }
        }

        // Copy the randomized bits to the bitmap pointer.
        var ptr = bitmapData.Scan0;
        Marshal.Copy(bitmapBytes, 0, ptr, numberOfBytes);

        // Unlock the bitmap, we're all done.
        bitmap.UnlockBits(bitmapData);
        return bitmap;
    }

Then you can do something like this:

    public void Run()
    {
        using(var bitmap = CreateRandomBitmap(new Size(64, 64)))
        {
            bitmap.Save("random.png", ImageFormat.Png);
        }
    }

You can't use random bytes to create an image, because each type of image (bmp, jpeg, png) is constructed with a certain format. The code wouldn't know how to interpret random bytes.

http://en.wikipedia.org/wiki/Image_file_formats

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top