我正在编写一个非常小的C ++程序来帮助我制作animation精灵。 我希望它能够将数据从photoshop复制到剪贴板,在我的程序中进行操作,然后用转换覆盖剪贴板。
但问题是,我不知道如何从Photoshop中读取初始剪贴板。
我可以加载剪贴板与GetClipboardData(CF_DIB)
,并得到一个有效的句柄,但我不知道如何使用该句柄。 我已经尝试过使用SFML的Image::LoadFromMemory(handle, GlobalSize(handle))
,它能够从内存中加载位图文件,但似乎没有工作。
我需要真正parsing整个格式吗? 在这种情况下,我会考虑什么格式的结构? 那么可能有什么办法可以快速修改数据,使其看起来像位图文件? 使用Windows API将其保存到文件可能更容易吗? (我可以用SFML加载这个文件来编辑,那样)
这只是一个快速而肮脏的工具,可以帮助我们在Photoshop中节省大量的工作量,因此效率或稳健性并不重要。
从维基百科学习位图结构,然后写出一个文件,然后写出像素..
我在Windows 8.1上用Paint测试了下面的内容。 我用油漆打开一个图像,然后按下Ctrl + C复制到剪贴板。然后我运行下面的代码,它将剪贴板图像复制到桌面:
#include <iostream> #include <fstream> #include <windows.h> typedef struct { std::uint32_t biSize; std::int32_t biWidth; std::int32_t biHeight; std::uint16_t biPlanes; std::uint16_t biBitCount; std::uint32_t biCompression; std::uint32_t biSizeImage; std::int32_t biXPelsPerMeter; std::int32_t biYPelsPerMeter; std::uint32_t biClrUsed; std::uint32_t biClrImportant; } DIB; typedef struct { std::uint16_t type; std::uint32_t bfSize; std::uint32_t reserved; std::uint32_t offset; } HEADER; typedef struct { HEADER header; DIB dib; } BMP; 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_BITMAP) || IsClipboardFormatAvailable(CF_DIB) || IsClipboardFormatAvailable(CF_DIBV5)) { if (OpenClipboard(NULL)) { HANDLE hClipboard = GetClipboardData(CF_DIB); if (!hClipboard) { hClipboard = GetClipboardData(CF_DIBV5); } if (hClipboard != NULL && hClipboard != INVALID_HANDLE_VALUE) { void* dib = GlobalLock(hClipboard); if (dib) { DIB *info = reinterpret_cast<DIB*>(dib); BMP bmp = {0}; bmp.header.type = 0x4D42; bmp.header.offset = 54; bmp.header.bfSize = info->biSizeImage + bmp.header.offset; bmp.dib = *info; std::cout<<"Type: "<<std::hex<<bmp.header.type<<std::dec<<"\n"; std::cout<<"bfSize: "<<bmp.header.bfSize<<"\n"; std::cout<<"Reserved: "<<bmp.header.reserved<<"\n"; std::cout<<"Offset: "<<bmp.header.offset<<"\n"; std::cout<<"biSize: "<<bmp.dib.biSize<<"\n"; std::cout<<"Width: "<<bmp.dib.biWidth<<"\n"; std::cout<<"Height: "<<bmp.dib.biHeight<<"\n"; std::cout<<"Planes: "<<bmp.dib.biPlanes<<"\n"; std::cout<<"Bits: "<<bmp.dib.biBitCount<<"\n"; std::cout<<"Compression: "<<bmp.dib.biCompression<<"\n"; std::cout<<"Size: "<<bmp.dib.biSizeImage<<"\n"; std::cout<<"X-res: "<<bmp.dib.biXPelsPerMeter<<"\n"; std::cout<<"Y-res: "<<bmp.dib.biYPelsPerMeter<<"\n"; std::cout<<"ClrUsed: "<<bmp.dib.biClrUsed<<"\n"; std::cout<<"ClrImportant: "<<bmp.dib.biClrImportant<<"\n"; std::ofstream file("C:/Users/Brandon/Desktop/Test.bmp", std::ios::out | std::ios::binary); if (file) { file.write(reinterpret_cast<char*>(&bmp.header.type), sizeof(bmp.header.type)); file.write(reinterpret_cast<char*>(&bmp.header.bfSize), sizeof(bmp.header.bfSize)); file.write(reinterpret_cast<char*>(&bmp.header.reserved), sizeof(bmp.header.reserved)); file.write(reinterpret_cast<char*>(&bmp.header.offset), sizeof(bmp.header.offset)); file.write(reinterpret_cast<char*>(&bmp.dib.biSize), sizeof(bmp.dib.biSize)); file.write(reinterpret_cast<char*>(&bmp.dib.biWidth), sizeof(bmp.dib.biWidth)); file.write(reinterpret_cast<char*>(&bmp.dib.biHeight), sizeof(bmp.dib.biHeight)); file.write(reinterpret_cast<char*>(&bmp.dib.biPlanes), sizeof(bmp.dib.biPlanes)); file.write(reinterpret_cast<char*>(&bmp.dib.biBitCount), sizeof(bmp.dib.biBitCount)); file.write(reinterpret_cast<char*>(&bmp.dib.biCompression), sizeof(bmp.dib.biCompression)); file.write(reinterpret_cast<char*>(&bmp.dib.biSizeImage), sizeof(bmp.dib.biSizeImage)); file.write(reinterpret_cast<char*>(&bmp.dib.biXPelsPerMeter), sizeof(bmp.dib.biXPelsPerMeter)); file.write(reinterpret_cast<char*>(&bmp.dib.biYPelsPerMeter), sizeof(bmp.dib.biYPelsPerMeter)); file.write(reinterpret_cast<char*>(&bmp.dib.biClrUsed), sizeof(bmp.dib.biClrUsed)); file.write(reinterpret_cast<char*>(&bmp.dib.biClrImportant), sizeof(bmp.dib.biClrImportant)); file.write(reinterpret_cast<char*>(info + 1), bmp.dib.biSizeImage); } GlobalUnlock(dib); } } CloseClipboard(); } } return 0; }