0

I'm using this code to save a file to memory stream

using System.Drawing.Imaging;

Dictionary<string,MemoryStream> dict = new Dictionary<string,MemoryStream>();

dict.Add("mypicture.png",new MemoryStream());

bmp.Save(dict["mypicture.png"], ImageFormat.Bmp);

After that I have a function that accepts this file name

result = DrawMatches.Draw("box.png", "mypicture.png", out matchTime,i);

Am I accessing the file from a memory stream correctly? in the function it's saying

invalid argument

I think I'm not accessing the file in a correct way from the memory stream

this is the Drawmatches.Draw:

public static Image<Bgr, Byte> Draw(String modelImageFileName, String observedImageFileName, out long matchTime,int i)
{
   Image<Gray, Byte> modelImage = new Image<Gray, byte>(modelImageFileName);
   Image<Gray, Byte> observedImage = new Image<Gray, byte>(observedImageFileName);
}

error is not in compilation, it is when running

it says " parameter is not valid " and points to the observedimage

Kami
  • 19,134
  • 4
  • 51
  • 63

1 Answers1

1

I'm not really sure what the Image<Gray, byte> class is and how it is implemented, but you're passing a string to its constructor - are you sure that this is correct? (EDIT: Just found out it is part of the EMGU implementation). I'll show you how you'd normally create an image from the stream:

MemoryStream ms = dict["mypicture.png"]; // This gives you the memory stream from the dictionary
ms.Seek(0, SeekOrigin.Begin); // Go to the beginning of the stream
Bitmap bmp = new Bitmap(ms); // Create image from the stream

Now I suspect you want to create a new "emgu image" from the stream you have using the following constructor:

Image<Bgr, Byte> img1 = new Image<Bgr, Byte>("MyImage.jpg");

Which is - according to the EMGU documentation - supposed to read an image from a file. You don't have a file named "mypicture.png", you have a stream within a dictionary under the key "mypicture.png", which is something totally different. I doubt that the Image<t1, t2> class is able to read from a stream - at least I didn't see anything like that in the docs.

What you need to call is (using the code I provided above):

Image<Gray, Byte> img1 = new Image<Gray, Byte>(bmp);

All that being said, the code for the Draw method (which then can't be static, by the way) should read like this:

private Bitmap GetBitmapFromStream(String bitmapKeyName)
{
    MemoryStream ms = dict[bitmapKeyName];
    ms.Seek(0, SeekOrigin.Begin);
    return new Bitmap(ms);
}

public Image<Bgr, Byte> Draw(String modelImageFileName, String observedImageFileName, out long matchTime,int i)
{
   Image<Gray, Byte> modelImage = new Image<Gray, byte>(GetBitmapFromStream(modelImageFileName));
   Image<Gray, Byte> observedImage = new Image<Gray, byte>(GetBitmapFromStream(observedImageFileName));
}

EDIT
In the comments below you say that you want to reduce the processing time by saving the bitmaps into a memory stream instead of writing to the disk.

I need to ask you the following: Why do you do that in the first place? I notice from the code you posted above that obviously you already have a Bitmap which you save into the memory stream. Why don't you put the bitmap itself into the dictionary?

Dictionary<string, Bitmap> dict = new Dictionary<string, Bitmap>();
dict.Add("mypicture.png", bmp);

Then you could retrieve it right away with even less time being wasted for storing and reading the image from the stream. The Draw method then would read:

public Image<Bgr, Byte> Draw(String modelImageFileName, String observedImageFileName, out long matchTime,int i)
{
   Image<Gray, Byte> modelImage = new Image<Gray, byte>(dict[modelImageFileName);
   Image<Gray, Byte> observedImage = new Image<Gray, byte>(dict[observedImageFileName]);
}
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • thanks so much thorsten but you know, my function only accepts the file name and i want to call the file directly from the memory stream i dont want to make it a file bcoz im doing image processing and turning into file and saving it to the disk is going to take time which i dont want so how can i call directly from ram ? by file name – Mahmood Shahin Feb 06 '13 at 13:17
  • please how can i talk to you ? – Mahmood Shahin Feb 06 '13 at 13:18
  • You can not "call a file directly from a memory stream". A file is a file and a memory stream is an area in the computer's memory. If your function only accepts names of files on the hard disk, then you need to create a file on the hard disk. Also, I've shown you the code you can use to access to create EMGU images from a memory stream. Doesn't that work? – Thorsten Dittmar Feb 06 '13 at 13:28
  • Well actually i could have done this without the memory stream ill save to the disk, then enter the file to the function but when processing 100 images , it takes alot of time to save 100 images to disk and it takes less time to save 100 images to ram ( i suppose ?) thats why im trying to use the memory stream my goal is to reduce the processing time , and saving 100 images takes alot of time , and time is important in my application how can i solve this problem ? – Mahmood Shahin Feb 06 '13 at 13:33
  • I've edited my answer. Fact is: what you're asking can simply not be done the way you implemented it. Period. The constructor for `Image` expects either a `Bitmap` or the file name of an image file - a **file** name, not the string key of a stream in a dictionary. How in the world should the constructor know that it is supposed to access your dictionary (which it can't by the way) and get the stream? – Thorsten Dittmar Feb 06 '13 at 13:47