Как прочитать растровое изображение из буфера обмена Windows

Я пишу очень маленькую программу на C ++, чтобы помочь мне оживить спрайты. Я бы хотел, чтобы он взял данные, которые я копирую в буфер обмена из фотошопа, манипулировал ими в моей программе, а затем переписал буфер обмена с помощью преобразования.

Проблема в том, что я не уверен, как читать исходный буфер обмена из фотошопа.

Я могу загрузить буфер обмена с помощью GetClipboardData(CF_DIB) и получить действительный дескриптор, но я не знаю, как использовать этот дескриптор. Я попытался использовать SFML Image::LoadFromMemory(handle, GlobalSize(handle)), который может загружать растровые файлы из памяти, но, похоже, это не работает.

Нужно ли мне на самом деле анализировать весь формат? Какую структуру формата я бы посмотрел в этом случае? Может быть, есть какой-нибудь способ, которым я мог бы быстро манипулировать данными, чтобы они могли выглядеть как растровый файл? Может ли быть проще /возможно просто сохранить его в файл с помощью Windows API? (Я мог бы затем загрузить этот файл с SFML для редактирования, таким образом)

Для меня это всего лишь быстрый и грязный инструмент, позволяющий сэкономить большую часть тяжелой работы в фотошопе, поэтому эффективность или надежность вообще не важны.

4 голоса | спросил Anne Quinn 31 Mayam15 2015, 02:10:17

1 ответ


0

Изучите структуру растрового изображения из Википедии, затем запишите ее в файл, а затем запишите пиксели.

Я протестировал приведенное ниже с помощью 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;
}
ответил Brandon 31 Mayam15 2015, 04:10:35

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132