2010-12-31 4 views
3

(Это связано с вопросом о How would I load a PNG image using Win32/GDI (no GDI+ if possible)?.)Как рисовать PNG-изображение с помощью LoadImage и StretchDIBits?

Привет всем,

мне было интересно, учитывая, что у вас есть PNG ресурс, встроенный в двоичный файл с идентификатором IDB_PNG1, и LPDRAWITEMSTRUCT рисовать (так что это означает, что у вас есть HDC и прямоугольник для вашей цели), как вы рисуете это изображение на экране с помощью StretchDIBits? Я работал с BitBlt и TransparentBlt раньше, но StretchDIBits, похоже, работает по-другому, и LoadImage, похоже, не работает с PNG.

Спасибо!

(Примечание: язык, который я поставил, это C++, но это не так важно ... C, C#, Visual Basic и т. Д. Все будет в порядке, я просто пытаюсь выяснить шаги, а не точный код необходимо.)

+0

Если вы можете сохранить свой ресурс в качестве значка в формате PNG, можете ли вы загрузить его таким образом? – Gabe

ответ

1

Я думаю, что поддержка PNG внутри растровых изображений действительно предназначена только для использования драйверами принтера. Для отображения экрана вам, вероятно, придется самостоятельно распаковать данные PNG, используя код, например libpng.

+0

Хм ... Я, конечно, не видел этого. В чем разница между дисплеем и принтером, который может вызвать это? – Mehrdad

+1

Принтеры обычно (ну, по крайней мере, исторически) имеют значительно больше возможностей, чем экранирующие адаптеры. Принтеры также используют соединения с низкой пропускной способностью, поэтому экономия битов важна при отправке данных на принтер (лучше отправить сжатый PNG на принтер, который имеет возможность его декодировать, чем отправлять все необработанные биты). Это также позволяет принтеру выбирать наиболее подходящие параметры верности, когда он сам выполняет декомпрессию. Однако аппаратные средства и драйверы дисплея обычно хотят быть более детерминированными и избегать самих декомпрессии. –

+2

Как функция знает, используется ли она для принтера, а не для дисплея? – Gabe

9

Я написал blog post (при отображении заставки с C++), который содержит полный образец кода, который загружает PNG из ресурса и преобразует его в HBITMAP (с использованием WIC). Затем вы можете использовать CreateCompatibleDC, SelectObject и BitBlt для отображения в целевом HDC.

Хотя я никогда не пробовал это, вы должны иметь возможность использовать StretchDIBits для непосредственного отображения PNG, если вы загружаете необработанные байты из ресурса в память и настраиваете структуру BITMAPINFOHEADER с шириной, высотой и т. Д. как показано в этом документе MSDN sample.

Решения C# и VB.NET будут совсем другими, поскольку вы можете использовать System.Drawing (оболочку для GDI +) или System.Windows.Media.Imaging (в приложении WPF) для обработки загрузки и рисования изображений.

+1

Это очень интересно, кажется, именно то, что я ищу. Вопрос о попытке настроить «BITMAPINFOHEADER»: как я узнаю, каковы размеры изображения? Будет ли я все еще вынужден использовать WIC? (Edit: Кажется, что это не сработает, см. Мой комментарий к сообщению Грега.Но большое спасибо за ссылку на сообщение в блоге, это определенно будет полезно ... Я бы хотел отметить две должности в качестве ответа. :)) – Mehrdad

+1

Чтобы узнать размеры изображения, вам нужно либо написать png-декодер (или использовать libpng или WIC), чтобы читать их из PNG-файла, либо хранить их как отдельный ресурс, который хранится в синхронизации с вашим Ресурс PNG. (Вот почему я никогда не пробовал подход StretchDIBits, я всегда использовал libpng или WIC для обработки _all_ PNG-чтения.) –

Смежные вопросы