如何从Windows剪贴板读取位图 [英] How to read a bitmap from the Windows Clipboard

查看:80
本文介绍了如何从Windows剪贴板读取位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个非常小的C ++程序来帮助我设置精灵动画.我希望它获取从photoshop复制到剪贴板的数据,在程序中对其进行操作,然后使用转换覆盖剪贴板.

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.

但是问题是我不确定如何从photoshop中读取初始剪贴板.

The problem though is that I'm not sure how to read the initial clipboard from photoshop.

我可以用GetClipboardData(CF_DIB)加载剪贴板,并获得有效的句柄,但是我不知道如何使用该句柄.我尝试使用SFML的Image::LoadFromMemory(handle, GlobalSize(handle))能够从内存中加载位图文件,但这似乎不起作用.

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.

我是否需要解析整个格式?在这种情况下,我将查看哪种格式的结构?可能有什么方法可以快速处理数据,使其看起来像位图文件吗?使用Windows API将其简单地保存到文件中是否容易/可行? (然后,我可以用SFML加载该文件以进行编辑)

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)

对于我来说,这只是一个快速而又肮脏的工具,可以节省许多在Photoshop中的繁琐工作,因此效率或鲁棒性根本不重要.

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.

推荐答案

从Wikipedia学习位图结构,然后将其写到文件中,然后写出像素..

Learn the bitmap structure from Wikipedia and then write it out to a file and then write out the pixels..

我已经在Windows 8.1上使用Paint测试了以下内容.我用油漆打开图像,然后按Ctrl + C复制到剪贴板.然后运行以下代码,它将剪贴板图像复制到桌面:

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>

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;
}

这篇关于如何从Windows剪贴板读取位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆