tags:

views:

757

answers:

3

I have a problem to convert an byte array to double array using BitConverter.ToDouble().

Simply my program will select an image then convert the image to byte array. Then it will convert the byte array to double array.

The problem that when I convert the byte array to the double I will get this error before the loop finish.

(Destination array is not long enough to copy all the items in the collection. Check array index and length.)

The error happen exactly at array.Length-7 position which is last seventh position before the last position on the array.

I need help to solve this problem and here is my code:

private Bitmap loadPic;
byte[] imageArray;
double[] dImageArray;

private void btnLoad_Click(object sender, EventArgs e)
{
    try
    {
        OpenFileDialog open = new OpenFileDialog();
        open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";

        if (open.ShowDialog() == DialogResult.OK)
        {
            pictureBox1.Image = new Bitmap(open.FileName);
            loadPic = new Bitmap(pictureBox1.Image);
        }
    }
    catch
    {
        throw new ApplicationException("Failed loading image");
    }

    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}

private void btnConvert_Click(object sender, EventArgs e)
{
    imageArray =  imageToByteArray(loadPic);
    int index = imageArray.Length;
    dImageArray = new double[index];

    for (int i = 0; i < index; i++)
    {
        dImageArray[i] = BitConverter.ToDouble(imageArray,i);
    }
}   

public byte[] imageToByteArray(Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms, ImageFormat.Gif);
    return ms.ToArray();
}
+4  A: 
BitConverter.ToDouble(byte[], int)

uses eight bytes to construct a 64-bit double, which explains your problem (once you get to the 7th to last element, there are no longer eight bytes left). I'm guessing this is not what you want to do, based on how you set up your loop.

I imagine you want something like:

for(int i = 0; i < index; i++)
{
    dImageArray[i] = (double)imageArray[i];
}

Edit - or using LINQ, just for fun:

double[] dImageArray = imageArray.Select(i => (double)i).ToArray();

On the other hand...

If BitConverter is definitely what you want, then you'll need something like:

double[] dImageArray = new double[imageArray.Length / 8];
for (int i = 0; i < dImageArray.Length; i++)
{
    dImageArray[i] = BitConverter.ToDouble(imageArray, i * 8);
}

Again, based on your code, I think the first solution is what you need.

Sapph
No, that's not it. You're using a cast, which will produce a totally different result than BitConverter.
Robert Harvey
I just clarified my post to indicate that based on his loop (and his array initialization), I don't think BitConverter is what he wants.
Sapph
Yep, I think you're right. +1
Robert Harvey
I added an alternate solution just to be safe.
Sapph
There may need to be a LERP factor in there as well, 255 byte would normally map to 1.0 for images, my guess is it would be the same for a NNetwork.
Courtney de Lautour
A: 

I think you need to back up a bit and explain what you are actually trying to do. Each BitConverter.ToDouble will convert 8 consecutive bytes into 1 double. If you start at the next position in the byte array, you are using 7 bytes that have already been used. Since each conversion will need 8 bytes, you will need to stop at Length - 7.

Anyway, you are going to end up inflating the size of the data by a factor of 8.

I think some explanation of what this is for might help you get some better answers.

Tarydon
Thank you guys for replying.what I need exactly is to create an array to use it to deal with self organizing maps neural network as an input array.to pass the image to the neural network.
Eyla
+1  A: 

class Program { static void Main(string[] args) {

        Program p = new Program();
        p.Test();
    }

    private void Test()
    {

        Image i = Image.FromFile(@"C:\a.jpg");

        Bitmap b = new Bitmap(i);

        MemoryStream ms = new MemoryStream();

        b.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);

        byte[] by = ms.ToArray();

        double[] db = new double[(int)(Math.Ceiling((double)by.Length / 8))];



        int startInterval = 1;
        int interval = 8;
        int k = 0;
        byte[] bys = new byte[8];
        int n = 1;

            for (int m = startInterval; m <= interval && m<=by.Length; m++,n++)
            {
                bys[n-1] = by[m-1];


                if (m == interval)
                {


                    db[k] = BitConverter.ToDouble(bys, 0);
                    startInterval += 8;
                    interval += 8;
                    k++;
                    n = 0;
                    Array.Clear(bys, 0, bys.Length);

                }

                if (m == by.Length)
                {
                    db[k] = BitConverter.ToDouble(bys, 0);
                }



            }





    }
}
mo-z