Bitmap from Clipboard back to Clipboard as PNG?

J

Joe Duchtel

Hello -

I have the following code to get a bitmap from the clipboard and to
save it to a *.png file ...

Dim lData As IDataObject = Clipboard.GetDataObject()

If lData.GetDataPresent(DataFormats.Bitmap) Then
Dim lPictureBox As New PictureBox

lPictureBox.Image = lData.GetData(DataFormats.Bitmap,
True)
lPictureBox.Image.Save("Test.png",
System.Drawing.Imaging.ImageFormat.Png)
End If

How can I take the Image and put it back onto the Clipboard as a Png?
I found the Clipboard.SetDataObject() function but how can I use the
PictureBox or Image to convert it into a format that can be used by
SetDataObject()?

Thanks!
Joe
 
K

kimiraikkonen

Hello -

I have the following code to get a bitmap from the clipboard and to
save it to a *.png file ...

        Dim lData As IDataObject = Clipboard.GetDataObject()

        If lData.GetDataPresent(DataFormats.Bitmap) Then
            Dim lPictureBox As New PictureBox

            lPictureBox.Image = lData.GetData(DataFormats.Bitmap,
True)
            lPictureBox.Image.Save("Test.png",
System.Drawing.Imaging.ImageFormat.Png)
        End If

How can I take the Image and put it back onto the Clipboard as a Png?
I found the Clipboard.SetDataObject() function but how can I use the
PictureBox or Image to convert it into a format that can be used by
SetDataObject()?

Thanks!
Joe

To retrieve image from clipboard, have you considered using:

' Assuming your picturebox's name is "lPictureBox"
lPictureBox.Image = Clipboard.GetImage

' Save now in PNG format
lPictureBox.Image.Save("Test.png",
System.Drawing.Imaging.ImageFormat.Png)

.... and

' To add image to clipboard
Clipboard.SetImage(lPictureBox.Image)


Thanks,

Onur Güzel
 
J

Joe Duchtel

Hello -

I have .NET 1.1 and Visual Studio 2003 and there is no GetImage and
SetImage function of Clipboard.

Thanks,
Joe
 
K

kimiraikkonen

Hello -

I have .NET 1.1 and Visual Studio 2003 and there is no GetImage and
SetImage function of Clipboard.

Thanks,
Joe

Sorry, there are in .NET 2.0. I don't know if they're not present in
VS 2003 / .NET 1.1

So try this to copy image to clipboard as you say SetDataObject exists
in .NET 1.1:

Dim myimage As Object = lPictureBox.Image
Clipboard.SetDataObject(myimage)

Thanks,

Onur Güzel
 
J

Joe Duchtel

Hello -

The snipped you gave me will compile and run but the Clipboard tells
me that the "ClipBook Viewer cannot display the information in its
current format or there is not enough memory ...". I cannot paste it
into anything either.

I think that the Image is in some raw format that needs to be
converted to a *.png. It works with the Image.Save but I have found
no other way to convert the format.

Thanks,
Joe
 
K

kimiraikkonen

Hello -

The snipped you gave me will compile and run but the Clipboard tells
me that the "ClipBook Viewer cannot display the information in its
current format or there is not enough memory ...". I cannot paste it
into anything either.

I think that the Image is in some raw format that needs to be
converted to a *.png. It works with the Image.Save but I have found
no other way to convert the format.

Thanks,
Joe

Hi,
With the code i posted using SetDataObject, i ran it for once or more
it worked. Then it gave error when i try to paste onto Paint, after re-
creating project or changing picturebox name or re-launching
application it worked and image pasted to Paint with NO problem.

Anyway, SetImage method in .NET 2.0 never did this behaviour. So i
cannot say a certain thing on the issue and you may consider upgrading
to 2.0 at least.

Thanks,

Onur Güzel
 
K

kimiraikkonen

Hello -

The snipped you gave me will compile and run but the Clipboard tells
me that the "ClipBook Viewer cannot display the information in its
current format or there is not enough memory ...". I cannot paste it
into anything either.

I think that the Image is in some raw format that needs to be
converted to a *.png. It works with the Image.Save but I have found
no other way to convert the format.

Thanks,
Joe

.. or you can simply try to use:

Clipboard.SetDataObject(lPictureBox.Image)

...and see if it does not result with errors anylonger.

Hope this helps,

Onur Güzel
 
J

Joe Duchtel

Hello -

I actually did try the Clipboard.SetDataObject(lPictureBox.Image)
without using an Object and it is still not working.

Thanks,
Joe
 
K

kimiraikkonen

Hello -

I actually did try the Clipboard.SetDataObject(lPictureBox.Image)
without using an Object and it is still not working.

Thanks,
Joe

Which step is not working? Pasting to somewhere?

I was able to paste a image to Clipboard Viewer and mspaint (Paint)
after copying image to the clipboard.
Clipboard.SetDataObject(lPictureBox.Image) and make sure your
picturebox has a picture that'll be copied to the clipboard as well.

Thanks,

Onur Güzel
 
J

Joe Duchtel

Hello -

I use the Clipboard.SetDataObject(lPictureBox.Image) and get an "Error
getting the Clipboard Data!" when I try to paste it into Paint.

I also used the debugger to make sure that the lPictureBox.Image is
not Nothing and contains something.

Thanks,
Joachim
 
M

Michael Phillips, Jr.

How can I take the Image and put it back onto the Clipboard as a Png?

1) Create a MemoryStream object
2) Save your image to the stream encoded as a Png
Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
3) Create a new DataObject
4) Use SetData("PNG", false, ms) to embed the encoded png memory stream into
the dataObject
5) Use Clipboard.SetDataObject(dataObject, false) to place the dataObject on
the clipboard
 
J

Joe Duchtel

Hello -

Thanks a lot for your feedback!

I tried the following ...

Dim lMemoryStream As New MemoryStream

lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Png)

Dim lDataObject As New DataObject

lDataObject.SetData("PNG", False, lMemoryStream)

Clipboard.SetDataObject(lDataObject)

... but I still get the "ClipBook Viewer cannot display the
information in its current format ..." message and cannot past
anything into Paint or Word.

The lImage.Save() to a file works just fine ...

Thanks!
Joe
 
M

Michael Phillips, Jr.

... but I still get the "ClipBook Viewer cannot display the
information in its current format ..." message and cannot past
anything into Paint or Word.

The Windows ClipBook Viewer is old. It was never updated to recognize the
"PNG" format.

MSPaint does not recognize the "PNG" format either.

However, Microsoft Office 2007 does recognize the "PNG" format.

You must select "Paste Special" on the menu. You will then be presented
with a "Paste Special" dialog box will show all of the formats presented on
the clipboard. Your "PNG" image will be available on the clipboard. Once
selected, it will appear in the document.


Hello -

Thanks a lot for your feedback!

I tried the following ...

Dim lMemoryStream As New MemoryStream

lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Png)

Dim lDataObject As New DataObject

lDataObject.SetData("PNG", False, lMemoryStream)

Clipboard.SetDataObject(lDataObject)

.... but I still get the "ClipBook Viewer cannot display the
information in its current format ..." message and cannot past
anything into Paint or Word.

The lImage.Save() to a file works just fine ...

Thanks!
Joe
 
J

Joe Duchtel

Hello -

Okay ... so the code might have done the right thing all along but I
did not paste it into an application that would accept this format.

I just tried the following to see whether I could put a bitmap back
onto the Clipboard and it still would not let me paste it into
anything ...

Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Bmp)
Dim lDataObject As New DataObject
lDataObject.SetData("BMP", False, lMemoryStream)
Clipboard.SetDataObject(lDataObject)

Thanks,
Joe
 
K

kimiraikkonen

Hello -

Okay ... so the code might have done the right thing all along but I
did not paste it into an application that would accept this format.

I just tried the following to see whether I could put a bitmap back
onto the Clipboard and it still would not let me paste it into
anything ...

Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Bmp)
Dim lDataObject As New DataObject
lDataObject.SetData("BMP", False, lMemoryStream)
Clipboard.SetDataObject(lDataObject)

Thanks,
Joe

Joe,
I still recomended using SetImage, GetImage methods which are provided
in .NET 2.0. I sometimes, not always, had errors while pasting PNG or
other images (no matter even with JPG) which are copied to clipboard
using SetDataObject, but it seems Clipboard.SetImage method in 2.0
seems much more stable choice.

Thanks,

Onur Güzel
 
M

Michael Phillips, Jr.

Okay ... so the code might have done the right thing all along but I
did not paste it into an application that would accept this format.
I just tried the following to see whether I could put a bitmap back
onto the Clipboard and it still would not let me paste it into
anything ...
Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Bmp)
Dim lDataObject As New DataObject
lDataObject.SetData("BMP", False, lMemoryStream)
Clipboard.SetDataObject(lDataObject)

The above code is not correct!

It should be lDataObject.SetData("DeviceIndependentBitmap", False,
lMemoryStream) but only after you construct the memory stream correctly.

Your lMemoryStream looks like the following in memory:
1) BITMAPFILEHEADER----> 14 bytes.
2) BITMAPINFOHEADER---> 40 bytes
3) Color Palette or Bitfields array depending upon the depth of the
bitmap(i.e., 1bpp - 16bpp)
The size in bytes varies from 8 to 1024 bytes.
If your bitmap is 32bpp or PixelFormat16bppRGB555, then no color palette of
bitfield array is necessary.
4) The bitmap's pixels.
For some bitmaps this position in the stream may be aligned on a 32 bit
boundary so it is necessary to parse the BITMAPFILEHEADER for the exact
offset.

The correct format of the MemoryStream for a "DeviceIndependentBitmap"
should look like the following:
1) BITMAPINFOHEADER
2) Color Palette or Bitfields array depending upon the depth of the bitmap
3) The bitmap's pixels.

To correct your code, you need to create a second MemoryStream object and
copy the BITMAPINFOHEADER, Color Palette or Bitfields array, if present, and
the bitmap's pixels from the first stream to the second stream and then
rewind the stream to position 0.

The memory layout must be packed with Color Palette or Bitfields array
depending upon the depth of the bitmap and the bitmap's pixels directly
following the BITMAPINFOHEADER. This requires that you parse the
BITMAPFILEHEADER to get the exact offset of the bitmap's bits.
 
J

Joe Duchtel

Hello -

I just used the code as a sample of how I thought I could put the
bitmap back onto the Clipboard. I actually want it to be pasted as a
PNG. Do I have to do something similar to what you outlined below for
that? I assume that the "DeviceIndependentBitmap" would not work?

I guess I did not realize that I had to construct the memory stream
myself. I thought that since I can use the Image.Save() to save a
*.png to a file, I should somehow be able to put that back onto the
Clipboard.

So I assume that based on your feedback, the following is also
incorrect?

Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream, System.Drawing.Imaging.ImageFormat.Png)
Dim lDataObject As New DataObject
lDataObject.SetData("PNG", False, lMemoryStream)
Clipboard.SetDataObject(lDataObject)

I really thought this was going to be a lot easier ;) ...

Thanks a lot!
Joe
 
M

Michael Phillips, Jr.

So I assume that based on your feedback, the following is also
incorrect?
Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream, System.Drawing.Imaging.ImageFormat.Png)
Dim lDataObject As New DataObject
lDataObject.SetData("PNG", False, lMemoryStream)
Clipboard.SetDataObject(lDataObject)

The above code is correct. One way to test is to open an empty Word
document and use "Paste Special" from the menu.

The "PNG" clipboard format will appear in the dialog box.

You cannot force an application to support the "PNG" format. The
application may only support bitmaps, metafiles or private image formats.

The Windows clipboook viewer will also show that the "PNG" format is on the
clipboard albeit the format is grayed out.
 
J

Joe Duchtel

Hello -

The Edit > Paste and Edit > Paste Special... menu entries are grayed
out when I run the code. I even tried to use the Tiff format since I
could find it under DataFormats ...

Dim lData As DataObject = Clipboard.GetDataObject()
...
Dim lImage As Image = lData.GetData(DataFormats.Bitmap,
False)
...

Dim lMemoryStream As New MemoryStream
lImage.Save(lMemoryStream,
System.Drawing.Imaging.ImageFormat.Tiff)
Dim lDataObject As New DataObject
lDataObject.SetData(DataFormats.Tiff, False,
lMemoryStream)
Clipboard.SetDataObject(lDataObject)

Still not working ...

Thanks!
Joe
 
M

Michael Phillips, Jr.

The Edit > Paste and Edit > Paste Special... menu entries are grayed
out when I run the code.

What application(i.e., name and version) are you using for the test?

The "PNG" format will paste into any Office 2007 document with "Paste
Special".

I do not have any other version of Microsoft Office to test with.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top