I have an application which requires an image to be retrived from the
clipboard. So, I am writting a quick C# windows application to take
images from a webcam and store a single frame on the clipboard so it can
be pasted into this other application. My solution is working fine with
all applications (mspaint, word, wordpad) except the one I need it to
work with. I've contacted the vendor of the application, but I haven't
been able to get anywhere with them.
I think I've narrowed down my problem to the format of the DIB being
placed on the clipboard. When I call Clipboard.setDataObject(someBitmap)
the DIB which is placed into the clipboard has a type of 32bpp BITFIELDS
and not 24bpp RGB. Even though I specifically set the PixelFormat to
Format24bppRgb when the Bitmap object is created. When I attempt to
paste the image in the target application, nothing happens. If I first
paste the image to mspaint, then select all, copy it to the clipboard
again and then paste it into the application it works fine. When mspaint
places the image on the clipboard it is a 24bpp RGB image, and not a
32bpp BITFIELDS image. I've been using the clipboard viewer application
at
(http://www.codeguru.com/cpp/w-p/clipboard/externallinks/article.php/c9155/)
to see the data placed on the clipboard.
Anyone have any idea how I can take a C# Bitmap object and turn it into
a 24bit RGB image which will appear on the clipboard? I've been trying
to figure this out for hours!
The following code demonstrates the issue :
Bitmap b = new
Bitmap(100,100,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
for (int i=0;i<50;i++)
{
b.SetPixel(i,i,Color.Red);
}
Clipboard.SetDataObject(b);
After this the CF_DIB stored on the clipboard will be 32bpp and
BITFIELDS not RGB. I am not certain what BITFIELDS means, it is what is
displayed by the clipboard viewer I am using..
Thanks!
-James
BITFIELDS compression is only used in 16 and 32 bit DIBs, and simply describes how the data is packed. In the case of a
16-bit DIB it can define the resolution of the green channel (i.e. 5:6:5 or 5:5:5), where as for 32-bit DIBs it defines
whether the data is stored in RGB or BGR order (and, when using a BMIHv4/5 header, whether the alpha channel is used.)
for some reason when GDI creates a 32-bit DIB it often decides to use BITFIELDS compression and sets the default RGB
order, even though using BI_RGB compression would give exactly the same result, in these cases the BITFIELDS
'compression' flag can simply be ignored, but remember there will be an additional 12 bytes of data between the header
and image data.
One way of accomplishing what you're after is to use GDI directly, in which case you're in full control of the Bitmap
you create. If your destination is the clipboard then you could probably just get GetDIBits() to fill a global memory
object to perform the bit-depth conversion and packed DIB creation in one go.
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://EDais.mvps.org/
> One way of accomplishing what you're after is to use GDI directly, in which case you're in full control of the Bitmap
> you create. If your destination is the clipboard then you could probably just get GetDIBits() to fill a global memory
> object to perform the bit-depth conversion and packed DIB creation in one go.
> Hope this helps,
I've never really worked much with GDI. Could you give me some examples on
how I would take a Bitmap object (which is 24bpp RGB) and place it on the
clipboard so it's a 24bpp RGB DIB using GDI directly? Visual Basic or C#
would be helpful.
Thanks!
-James
Placing a bitmap in a clipboard have nothing to do with GDI really. If you want to put a bitmap into your own format don't use Clipboard.SetDataObject(b); because it probably converts it to 32bit BITFELDS and older applications which support strict bitmap ver. 3.0 format cannot deal with it. You need to use SetClipBoardData() API and use either CF_DIB or CF_BITMAP clipboard format format. I can't help you with Visual Basic or C# so search for some code examples in these languages.
--
677265676F727940346E6575726F6E732E636F6D
Right, but first I would need to take the Bitmap object and turn it into a
DIB with the correct format. This is where I am having the problem and I
think that would involve GDI. I've searched for examples of this in VB and
C#, but have yet to find something.
-jr
1) Create two MemoryStreams.
2) Use GDI+ with the System.Drawing namespace to write your 24bpp bitmap to
this stream.
3) You now must create a "Packed DIB" from this stream.
A packed DIB is a BITMAPINFOHEADER followed by the bits.
Since the stream that you created in step 2 is formatted as a
BITMAPFILEHEADER followed
by a BITMAPINFOHEADER and the bits, you simply copy the bytes after the
BITMAPFILEHEADER
to the second stream.
4) Use DataObject.SetData("DeviceIndependentBitmap", strm) to place the
bitmap on to the clipboard.
"JamesR" <Jam...@discussions.microsoft.com> wrote in message
news:9A1C3A99-58A8-4FC4...@microsoft.com...
Michael, Thanks for the reply. You're right it was easy!
Here is what I came up with:
MemoryStream ms = new MemoryStream();
MemoryStream ms2 = new MemoryStream();
objBitmap.Save(ms, ImageFormat.Bmp);
byte[] b = ms.GetBuffer();
ms2.Write(b,14,(int)ms.Length-14);
ms.Position = 0;
Clipboard.SetData("DeviceIndependentBitmap", ms2);
Thanks again!
-jr
> Clipboard.SetData("DeviceIndependentBitmap", ms2);
It should be:
DataObject dataObject = new DataObject();
dataObject.SetData("DeviceIndependentBitmap", ms2);
Clipboard.SetDataObject(dataObject, false);
"JamesR" <Jam...@discussions.microsoft.com> wrote in message
news:3D7F65DF-F5D7-4C61...@microsoft.com...
> This line is not correct:
>
> > Clipboard.SetData("DeviceIndependentBitmap", ms2);
>
> It should be:
>
> DataObject dataObject = new DataObject();
> dataObject.SetData("DeviceIndependentBitmap", ms2);
> Clipboard.SetDataObject(dataObject, false);
Thanks, but the other way did work!
-jr
-jr
The canonical CF_DIB format uses a global memory handle to represent the
packed DIB.
The net common language runtime uses an IStream to represent the packed DIB.
The clipboard will synthesize these formats for applications that don't
specifically
place them on the clipboard.
If your code works, then all is well!
"JamesR" <Jam...@discussions.microsoft.com> wrote in message
news:67EA0476-6D13-4E05...@microsoft.com...