2

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.

Community
  • 1
  • 1
Stack Tack Tack
  • 129
  • 2
  • 11

4 Answers4

4

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;
    }
Brian Driscoll
  • 19,373
  • 3
  • 46
  • 65
  • Thanks for your answer - that was exactly what I was looking for! Can you please explain how I can change the method you wrote, in order to get a picture with only the colors red, green or blue? – Stack Tack Tack Jan 08 '14 at 08:15
  • @StackTackTack I am not sure exactly what you mean, as the image generated by the code above contains only red, green, and blue combinations. Are you saying you only want certain discrete combinations of RGB? – Brian Driscoll Jan 08 '14 at 14:40
  • Are you sure that the code only creates an image with the colors red, green and blue? Because when I used your code I saw other colors like pink, gray etc'. – Stack Tack Tack Jan 08 '14 at 14:49
  • @StackTackTack It creates many different colors based on randomly generated values assigned to the red, green, and blue color channels for each pixel. Thus, every pixel is some combination of red, green, and blue. It sounds, however, like you want something different... – Brian Driscoll Jan 08 '14 at 15:14
0

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);
        }
    }
Cubicle.Jockey
  • 3,288
  • 1
  • 19
  • 31
Erik
  • 12,730
  • 5
  • 36
  • 42
0

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;

    }
Xinbi
  • 272
  • 1
  • 2
  • 10
  • How can I make legal byte array of image data, without using 'system.drawing' objects? I want to use only ImageSource or BitmapImage. Only WPF Technology. – Stack Tack Tack Jan 07 '14 at 21:30
-3

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

Xavier J
  • 4,326
  • 1
  • 14
  • 25