I am writing an extremely small C++ program to help me animate sprites. I'd like it to take data I copy to the clipboard from photoshop, manipulate it in my program, then overwrite the clipboard with the transform.
The problem though is that I'm not sure how to read the initial clipboard from photoshop.
I can load the clipboard with GetClipboardData(CF_DIB)
, and get a valid handle, but I've no idea how to use that handle. I've tried using SFML's Image::LoadFromMemory(handle, GlobalSize(handle))
which is able to load bitmap files from memory, but that doesn't seem to work.
Will I need to actually parse the entire format? What format structure would I be looking at in that case? Would there perhaps be any way I could quickly mangle the data so it might look like a bitmap file? Could it be easier/possible to simply save it to file using the windows API? (I could then load that file with SFML to edit, that way)
It's just a quick and dirty tool for myself to save a lot of grunt work in photoshop, so efficiency or robustness aren't important at all.
Learn the bitmap structure from Wikipedia and then write it out to a file and then write out the pixels..
I've tested the below with Paint on Windows 8.1. I opened an image with paint and then pressed Ctrl + C to copy to the clipboard.. then I ran the following code and it copied the clipboard image to the desktop:
#include <iostream>
#include <fstream>
#include <windows.h>
int main()
{
std::cout<<"Format Bitmap: "<<IsClipboardFormatAvailable(CF_BITMAP)<<"\n";
std::cout<<"Format DIB: "<<IsClipboardFormatAvailable(CF_DIB)<<"\n";
std::cout<<"Format DIBv5: "<<IsClipboardFormatAvailable(CF_DIBV5)<<"\n";
if (IsClipboardFormatAvailable(CF_DIB))
{
if (OpenClipboard(NULL))
{
HANDLE hClipboard = GetClipboardData(CF_DIB);
if (hClipboard != NULL && hClipboard != INVALID_HANDLE_VALUE)
{
void* dib = GlobalLock(hClipboard);
if (dib)
{
BITMAPINFOHEADER* info = reinterpret_cast<BITMAPINFOHEADER*>(dib);
BITMAPFILEHEADER fileHeader = {0};
fileHeader.bfType = 0x4D42;
fileHeader.bfOffBits = 54;
fileHeader.bfSize = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) / 8
* info->bmiHeader.biHeight) + fileHeader.bfOffBits;
std::cout<<"Type: "<<std::hex<<fileHeader.bfType<<std::dec<<"\n";
std::cout<<"bfSize: "<<fileHeader.bfSize<<"\n";
std::cout<<"Reserved: "<<fileHeader.bfReserved1<<"\n";
std::cout<<"Reserved2: "<<fileHeader.bfReserved2<<"\n";
std::cout<<"Offset: "<<fileHeader.bfOffBits<<"\n";
std::cout<<"biSize: "<<info->bmiHeader.biSize<<"\n";
std::cout<<"Width: "<<info->bmiHeader.biWidth<<"\n";
std::cout<<"Height: "<<info->bmiHeader.biHeight<<"\n";
std::cout<<"Planes: "<<info->bmiHeader.biPlanes<<"\n";
std::cout<<"Bits: "<<info->bmiHeader.biBitCount<<"\n";
std::cout<<"Compression: "<<info->bmiHeader.biCompression<<"\n";
std::cout<<"Size: "<<info->bmiHeader.biSizeImage<<"\n";
std::cout<<"X-res: "<<info->bmiHeader.biXPelsPerMeter<<"\n";
std::cout<<"Y-res: "<<info->bmiHeader.biYPelsPerMeter<<"\n";
std::cout<<"ClrUsed: "<<info->bmiHeader.biClrUsed<<"\n";
std::cout<<"ClrImportant: "<<info->bmiHeader.biClrImportant<<"\n";
std::ofstream file("C:/Users/Brandon/Desktop/Test.bmp", std::ios::out | std::ios::binary);
if (file)
{
file.write(reinterpret_cast<char*>(&fileHeader), sizeof(BITMAPFILEHEADER));
file.write(reinterpret_cast<char*>(info), sizeof(BITMAPINFOHEADER));
file.write(reinterpret_cast<char*>(++info), bmp.dib.biSizeImage);
}
GlobalUnlock(dib);
}
}
CloseClipboard();
}
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With