How to read a bitmap from the Windows clipboard

I am writing an extremely small C ++ program to help me animate sprites. I would like the data that I copied to the clipboard from Photoshop to manipulate it in my program, and then overwrite the clipboard using conversion.

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

I can load the clipboard from GetClipboardData(CF_DIB)and get a valid descriptor, but I do not know how to use this descriptor. I tried using SFML Image::LoadFromMemory(handle, GlobalSize(handle)), which can load raster files from memory, but this does not seem to work.

Is there any need to analyze the whole format? What format structure will I look in this case? Maybe, perhaps, somehow, I could quickly manipulate the data so that it can look like a raster file? Could it be easier / possible to just save it to a file using the windows API? (Then I could upload this file using SFML)

It's just a quick and dirty tool for me to save a lot of work in Photoshop, so efficiency or reliability is not important at all.

+4
source share
1 answer

Examine the structure of the bitmap from Wikipedia, and then write it to a file and then write down the pixels.

Paint Windows 8.1. , 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;
}
+5

All Articles