GDI+ Image to Clipboard

March 05th, 2008 - 07:49 am ET by marcusadeleon | Report spam
Hi,

What is the best way to copy a GDI+ Image read in TIFF format to the
clipboard in Bitmap Format. Also if the TIFF has multi layers, how can
I do this for each layer of the TIFF.

Thanks,

Marcus de Leon
email Follow the discussionReplies 8 repliesReplies Make a reply

Similar topics

Replies

#1 Tobias Selander
April 10th, 2008 - 11:35 am ET | Report spam
Hi,
this is exactly what I would like to do, copy a gdiplus bitmap to the
clipboard, but I just can't get it to work. I have no problem copying a
CBitmap to the clipboard by using SetClipboardData(CF_BITMAP,
bmp.GetSafeHandle()). However it does not work when I try the same approach
with a gdiplus bitmap:
HBITMAP hBitmap;
if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) == Gdiplus::Ok)
{
HANDLE hHandle = ::SetClipboardData(CF_BITMAP, hBitmap);
}

Then I tried your solution by copying the bitmap (minus the first 14 bytes)
to a global area and using the global handle as input to the SetClipboardData
method - no luck! Am I missing something obvious? This drives me crazy!!
Please help...

/Tobias

"Michael Phillips, Jr." wrote:

The approach that I gave is for a TIFF only.

For a bitmap, you can still use the same approach except that gdiplus writes
the BITMAPFILEHEADER, BITMAPINFOHEADER and bits to the stream.
You just want the entire stream minus the 14 bytes of the BITMAPFILEHEADER.

You can create a second stream with CreateStreamOnHGlobal and copy the bytes
after
the BITMAPFILEHEADER. Use the CF_DIB clipboard format.

Since it is a multipage tiff, you need to create a bitmap from each frame
and follow the above.


"Michael Phillips, Jr." wrote in message
news:%
>> What is the best way to copy a GDI+ Image read in TIFF format to the
>> clipboard in Bitmap Format. Also if the TIFF has multi layers, how can
>> I do this for each layer of the TIFF.
>
> Use RegisterClipboardFormat("TIFF") and CreateStreamOnHGlobal.
>
> After you write the stream with gdiplus, detach the HGLOBAL handle and
> place the handle on the clipboard with SetClipboardData.
>





Replies Reply to this message
#2 Michael Phillips, Jr.
April 12th, 2008 - 07:06 pm ET | Report spam
> if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
Gdiplus::Ok)
{
HANDLE hHandle = ::SetClipboardData(CF_BITMAP, hBitmap);
}




The above code creates a handle to a DIB.

If you want to use CF_BITMAP, then covert the DIB to a DDB with
CreateDIBitmap and then place that handle on the clipboard.

If you want to place a CF_DIB on the clipboard then take your DIB handle
from GetHBITMAP and break out the BITMAPINFOHEADER and bits by using
GetObject with the DIBSECTION structure.

GetObject will provide you with the building blocks necessary for
CreateDIBitmap and provide you with the information necessary for the packed
DIB.

You can kill two birds with one stone and create a CF_BITMAP and CF_DIB at
the same time.

Use GlobalAlloc(GHND | GMEM_DDESHARE, iPackedSize) where iPackedSize is
equal to the dsBmih.biSize + dsBmih.biSizeImage.

Since gdiplus produces a 32bpp DIB there is no color table to worry about.

The dsBm structure member provides you with a pointer to the bits and the
width, height and stride of the bitmap.

The dsBmih structure member provides you with the BITMAPINFOHEADER.

Make sure that you use BI_RGB instead of BI_BITFIELDS. This will allow you
to avoid writing the bitfields.

If you are not comfortable with pointer arithmetic then you can use the
HGLOBAL with CreateStreamOnHGlobal and then use the IStream API to construct
the CF_DIB.

When you are done place both formats on the clipboard.


"Tobias Selander" <Tobias wrote in
message news:
Hi,
this is exactly what I would like to do, copy a gdiplus bitmap to the
clipboard, but I just can't get it to work. I have no problem copying a
CBitmap to the clipboard by using SetClipboardData(CF_BITMAP,
bmp.GetSafeHandle()). However it does not work when I try the same
approach
with a gdiplus bitmap:
HBITMAP hBitmap;
if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
Gdiplus::Ok)
{
HANDLE hHandle = ::SetClipboardData(CF_BITMAP, hBitmap);
}

Then I tried your solution by copying the bitmap (minus the first 14
bytes)
to a global area and using the global handle as input to the
SetClipboardData
method - no luck! Am I missing something obvious? This drives me crazy!!
Please help...

/Tobias

"Michael Phillips, Jr." wrote:

The approach that I gave is for a TIFF only.

For a bitmap, you can still use the same approach except that gdiplus
writes
the BITMAPFILEHEADER, BITMAPINFOHEADER and bits to the stream.
You just want the entire stream minus the 14 bytes of the
BITMAPFILEHEADER.

You can create a second stream with CreateStreamOnHGlobal and copy the
bytes
after
the BITMAPFILEHEADER. Use the CF_DIB clipboard format.

Since it is a multipage tiff, you need to create a bitmap from each frame
and follow the above.


"Michael Phillips, Jr." wrote in message
news:%
>> What is the best way to copy a GDI+ Image read in TIFF format to the
>> clipboard in Bitmap Format. Also if the TIFF has multi layers, how can
>> I do this for each layer of the TIFF.
>
> Use RegisterClipboardFormat("TIFF") and CreateStreamOnHGlobal.
>
> After you write the stream with gdiplus, detach the HGLOBAL handle and
> place the handle on the clipboard with SetClipboardData.
>







Replies Reply to this message
#3 crino
June 01st, 2008 - 07:39 am ET | Report spam
hi micheal,
i'm trying to copy a bitmap to clipboard but with no luck :(
i tried your code but or fails or get 'black' image.
can you post an example code?
thanks in advance

"Michael Phillips, Jr." wrote:

> if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
> Gdiplus::Ok)
> {
> HANDLE hHandle = ::SetClipboardData(CF_BITMAP, hBitmap);
> }
>

The above code creates a handle to a DIB.

If you want to use CF_BITMAP, then covert the DIB to a DDB with
CreateDIBitmap and then place that handle on the clipboard.

If you want to place a CF_DIB on the clipboard then take your DIB handle
from GetHBITMAP and break out the BITMAPINFOHEADER and bits by using
GetObject with the DIBSECTION structure.

GetObject will provide you with the building blocks necessary for
CreateDIBitmap and provide you with the information necessary for the packed
DIB.

You can kill two birds with one stone and create a CF_BITMAP and CF_DIB at
the same time.

Use GlobalAlloc(GHND | GMEM_DDESHARE, iPackedSize) where iPackedSize is
equal to the dsBmih.biSize + dsBmih.biSizeImage.

Since gdiplus produces a 32bpp DIB there is no color table to worry about.

The dsBm structure member provides you with a pointer to the bits and the
width, height and stride of the bitmap.

The dsBmih structure member provides you with the BITMAPINFOHEADER.

Make sure that you use BI_RGB instead of BI_BITFIELDS. This will allow you
to avoid writing the bitfields.

If you are not comfortable with pointer arithmetic then you can use the
HGLOBAL with CreateStreamOnHGlobal and then use the IStream API to construct
the CF_DIB.

When you are done place both formats on the clipboard.


"Tobias Selander" <Tobias wrote in
message news:
> Hi,
> this is exactly what I would like to do, copy a gdiplus bitmap to the
> clipboard, but I just can't get it to work. I have no problem copying a
> CBitmap to the clipboard by using SetClipboardData(CF_BITMAP,
> bmp.GetSafeHandle()). However it does not work when I try the same
> approach
> with a gdiplus bitmap:
> HBITMAP hBitmap;
> if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
> Gdiplus::Ok)
> {
> HANDLE hHandle = ::SetClipboardData(CF_BITMAP, hBitmap);
> }
>
> Then I tried your solution by copying the bitmap (minus the first 14
> bytes)
> to a global area and using the global handle as input to the
> SetClipboardData
> method - no luck! Am I missing something obvious? This drives me crazy!!
> Please help...
>
> /Tobias
>
> "Michael Phillips, Jr." wrote:
>
>> The approach that I gave is for a TIFF only.
>>
>> For a bitmap, you can still use the same approach except that gdiplus
>> writes
>> the BITMAPFILEHEADER, BITMAPINFOHEADER and bits to the stream.
>> You just want the entire stream minus the 14 bytes of the
>> BITMAPFILEHEADER.
>>
>> You can create a second stream with CreateStreamOnHGlobal and copy the
>> bytes
>> after
>> the BITMAPFILEHEADER. Use the CF_DIB clipboard format.
>>
>> Since it is a multipage tiff, you need to create a bitmap from each frame
>> and follow the above.
>>
>>
>> "Michael Phillips, Jr." wrote in message
>> news:%
>> >> What is the best way to copy a GDI+ Image read in TIFF format to the
>> >> clipboard in Bitmap Format. Also if the TIFF has multi layers, how can
>> >> I do this for each layer of the TIFF.
>> >
>> > Use RegisterClipboardFormat("TIFF") and CreateStreamOnHGlobal.
>> >
>> > After you write the stream with gdiplus, detach the HGLOBAL handle and
>> > place the handle on the clipboard with SetClipboardData.
>> >
>>
>>
>>





Replies Reply to this message
#4 Michael Phillips, Jr.
June 01st, 2008 - 12:46 pm ET | Report spam
> i'm trying to copy a bitmap to clipboard but with no luck :(
i tried your code but or fails or get 'black' image.
can you post an example code?



Here is a code snippet:
...
// Get a handle for a 32bpp DIB from gdiplus
HBITMAP hBitmap = NULL;
if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
Gdiplus::Ok)
{
DIBSECTION ds;
GetObject( hBitmap, sizeof(ds), &ds );
ds.dsBmih.biCompression = BI_RGB; // change compression from
BI_BITFIELDS to BI_RGB
// Convert the DIB to a device dependent bitmap(i.e., DDB)
HDC hDC = GetDC(NULL);
HBITMAP hDDB = CreateDIBitmap( hDC, &ds.dsBmih, CBM_INIT,
ds.dsBm.bmBits, (BITMAPINFO*)&ds.dsBmih, DIB_RGB_COLORS );
ReleaseDC(NULL, hDC);
// Open the clipboard
OpenClipboard(hWnd);
EmptyClipboard();
// Place the handle to the DDB on the clipboard
SetClipboardData(CF_BITMAP, hDDB);
// Do not delete the hDDB handle, the clipboard owns it
CloseClipboard();
}
DeleteObject(hBitmap);
Replies Reply to this message
#5 crino
June 02nd, 2008 - 08:41 am ET | Report spam
hi micheal,
thanks!, i was wrong in CreateDIBitmap and forgot to change compression.
Now works great!
thanks again ;)


"Michael Phillips, Jr." wrote:

> i'm trying to copy a bitmap to clipboard but with no luck :(
> i tried your code but or fails or get 'black' image.
> can you post an example code?

Here is a code snippet:

// Get a handle for a 32bpp DIB from gdiplus
HBITMAP hBitmap = NULL;
if(GDIPlusBmp.GetHBITMAP(Gdiplus::Color(255,0,0,0), &hBitmap) ==
Gdiplus::Ok)
{
DIBSECTION ds;
GetObject( hBitmap, sizeof(ds), &ds );
ds.dsBmih.biCompression = BI_RGB; // change compression from
BI_BITFIELDS to BI_RGB
// Convert the DIB to a device dependent bitmap(i.e., DDB)
HDC hDC = GetDC(NULL);
HBITMAP hDDB = CreateDIBitmap( hDC, &ds.dsBmih, CBM_INIT,
ds.dsBm.bmBits, (BITMAPINFO*)&ds.dsBmih, DIB_RGB_COLORS );
ReleaseDC(NULL, hDC);
// Open the clipboard
OpenClipboard(hWnd);
EmptyClipboard();
// Place the handle to the DDB on the clipboard
SetClipboardData(CF_BITMAP, hDDB);
// Do not delete the hDDB handle, the clipboard owns it
CloseClipboard();
}
DeleteObject(hBitmap);





Replies Reply to this message
Help Create a new topicNext page Replies Make a reply
Search Make your own search