By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,925 Members | 727 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,925 IT Pros & Developers. It's quick & easy.

Copy/Paste Image from Clipboard

P: n/a
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy. But
pasting an image from the clipboard is proving to be more difficult. These
pictureboxes are bound to an AccessDB. If the user wants to add an image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox (ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from the
clipboard. Any ideas?

TIA,
Lee
Nov 21 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Hi,

Here is a quick example. Loads the northwind databases category
names into a listbox (listbox1) and displays the image in a picture box
(picturebox1).

Dim ds As DataSet

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim strConn As String

Dim conn As SqlClient.SqlConnection

Dim daCustomer As SqlClient.SqlDataAdapter

ds = New DataSet
strConn = "Server = " + Environment.MachineName + "\VSdotNet;"

strConn &= "Database = NorthWind;"

strConn &= "Integrated Security = SSPI;"

conn = New SqlClient.SqlConnection(strConn)

daCustomer = New SqlClient.SqlDataAdapter("Select * from Categories", conn)

ds = New DataSet

daCustomer.Fill(ds, "Categories")

ListBox1.DataSource = ds.Tables("Categories")

ListBox1.DisplayMember = "CategoryName"

End Sub

Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles ListBox1.SelectedValueChanged

Dim dr As DataRow = ds.Tables("Categories").Rows(ListBox1.SelectedInde x)

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

Dim arData() As Byte = dr.Item("Picture")

ms.Write(arData, 78, arData.Length - 78)

bm = New Bitmap(ms)

PictureBox1.Image = bm

End Sub

Ken

-----------------

"lgbjr" <lg***@online.nospam> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy. But
pasting an image from the clipboard is proving to be more difficult. These
pictureboxes are bound to an AccessDB. If the user wants to add an image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox (ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from the
clipboard. Any ideas?

TIA,
Lee

Nov 21 '05 #2

P: n/a
Hi Ken,

I'm not sure whether you misunderstood what I was asking, or whether what
you've provided is way over my head (because I'm not sure I understand)!
Anyway, let me give you a bit more information:

I have a form with several pictureboxes (and other controls) that are bound
to an AccessDB. To avoid the nasty "Generic GDI+ Error", I am using the
following code to store an image in the DB:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
M_BTS.CurrentRow.Item("BTS_Pic1") = rawData
End If

To retrieve the image from the DB (save it back to disk), I'm using the
following (where pbfile is the disk file):

Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
Dim fs As FileStream
Dim bw As BinaryWriter
Dim bufferSize As Integer = 300000
Dim outbyte(300000 - 1) As Byte
Dim retval As Long
Dim startIndex As Long = 0
Dim reader As OleDbDataReader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess )
reader.Read()
fs = New FileStream(pbfile, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
startIndex = 0
retval = reader.GetBytes(0, 0, outbyte, 0, bufferSize)
bw.Write(outbyte)
bw.Flush()
bw.Close()
fs.Close()
reader.Close()

The reason I'm doing this is because if I do a pb.image.save, I get a GDI+
error.

So, now I'm able to get images in/out of the AccessDB, while displaying them
in the pictureboxes.

Now, I'm adding a context menu to the Pictureboxes to allow
open/edit/preview/copy/paste of the images. Open, edit, and preview are no
problem. when I load the form, I'm going to the registry and getting the
information for whatever programs the user's system has defined for opening,
editing, and previewing images and using that in my context menu. For the
copy, I'm doing the following:

If CM1.SourceControl Is Pic1 Then
Clipboard.SetDataObject(Pic1.Image, False)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

I can paste the contents of the clipboard to any app that supports images
(Word, Excel, Outlook, etc.).

For paste (into a picturebox), currently I'm using

If CM1.SourceControl Is Pic1 Then
M_BTS.CurrentRow.Item("BTS_PIC1") =
Clipboard.GetDataObject.GetData(DataFormats.Bitmap , True)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

This is where the problem is. If I copy an image from pb1 and paste it to
pb2, the image in the picturebox looks fine (which means that whatever data
is being put in the table is being properly translated by the picturebox).
But, if I try to open the image (save it to disk, then open it, the file is
corrupted, or at minimum, changed.

some examples:

If I store an image from a digital camera (c.jpg) in the AccessDB, then save
it to disk (c1.jpg), the file is exactly the same as the original (including
the MetaData). So, I know my method for getting images into and from the DB
is working.

If I copy an image from one pb to another pb (let's say c.jpg), update the
DB, then try to open the image (save to disk), the image is corrupted. The
original image was 1024x768x24b. The image created from the pasted data is
1024x768x32b. There is no MetaData. And only about the top 20% of the
original image exists. Additionally, the image type for the original image
is JPEG, the image from the pasted data is PNG.

For a smaller file, say 150x150x24b, all of the same corruption occurs, but
I can see the entire image.

So, I don't know if it's the way I'm copying the image to the clipboard, or
the way I'm pasting it back to my app, or some combination of both. I'm
hoping that it's only the way I'm pasting it, as I can't control the way
other apps copy images to the clipboard.

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Hi,

Here is a quick example. Loads the northwind databases category
names into a listbox (listbox1) and displays the image in a picture box
(picturebox1).

Dim ds As DataSet

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim strConn As String

Dim conn As SqlClient.SqlConnection

Dim daCustomer As SqlClient.SqlDataAdapter

ds = New DataSet
strConn = "Server = " + Environment.MachineName + "\VSdotNet;"

strConn &= "Database = NorthWind;"

strConn &= "Integrated Security = SSPI;"

conn = New SqlClient.SqlConnection(strConn)

daCustomer = New SqlClient.SqlDataAdapter("Select * from Categories",
conn)

ds = New DataSet

daCustomer.Fill(ds, "Categories")

ListBox1.DataSource = ds.Tables("Categories")

ListBox1.DisplayMember = "CategoryName"

End Sub

Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e
As
System.EventArgs) Handles ListBox1.SelectedValueChanged

Dim dr As DataRow = ds.Tables("Categories").Rows(ListBox1.SelectedInde x)

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

Dim arData() As Byte = dr.Item("Picture")

ms.Write(arData, 78, arData.Length - 78)

bm = New Bitmap(ms)

PictureBox1.Image = bm

End Sub

Ken

-----------------

"lgbjr" <lg***@online.nospam> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy. But
pasting an image from the clipboard is proving to be more difficult. These
pictureboxes are bound to an AccessDB. If the user wants to add an image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox (ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from the
clipboard. Any ideas?

TIA,
Lee

Nov 21 '05 #3

P: n/a
Hi,

You dont need to use the clipboard to display an image stored in an
database. Here are two functions to convert an image to and from a format
you can save in a database. Storeimage converts image to binary format.
ConvertToBitmap converts it back. Note the offset for the northwind database
is 78 my storeimage function has a offset of 0. Once you have converted the
image into a bitmap you can use bitmap.save to store the image.

Private Function StoreImage(ByVal bm As Bitmap) As Object

Dim ms As New MemoryStream

Try

bm.Save(ms, Imaging.ImageFormat.Jpeg)

Return ms.GetBuffer

Catch

Return Convert.DBNull

End Try

End Function

Private Function ConvertToBitmap(ByVal data() As Byte, ByVal offset As
Integer) As Bitmap

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

ms = New MemoryStream

ms.Write(data, offset, data.Length - offset)

bm = New Bitmap(ms)

Return bm

End Function

Bitmap save
http://msdn.microsoft.com/library/de...ssavetopic.asp

http://support.microsoft.com/default...b;en-us;818410

Picture box control that I overloaded to support binding to a database.
http://www.gotdotnet.com/Community/U...3-c664ae2f91f8
Ken

----------------------
"lgbjr" <lg***@online.nospam> wrote in message
news:eX****************@TK2MSFTNGP09.phx.gbl...
Hi Ken,

I'm not sure whether you misunderstood what I was asking, or whether what
you've provided is way over my head (because I'm not sure I understand)!
Anyway, let me give you a bit more information:

I have a form with several pictureboxes (and other controls) that are bound
to an AccessDB. To avoid the nasty "Generic GDI+ Error", I am using the
following code to store an image in the DB:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
M_BTS.CurrentRow.Item("BTS_Pic1") = rawData
End If

To retrieve the image from the DB (save it back to disk), I'm using the
following (where pbfile is the disk file):

Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
Dim fs As FileStream
Dim bw As BinaryWriter
Dim bufferSize As Integer = 300000
Dim outbyte(300000 - 1) As Byte
Dim retval As Long
Dim startIndex As Long = 0
Dim reader As OleDbDataReader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess )
reader.Read()
fs = New FileStream(pbfile, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
startIndex = 0
retval = reader.GetBytes(0, 0, outbyte, 0, bufferSize)
bw.Write(outbyte)
bw.Flush()
bw.Close()
fs.Close()
reader.Close()

The reason I'm doing this is because if I do a pb.image.save, I get a GDI+
error.

So, now I'm able to get images in/out of the AccessDB, while displaying them
in the pictureboxes.

Now, I'm adding a context menu to the Pictureboxes to allow
open/edit/preview/copy/paste of the images. Open, edit, and preview are no
problem. when I load the form, I'm going to the registry and getting the
information for whatever programs the user's system has defined for opening,
editing, and previewing images and using that in my context menu. For the
copy, I'm doing the following:

If CM1.SourceControl Is Pic1 Then
Clipboard.SetDataObject(Pic1.Image, False)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

I can paste the contents of the clipboard to any app that supports images
(Word, Excel, Outlook, etc.).

For paste (into a picturebox), currently I'm using

If CM1.SourceControl Is Pic1 Then
M_BTS.CurrentRow.Item("BTS_PIC1") =
Clipboard.GetDataObject.GetData(DataFormats.Bitmap , True)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

This is where the problem is. If I copy an image from pb1 and paste it to
pb2, the image in the picturebox looks fine (which means that whatever data
is being put in the table is being properly translated by the picturebox).
But, if I try to open the image (save it to disk, then open it, the file is
corrupted, or at minimum, changed.

some examples:

If I store an image from a digital camera (c.jpg) in the AccessDB, then save
it to disk (c1.jpg), the file is exactly the same as the original (including
the MetaData). So, I know my method for getting images into and from the DB
is working.

If I copy an image from one pb to another pb (let's say c.jpg), update the
DB, then try to open the image (save to disk), the image is corrupted. The
original image was 1024x768x24b. The image created from the pasted data is
1024x768x32b. There is no MetaData. And only about the top 20% of the
original image exists. Additionally, the image type for the original image
is JPEG, the image from the pasted data is PNG.

For a smaller file, say 150x150x24b, all of the same corruption occurs, but
I can see the entire image.

So, I don't know if it's the way I'm copying the image to the clipboard, or
the way I'm pasting it back to my app, or some combination of both. I'm
hoping that it's only the way I'm pasting it, as I can't control the way
other apps copy images to the clipboard.

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Hi,

Here is a quick example. Loads the northwind databases category
names into a listbox (listbox1) and displays the image in a picture box
(picturebox1).

Dim ds As DataSet

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim strConn As String

Dim conn As SqlClient.SqlConnection

Dim daCustomer As SqlClient.SqlDataAdapter

ds = New DataSet
strConn = "Server = " + Environment.MachineName + "\VSdotNet;"

strConn &= "Database = NorthWind;"

strConn &= "Integrated Security = SSPI;"

conn = New SqlClient.SqlConnection(strConn)

daCustomer = New SqlClient.SqlDataAdapter("Select * from Categories",
conn)

ds = New DataSet

daCustomer.Fill(ds, "Categories")

ListBox1.DataSource = ds.Tables("Categories")

ListBox1.DisplayMember = "CategoryName"

End Sub

Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e
As
System.EventArgs) Handles ListBox1.SelectedValueChanged

Dim dr As DataRow = ds.Tables("Categories").Rows(ListBox1.SelectedInde x)

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

Dim arData() As Byte = dr.Item("Picture")

ms.Write(arData, 78, arData.Length - 78)

bm = New Bitmap(ms)

PictureBox1.Image = bm

End Sub

Ken

-----------------

"lgbjr" <lg***@online.nospam> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy. But
pasting an image from the clipboard is proving to be more difficult. These
pictureboxes are bound to an AccessDB. If the user wants to add an image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox (ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from the
clipboard. Any ideas?

TIA,
Lee


Nov 21 '05 #4

P: n/a
Ken,

Again, thanks for the reply, but also again, I think there's a
misunderstanding. Maybe I'm just not being clear about what I am having
trouble with, or I'm too dense to understand what your saying!

I understand that I don't "need" the clipboard for displaying images from a
DB. If the user wants to place an image in the DB, they click an
open image button and using the code from the previous post, I stream the
image into the DB. Once it's there, the picturebox displays it.

If the user wants to retrieve a copy of an image in the DB (ie. a disk
file), they click a save to disk button and I use the code in the previous
post to stream the image to a disk file. If the original image had MetaData
associated with it, the image that is saved to disk has the same MetaData.

Both of these work with no problems.

Now, if the user doesn't want/need a disk file, but wants to place a copy of
one
of the images in the DB in another app (let's say a Word Document), again, I
use the code from the previous post (in a context menu) to put a copy of the
image from the picturebox (not from the DB) onto the clipboard. The user
goes to the target app and clicks paste. I understand that in this case, any
MetaData associated with the image is not included on the clipboard (which
is ok). I actually used the info from
http://support.microsoft.com/default...b;en-us;818410 to verify
that what I'm copying to the clipboard is a valid image (by saving the
contents of the clipboard to a file. The saved image file is exactly the
same as the original image file (minus any MetaData)

So, This also works with no problems.

If the user wants to add an image to the DB and there isn't an image file,
ie.
they want to copy an image from another App (again, let's say Word), and
paste it into a picturebox, using the code in my previous post, I'm pasting
the contents of the clipboard into the DB. This is where the problem is.
Whether I paste the image directly to the picturebox
(Pic1.Image=Clipboard.GetDataObject.GetData(DataFo rmats.Bitmap, True)) or
paste the image directly to the table as shown in the code below, the image
is corrupted (See previous post for description of corrupted images). I've
also tried setting the AutoConvert flag to False for both methods. Same
problem.

I'm assuming that I need to do something similar to how I store an image in
the DB from disk. I use a filestream to fill a byte array, then store the
byte array directly to the DB, then let the picturebox display the image
from the DB, rather than using Pic1.Image=Image.Fromfile and letting the
picturebox store the image to the DB. The later method causes GDI+ errors if
I subsequently try to save the image from the DB to a file.

So, I guess what I need to know is how to get the contents of the clipboard
into a byte array, so I can store the byte array directly to the DB, and
then let the picbox display the image.

Sorry for any previous confusion!

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:OF**************@TK2MSFTNGP12.phx.gbl...
Hi,

You dont need to use the clipboard to display an image stored in an
database. Here are two functions to convert an image to and from a format
you can save in a database. Storeimage converts image to binary format.
ConvertToBitmap converts it back. Note the offset for the northwind
database
is 78 my storeimage function has a offset of 0. Once you have converted
the
image into a bitmap you can use bitmap.save to store the image.

Private Function StoreImage(ByVal bm As Bitmap) As Object

Dim ms As New MemoryStream

Try

bm.Save(ms, Imaging.ImageFormat.Jpeg)

Return ms.GetBuffer

Catch

Return Convert.DBNull

End Try

End Function

Private Function ConvertToBitmap(ByVal data() As Byte, ByVal offset As
Integer) As Bitmap

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

ms = New MemoryStream

ms.Write(data, offset, data.Length - offset)

bm = New Bitmap(ms)

Return bm

End Function

Bitmap save
http://msdn.microsoft.com/library/de...ssavetopic.asp

http://support.microsoft.com/default...b;en-us;818410

Picture box control that I overloaded to support binding to a database.
http://www.gotdotnet.com/Community/U...3-c664ae2f91f8
Ken

----------------------
"lgbjr" <lg***@online.nospam> wrote in message
news:eX****************@TK2MSFTNGP09.phx.gbl...
Hi Ken,

I'm not sure whether you misunderstood what I was asking, or whether what
you've provided is way over my head (because I'm not sure I understand)!
Anyway, let me give you a bit more information:

I have a form with several pictureboxes (and other controls) that are
bound
to an AccessDB. To avoid the nasty "Generic GDI+ Error", I am using the
following code to store an image in the DB:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
M_BTS.CurrentRow.Item("BTS_Pic1") = rawData
End If

To retrieve the image from the DB (save it back to disk), I'm using the
following (where pbfile is the disk file):

Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
Dim fs As FileStream
Dim bw As BinaryWriter
Dim bufferSize As Integer = 300000
Dim outbyte(300000 - 1) As Byte
Dim retval As Long
Dim startIndex As Long = 0
Dim reader As OleDbDataReader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess )
reader.Read()
fs = New FileStream(pbfile, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
startIndex = 0
retval = reader.GetBytes(0, 0, outbyte, 0, bufferSize)
bw.Write(outbyte)
bw.Flush()
bw.Close()
fs.Close()
reader.Close()

The reason I'm doing this is because if I do a pb.image.save, I get a GDI+
error.

So, now I'm able to get images in/out of the AccessDB, while displaying
them
in the pictureboxes.

Now, I'm adding a context menu to the Pictureboxes to allow
open/edit/preview/copy/paste of the images. Open, edit, and preview are no
problem. when I load the form, I'm going to the registry and getting the
information for whatever programs the user's system has defined for
opening,
editing, and previewing images and using that in my context menu. For the
copy, I'm doing the following:

If CM1.SourceControl Is Pic1 Then
Clipboard.SetDataObject(Pic1.Image, False)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

I can paste the contents of the clipboard to any app that supports images
(Word, Excel, Outlook, etc.).

For paste (into a picturebox), currently I'm using

If CM1.SourceControl Is Pic1 Then
M_BTS.CurrentRow.Item("BTS_PIC1") =
Clipboard.GetDataObject.GetData(DataFormats.Bitmap , True)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

This is where the problem is. If I copy an image from pb1 and paste it to
pb2, the image in the picturebox looks fine (which means that whatever
data
is being put in the table is being properly translated by the picturebox).
But, if I try to open the image (save it to disk, then open it, the file
is
corrupted, or at minimum, changed.

some examples:

If I store an image from a digital camera (c.jpg) in the AccessDB, then
save
it to disk (c1.jpg), the file is exactly the same as the original
(including
the MetaData). So, I know my method for getting images into and from the
DB
is working.

If I copy an image from one pb to another pb (let's say c.jpg), update the
DB, then try to open the image (save to disk), the image is corrupted. The
original image was 1024x768x24b. The image created from the pasted data is
1024x768x32b. There is no MetaData. And only about the top 20% of the
original image exists. Additionally, the image type for the original image
is JPEG, the image from the pasted data is PNG.

For a smaller file, say 150x150x24b, all of the same corruption occurs,
but
I can see the entire image.

So, I don't know if it's the way I'm copying the image to the clipboard,
or
the way I'm pasting it back to my app, or some combination of both. I'm
hoping that it's only the way I'm pasting it, as I can't control the way
other apps copy images to the clipboard.

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Hi,

Here is a quick example. Loads the northwind databases category
names into a listbox (listbox1) and displays the image in a picture box
(picturebox1).

Dim ds As DataSet

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim strConn As String

Dim conn As SqlClient.SqlConnection

Dim daCustomer As SqlClient.SqlDataAdapter

ds = New DataSet
strConn = "Server = " + Environment.MachineName + "\VSdotNet;"

strConn &= "Database = NorthWind;"

strConn &= "Integrated Security = SSPI;"

conn = New SqlClient.SqlConnection(strConn)

daCustomer = New SqlClient.SqlDataAdapter("Select * from Categories",
conn)

ds = New DataSet

daCustomer.Fill(ds, "Categories")

ListBox1.DataSource = ds.Tables("Categories")

ListBox1.DisplayMember = "CategoryName"

End Sub

Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal e
As
System.EventArgs) Handles ListBox1.SelectedValueChanged

Dim dr As DataRow = ds.Tables("Categories").Rows(ListBox1.SelectedInde x)

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

Dim arData() As Byte = dr.Item("Picture")

ms.Write(arData, 78, arData.Length - 78)

bm = New Bitmap(ms)

PictureBox1.Image = bm

End Sub

Ken

-----------------

"lgbjr" <lg***@online.nospam> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy.
But
pasting an image from the clipboard is proving to be more difficult.
These
pictureboxes are bound to an AccessDB. If the user wants to add an image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox
(ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some
reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from the
clipboard. Any ideas?

TIA,
Lee



Nov 21 '05 #5

P: n/a
lgbjr,

I did not check it, however probably is what you are looking in an object.

Why don't you set a breakpoint there (after) the point you have that object.

Open the quickwatch and sees how that image (most probably a byte array) is
stored in that object?

That is the way I would do this.

I hope this gives some ideas?

Cor
Nov 21 '05 #6

P: n/a
Ken,

You can ignore my last post. I was obviously too dense to understand what
you were trying to say. I used the storeimage function and passed it the
contents of the clipboard, then saved the return value to the DB. Works
fine!!

Thanks!!

Lee

"lgbjr" <lg***@online.nospam> wrote in message
news:uI**************@TK2MSFTNGP14.phx.gbl...
Ken,

Again, thanks for the reply, but also again, I think there's a
misunderstanding. Maybe I'm just not being clear about what I am having
trouble with, or I'm too dense to understand what your saying!

I understand that I don't "need" the clipboard for displaying images from
a
DB. If the user wants to place an image in the DB, they click an
open image button and using the code from the previous post, I stream the
image into the DB. Once it's there, the picturebox displays it.

If the user wants to retrieve a copy of an image in the DB (ie. a disk
file), they click a save to disk button and I use the code in the previous
post to stream the image to a disk file. If the original image had
MetaData associated with it, the image that is saved to disk has the same
MetaData.

Both of these work with no problems.

Now, if the user doesn't want/need a disk file, but wants to place a copy
of one
of the images in the DB in another app (let's say a Word Document), again,
I
use the code from the previous post (in a context menu) to put a copy of
the image from the picturebox (not from the DB) onto the clipboard. The
user goes to the target app and clicks paste. I understand that in this
case, any MetaData associated with the image is not included on the
clipboard (which is ok). I actually used the info from
http://support.microsoft.com/default...b;en-us;818410 to verify
that what I'm copying to the clipboard is a valid image (by saving the
contents of the clipboard to a file. The saved image file is exactly the
same as the original image file (minus any MetaData)

So, This also works with no problems.

If the user wants to add an image to the DB and there isn't an image file,
ie.
they want to copy an image from another App (again, let's say Word), and
paste it into a picturebox, using the code in my previous post, I'm
pasting
the contents of the clipboard into the DB. This is where the problem is.
Whether I paste the image directly to the picturebox
(Pic1.Image=Clipboard.GetDataObject.GetData(DataFo rmats.Bitmap, True)) or
paste the image directly to the table as shown in the code below, the
image
is corrupted (See previous post for description of corrupted images). I've
also tried setting the AutoConvert flag to False for both methods. Same
problem.

I'm assuming that I need to do something similar to how I store an image
in the DB from disk. I use a filestream to fill a byte array, then store
the byte array directly to the DB, then let the picturebox display the
image from the DB, rather than using Pic1.Image=Image.Fromfile and letting
the picturebox store the image to the DB. The later method causes GDI+
errors if I subsequently try to save the image from the DB to a file.

So, I guess what I need to know is how to get the contents of the
clipboard into a byte array, so I can store the byte array directly to the
DB, and then let the picbox display the image.

Sorry for any previous confusion!

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:OF**************@TK2MSFTNGP12.phx.gbl...
Hi,

You dont need to use the clipboard to display an image stored in
an
database. Here are two functions to convert an image to and from a
format
you can save in a database. Storeimage converts image to binary format.
ConvertToBitmap converts it back. Note the offset for the northwind
database
is 78 my storeimage function has a offset of 0. Once you have converted
the
image into a bitmap you can use bitmap.save to store the image.

Private Function StoreImage(ByVal bm As Bitmap) As Object

Dim ms As New MemoryStream

Try

bm.Save(ms, Imaging.ImageFormat.Jpeg)

Return ms.GetBuffer

Catch

Return Convert.DBNull

End Try

End Function

Private Function ConvertToBitmap(ByVal data() As Byte, ByVal offset As
Integer) As Bitmap

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

ms = New MemoryStream

ms.Write(data, offset, data.Length - offset)

bm = New Bitmap(ms)

Return bm

End Function

Bitmap save
http://msdn.microsoft.com/library/de...ssavetopic.asp

http://support.microsoft.com/default...b;en-us;818410

Picture box control that I overloaded to support binding to a database.
http://www.gotdotnet.com/Community/U...3-c664ae2f91f8
Ken

----------------------
"lgbjr" <lg***@online.nospam> wrote in message
news:eX****************@TK2MSFTNGP09.phx.gbl...
Hi Ken,

I'm not sure whether you misunderstood what I was asking, or whether what
you've provided is way over my head (because I'm not sure I understand)!
Anyway, let me give you a bit more information:

I have a form with several pictureboxes (and other controls) that are
bound
to an AccessDB. To avoid the nasty "Generic GDI+ Error", I am using the
following code to store an image in the DB:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
M_BTS.CurrentRow.Item("BTS_Pic1") = rawData
End If

To retrieve the image from the DB (save it back to disk), I'm using the
following (where pbfile is the disk file):

Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
Dim fs As FileStream
Dim bw As BinaryWriter
Dim bufferSize As Integer = 300000
Dim outbyte(300000 - 1) As Byte
Dim retval As Long
Dim startIndex As Long = 0
Dim reader As OleDbDataReader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess )
reader.Read()
fs = New FileStream(pbfile, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
startIndex = 0
retval = reader.GetBytes(0, 0, outbyte, 0, bufferSize)
bw.Write(outbyte)
bw.Flush()
bw.Close()
fs.Close()
reader.Close()

The reason I'm doing this is because if I do a pb.image.save, I get a
GDI+
error.

So, now I'm able to get images in/out of the AccessDB, while displaying
them
in the pictureboxes.

Now, I'm adding a context menu to the Pictureboxes to allow
open/edit/preview/copy/paste of the images. Open, edit, and preview are
no
problem. when I load the form, I'm going to the registry and getting the
information for whatever programs the user's system has defined for
opening,
editing, and previewing images and using that in my context menu. For the
copy, I'm doing the following:

If CM1.SourceControl Is Pic1 Then
Clipboard.SetDataObject(Pic1.Image, False)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

I can paste the contents of the clipboard to any app that supports images
(Word, Excel, Outlook, etc.).

For paste (into a picturebox), currently I'm using

If CM1.SourceControl Is Pic1 Then
M_BTS.CurrentRow.Item("BTS_PIC1") =
Clipboard.GetDataObject.GetData(DataFormats.Bitmap , True)
ElseIf CM1.SourceControl Is Pic2 Then
etc.

This is where the problem is. If I copy an image from pb1 and paste it to
pb2, the image in the picturebox looks fine (which means that whatever
data
is being put in the table is being properly translated by the
picturebox).
But, if I try to open the image (save it to disk, then open it, the file
is
corrupted, or at minimum, changed.

some examples:

If I store an image from a digital camera (c.jpg) in the AccessDB, then
save
it to disk (c1.jpg), the file is exactly the same as the original
(including
the MetaData). So, I know my method for getting images into and from the
DB
is working.

If I copy an image from one pb to another pb (let's say c.jpg), update
the
DB, then try to open the image (save to disk), the image is corrupted.
The
original image was 1024x768x24b. The image created from the pasted data
is
1024x768x32b. There is no MetaData. And only about the top 20% of the
original image exists. Additionally, the image type for the original
image
is JPEG, the image from the pasted data is PNG.

For a smaller file, say 150x150x24b, all of the same corruption occurs,
but
I can see the entire image.

So, I don't know if it's the way I'm copying the image to the clipboard,
or
the way I'm pasting it back to my app, or some combination of both. I'm
hoping that it's only the way I'm pasting it, as I can't control the way
other apps copy images to the clipboard.

TIA,
Lee

"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Hi,

Here is a quick example. Loads the northwind databases category
names into a listbox (listbox1) and displays the image in a picture box
(picturebox1).

Dim ds As DataSet

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim strConn As String

Dim conn As SqlClient.SqlConnection

Dim daCustomer As SqlClient.SqlDataAdapter

ds = New DataSet
strConn = "Server = " + Environment.MachineName + "\VSdotNet;"

strConn &= "Database = NorthWind;"

strConn &= "Integrated Security = SSPI;"

conn = New SqlClient.SqlConnection(strConn)

daCustomer = New SqlClient.SqlDataAdapter("Select * from Categories",
conn)

ds = New DataSet

daCustomer.Fill(ds, "Categories")

ListBox1.DataSource = ds.Tables("Categories")

ListBox1.DisplayMember = "CategoryName"

End Sub

Private Sub ListBox1_SelectedValueChanged(ByVal sender As Object, ByVal
e
As
System.EventArgs) Handles ListBox1.SelectedValueChanged

Dim dr As DataRow = ds.Tables("Categories").Rows(ListBox1.SelectedInde x)

Dim ms As New System.IO.MemoryStream

Dim bm As Bitmap

Dim arData() As Byte = dr.Item("Picture")

ms.Write(arData, 78, arData.Length - 78)

bm = New Bitmap(ms)

PictureBox1.Image = bm

End Sub

Ken

-----------------

"lgbjr" <lg***@online.nospam> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hello All,

Im using a context menu associated with some pictureboxes to provide
copy/paste functionality. Copying the image to the clipboard was easy.
But
pasting an image from the clipboard is proving to be more difficult.
These
pictureboxes are bound to an AccessDB. If the user wants to add an
image,
they select an image using an OpenFileDialog:

Dim result As DialogResult = Pic_Sel.ShowDialog()
If (result = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(Pic_Sel.FileName, FileMode.Open,
FileAccess.Read)
Dim rawData() As Byte = New Byte(fs.Length) {}
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
Table.CurrentRow.Item("Pic1") = rawData
End If

As you can see, I'm not placing the image directly into the picturebox
(ie
PB1.image=image.fromfile). I'm putting the image directly into the data
table, then letting the picturebox update from the table. For some
reason,
if I place the image directly into the picturebox and let the picturebox
update the table, I get a GDI+ error if I try to save the image from the
table back to a file.

Anyway, I need to do something similar when I do a GetDataObject from
the
clipboard. Any ideas?

TIA,
Lee



Nov 21 '05 #7

P: n/a
Hi Cor,

Thanks for the idea. I was actually in the process of setting breakpoints
and trying to look at the byte array when I got the post from Ken. At first,
I didn't grasp what he was saying, so I sent another post trying to explain
again what I was trying to do. then I took a 5 minute coffee break! when I
sat back down in front of the computer and thought about it, I realized that
Ken sent me the answer I was looking for. I was just to dense to see it when
I first read his post. So, all's well now.

To retrieve an image that's been placed on the clipboard directly to the DB:

Table.CurrentRow.Item("Pic1")=StoreImage(Clipboard .GetDataObject.GetData(DataFormats.Bitmap,
False))

Works like a charm!

cheers,
Lee

"Cor Ligthert" <no************@planet.nl> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
lgbjr,

I did not check it, however probably is what you are looking in an object.

Why don't you set a breakpoint there (after) the point you have that
object.

Open the quickwatch and sees how that image (most probably a byte array)
is stored in that object?

That is the way I would do this.

I hope this gives some ideas?

Cor

Nov 21 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.