Преобразование растрового изображения в PNG в памяти в C ++ (win32) - PullRequest
16 голосов
/ 14 декабря 2008

Можно ли преобразовать растровое изображение в PNG в памяти (т.е. без записи в файл), используя только Platform SDK? (т.е. без libpng и т. д.).

Я также хочу иметь возможность определить прозрачный цвет (не альфа-канал) для этого изображения.

Похоже, что решение GdiPlus ограничено изображениями шириной, кратной 4 . Все остальное терпит неудачу во время вызова Save (). Кто-нибудь знает причину этого ограничения и как / могу ли я обойти его?

Обновление: Баунти

Я начинаю вознаграждение (я действительно хочу, чтобы это работало). Я реализовал решение GDI +, но, как я уже сказал, оно ограничено изображениями с четырехугольной шириной. Награда будет предоставлена ​​любому, кто может решить эту проблему ширины (без изменения размеров изображения), или может предложить альтернативное решение без GDI +, которое работает.

Ответы [ 8 ]

18 голосов
/ 14 февраля 2009

LodePNG ( GitHub ) - это кодировщик / декодер PNG без библиотек.

15 голосов
/ 11 февраля 2009

Я читаю и пишу PNG, используя libpng , и мне кажется, что это имеет отношение ко всему, что я к этому добавляю (я использовал его в модульных тестах с такими вещами, как изображения размером 257x255, и они не вызывают проблем). Я считаю, что API достаточно гибок, чтобы его нельзя было привязать к файловому вводу-выводу (или, по крайней мере, вы можете переопределить его поведение по умолчанию, например, см. png_set_write_fn в разделе customization )

На практике я всегда использую его с помощью более чистого boost :: gil PNG IO extension , но, к сожалению, для этого требуется char* имен файлов, и если вы в него копаете, * 1015 Классы * и file_mgr в своей реализации кажутся довольно привязанными к FILE* (хотя, если бы вы работали в Linux, версия, использующая буферы fmemopen и in-memory, вероятно, могла бы быть довольно легко создана).

11 голосов
/ 14 декабря 2008

На этом сайте код показывает, как преобразовать растровое изображение в PNG, записав его в файл: http://dotnet -snippets.de / dns / gdi-speichern-eines-png-SID814.aspx . Вместо записи в файл метод растрового изображения Save также поддерживает запись в IStream (http://msdn.microsoft.com/en-us/library/ms535406%28VS.85%29.aspx).. Вы можете создать поток, резервное копирование которого осуществляется с помощью памяти, с помощью функции CreateStreamOnHGlobal API. ( http://msdn.microsoft.com/en-us/library/aa378980%28VS.85%29.aspx). Используемая библиотека GDI + включена в Windows, начиная с WindowsXP, и работает в Windows, начиная с Windows98. Я никогда ничего с этим не делал, просто гуглял. Похоже, что вы можете использовать это, хотя.

7 голосов
/ 12 февраля 2009

Класс CImage (ATL / MFC) поддерживает сохранение в формате PNG. Как и решение GDI +, оно также поддерживает сохранение в поток. Вот некоторый код, который я использую, чтобы сохранить его в CByteArray:

CByteArray baPicture;
IStream *pStream = NULL;
if (CreateStreamOnHGlobal(NULL, TRUE, &pStream) == S_OK)
{
    if (image.Save(pStream, Gdiplus::ImageFormatPNG) == S_OK)
    {
    ULARGE_INTEGER ulnSize;
        LARGE_INTEGER lnOffset;
        lnOffset.QuadPart = 0;
        if (pStream->Seek(lnOffset, STREAM_SEEK_END, &ulnSize) == S_OK)
        {
            if (pStream->Seek(lnOffset, STREAM_SEEK_SET, NULL) == S_OK)
            {                       
                baPicture.SetSize(ulnSize.QuadPart);
                ULONG ulBytesRead;
                pStream->Read(baPicture.GetData(), ulnSize.QuadPart, &ulBytesRead);
            }
        }
    }
}
pStream->Release();

Я не знаю, хотите ли вы использовать ATL или MFC.

5 голосов
/ 14 декабря 2008

Я использовал GDI + для сохранения растрового изображения в виде PNG в файл. Вам, вероятно, следует проверить информацию MSDN о GDI + здесь и, в частности, об этой функции GdipSaveImageToStream .

Этот урок здесь , вероятно, также поможет.

3 голосов
/ 12 февраля 2009

Если вы хотите использовать только API-интерфейсы Windows, WIC - это способ сделать это, и он поддерживает как растровые изображения, так и PNG.

3 голосов
/ 11 февраля 2009

GDI (старая школа, не плюс) имеет метод GetDIBits, который может быть запрошен для вывода битов с использованием сжатия PNG (BITMAPINFOHEADER::biCompression == BI_PNG). Интересно, можно ли это использовать для создания файла PNG? Использование GetDIBits для записи стандартных растровых файлов достаточно сложно, поэтому я подозреваю, что это будет еще сложнее.

2 голосов
/ 14 декабря 2008

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

Просмотр freeImage

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...