converting image in a clipboard to memory stream

suppose i have copied an image to clipboard and then pasted it onto a picturebox.
using:
IDataObject iDataObj=Clipboard.GetDataObject();
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
pictureBox1.Image=(Image)iDataObj.GetData(DataFormats.Bitmap);
}
in order to save this image to database. i would then have to convert the contnts of the clipboard to a memory stream object and then serialize to byte[] object.
how do we do that.
[511 byte] By [connect2sandeep] at [2007-12-16]
# 1
You are almost there. Here's the missing piece:


IDataObject iDataObj = Clipboard.GetDataObject();
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
Image image = (Image)iDataObj.GetData(DataFormats.Bitmap);
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
image.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] buffer = memStream.ToArray();
}

HTH

VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 2
An unhandled exception of type 'System.ArgumentNullException' occurred in system.drawing.dll
Additional information: Value cannot be null.
showed up when i did this.
private void contextMenuPasteImage_Click(object sender, System.EventArgs e)
{
IDataObject iDataObj=Clipboard.GetDataObject();
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
Image imgClipboard = (Image)iDataObj.GetData(DataFormats.Bitmap);//imgClipboard.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);pictureBox1.Image=(Image)iDataObj.GetData(DataFormats.Bitmap);pictureBox1.Image.Save(ms,pictureBox1.Image.RawFormat);
arrImage = ms.ToArray(); //this LINE generates the NULL REF exception byte[]==arrImage
ms.Close();
}

}
is there a problem wit image formats?

connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 3

Image.RawFormat will give you the format of the current image - I'm not sure if this is the intended usage of this property.

Try one of the static members of the ImageFormat class: Bmp, Gif, Jpeg, Png, etc.

VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 4
nope that didnt work.
the problem is when i create an image object from the clipboard. i get nothing.
private void contextMenuPasteImage_Click(object sender, System.EventArgs e)
{
IDataObject iDataObj=Clipboard.GetDataObject();
Image imgClipboard = (Image)iDataObj.GetData(DataFormats.Bitmap);
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{

pictureBox1.Image=imgClipboard;
}
picturebox is still empty when is paste the picture

connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 5
Are you sure you have something on the clipboard of type Bitmap?

1. I opened mspaint.exe
2. Drew something on the canvas
3. Made a selection
4. Copied the selection

Ran the exact same code and it works for me.

Also, you might want to move the line

Image imgClipboard = (Image)iDataObj.GetData(DataFormats.Bitmap);

into the "if" block.

VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 6
i was actually trying to update the database by pasting an image in the picturebox.
the picture appears on the picturebox but when i insert the database. the code:
arrImage=ms.GetBuffer();
arrImage=byte[]
ms=memorystream
thrown a null excpetion.
i saved the image to the memory stream using
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);arrImage=(Byte[])ms.GetBuffer();
ms.Close();
the problem is visble in some image formats.
please help
connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 7
MemoryStream.GetBuffer() will return the underlying buffer. Use ToArray() to get just the interesting portion.

Unless you haven't initialized "ms", I don't see any reason why ms.GetBuffer() should throw.

If it were to do with image formats, I would expect the Image.Save method to throw. However in my experiments, Image.Save has worked for pretty much all formats.

Also, please explain what you mean by "insert the database"

So far you've reported 3 different problems (ArgumentNullException, Picture box not showing picture and Null reference exception). It'll be nice to know if you've actually solved the other 2 problems.

Thanks

VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 8
sorry eh for my language. ihave been trying to update the database with an image field
it works pretty fine when i insert the images from a file, but i can't figure it out by pasting from the clipboard. as far as the memory stream: it is declare as
private MemoryStream ms=new MemoryStream();
in the class declaration.
does it create a problem.
kindly, please show me the code to insert image into database by pasting a picture in the picturebox. that would be veeeery helpful.
ps:
ieven tried ms.ToArray(), but i end up with the same results.
connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 9
Can you paste the code that inserts the image into your database?
VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 10
//contxmenu event haandler for pasting the picture
private void contextMenuPasteImage_Click(object sender, System.EventArgs e)
{
IDataObject iDataObj=Clipboard.GetDataObject();
Bitmap imgClipboard;
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp );
arrImage=(Byte[])ms.GetBuffer();
ms.Close();
//p/asteStat=true;
}
else
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
arrImage=(Byte[])ms.GetBuffer();
ms.Close();
}
//to determine appropriate format?

// the actual code that insert the record ito the database
private void btnInsertItems_Click(object sender, System.EventArgs e)
{
//ms=new MemoryStream();
//save picture to memory stream
/*
if (pictureBox1.Image!=null && pasteStat==false)
{
pictureBox1.Image.Save(ms, pictureBox1.Image.RawFormat);
arrImage = ms.GetBuffer();
ms.Close();
}
*/
//connection object
string sqlInsertMenu="INSERT INTO Menu (Item_Name,Description,UnitPrice,Type,Image)"+
"VALUES (@Item_Name,@Description,@UnitPrice,@Type,@Image)";
SqlConnection conn=new SqlConnection(connString);
SqlCommand cmd=new SqlCommand(sqlInsertMenu,conn);
//add paramters to the command object
try
{
cmd.Parameters.Add(new SqlParameter("@Item_Name",SqlDbType.Char,35)).Value=Convert.ToString(txtInput1.Text);
cmd.Parameters.Add(new SqlParameter("@Description",SqlDbType.Char,50)).Value=Convert.ToString(txtInput2.Text);
cmd.Parameters.Add(new SqlParameter("@UnitPrice",SqlDbType.Money,8)).Value=Convert.ToInt32(txtInput3.Text);
cmd.Parameters.Add(new SqlParameter("@Type",SqlDbType.Char,35)).Value=Convert.ToString(txtInput4.Text);
cmd.Parameters.Add(new SqlParameter("@Image",SqlDbType.Image)).Value=arrImage;
}
catch (Exception ex)
{
//exception code
MessageBox.Show(ex.Message);
}
//open the connection and insert the data
try
{
conn.Open();
cmd.ExecuteNonQuery();
MessageBox.Show("One Records inserted");
}
catch(Exception ex)
{
MessageBox.Show("An Error occured: "+ex.Message);
}
finally
{
conn.Close();
}


}

connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 11
The following code is wrong.

IDataObject iDataObj=Clipboard.GetDataObject();
Bitmap imgClipboard;
//determine the format of data
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp );
arrImage=(Byte[])ms.GetBuffer();
ms.Close();
//p/asteStat=true;
}

else
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
arrImage=(Byte[])ms.GetBuffer();
ms.Close();

}

If the clipboard doesn't have an image, you're still doing a iDataObj.GetData with DataFormats.Bitmap. This will return you a null object. The else clause is wrong and should be replaced with an Error dialog or something. Also, don't keep ms as a member, if you just want access to arrImage. And, use ToArray() instead of GetBuffer(). Try the following:


private void contextMenuPasteImage_Click(object sender, System.EventArgs e)
{
IDataObject iDataObj=Clipboard.GetDataObject();
Bitmap imgClipboard;

if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;

MemoryStream msLocal = new MemoryStream();
pictureBox1.Image.Save(msLocal, System.Drawing.Imaging.ImageFormat.Bmp);
arrImage = msLocal.ToArray();
msLocal.Close();
}
else
{
MessageBox.Show("Nothing to paste!");
}
}

VijayeRaji at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 12
i did that by creating an image object instead of a bitmap object. let me see if that works.
connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 13
there was nothing new i'd already tried it.
i figured it out why it didn't work.
try pasting the image twice. then see what happens.
finding a workaroung for this?
how to clear the memory stream?
will Flush() method work?
connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...
# 14
i figured it ou. the problem was with the memory stream.
the problem was created when saving multiple images to the clipboard and the memory stream was filled with multiple images.
solution
if there already exists image
msImage.Position=0; //sets the pointer to the first location in the stream
caution:
donot close the memory stream
i.e. remove ms.Close();
becuase we need to paste images many times.
here is the final code below. thanks for ur help guys.
//clear the picturebox
if (pictureBox1.Image!= null)
{
ms.Position=0;
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
IDataObject iDataObj=Clipboard.GetDataObject();
Bitmap imgClipboard;
//determine the format of data
try
{
if (iDataObj.GetDataPresent(DataFormats.Bitmap))
{
imgClipboard=(Bitmap)iDataObj.GetData(DataFormats.Bitmap);
pictureBox1.Image=imgClipboard;
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
arrImage=ms.ToArray();
}
else
{
MessageBox.Show("The Clipboard does not contain an image");
}
connect2sandeep at 2007-9-9 > top of Msdn Tech,Visual C#,Visual C# General...