Аннотация:
В статье рассмотрена работа с растрами средствами GDI+ — новой библиотеки от Microsoft. Описываются методы создания растров из внешних источников, их взаимодействие с устройствами вывода и работа с графическими файлами.
Продолжая тему, хочу поделиться своими наблюдениями.
Если создать Bitmap конструктором:
Bitmap(const BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData);
внутреннего буфера в bitmap-e, видимо, не создается и изменения, произведенные, "вручную" в данных gdiBitmapData, отражаются на bitmap-объекте и наооборот. Еще одна фича, которая мне понравилась — это создать объект Graphics на основе bitmap-а. Тогда можно рисовать прямо на буффере gdiBitmapData методами Graphics.
Привет. Отличная статья.
По поводу Bitmap::GetHBITMAP() — если я правильно понял описание в SDK, то этот метод создает HBITMAP — копию изображения, содержащегося в объекте Bitmap. В этом случае изменение данных в HBITMAP не отобразится на Bitmap. Похоже в любом случае для быстрой работы (модификации) данных придется с использовать копию, создаваемую LockBits, а потом заливать ее обратно в Bitmap с помощью UnlockBits. Есть ли еще способы быстрого доступа к растровым данным?
Статья обошла стороной очень интересные возможности GDI+ в области работы с картинками, связанные с использванием класса ImageAttributes при отрисовке растра.
Этот класс позволяет проделывать много презабавных штук с картинками, в частности — задавать при отрисовке линейное преобразование каждого пиксела в пространстве ARGB. Есть и другие полезные возможности.
Спасибо за отзыв.
Действительно, метод GetHBITMAP создаст _копию_ растровых данных, но содержащуюся именно в DIB Section, как и было сказано в статье. Правда, это поведение так и не было документировано.
Если же требуется быстрый доступ к битам растра на запись, то можно попробовать пойти от противного: держать растр изначально в "сыром" формате DIB Section, а для получения GDI+ Bitmap создавать его, например, при помощи FromHBITMAP. При этом способ вполне законный и налицо экономия одного копирования.
Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере
600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются.
Что посоветуешь для сжатия выходных картинок?
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Здравствуйте, dad, Вы писали:
R>>Спасибо за отзыв.
dad>Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере dad>600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются. dad>Что посоветуешь для сжатия выходных картинок?
Здравствуйте, AP999, Вы писали:
AP>Продолжая тему, хочу поделиться своими наблюдениями. AP>Если создать Bitmap конструктором: AP>Bitmap(const BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData); AP>внутреннего буфера в bitmap-e, видимо, не создается и изменения, произведенные, "вручную" в данных gdiBitmapData, отражаются на bitmap-объекте и наооборот. Еще одна фича, которая мне понравилась — это создать объект Graphics на основе bitmap-а. Тогда можно рисовать прямо на буффере gdiBitmapData методами Graphics.
Здравствуйте, dad, Вы писали:
dad>Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере dad>600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются. dad>Что посоветуешь для сжатия выходных картинок?
Странно — у меня скриншот экрана в формате PNG занимает около 50 килобайт при формате 1024х768.
Вот код (можно скачать отсюда
dad>>Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере dad>>600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются. dad>>Что посоветуешь для сжатия выходных картинок?
R>Странно — у меня скриншот экрана в формате PNG занимает около 50 килобайт при формате 1024х768. R>Вот код (можно скачать отсюда
dad>>Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере dad>>600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются. dad>>Что посоветуешь для сжатия выходных картинок?
AS>TIFF c LZW недостаточно сжимает?
мне нужен был png & gif
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
dad>>Отлично создаются форматы gip, png, только вот немеренных объемов ( до 2М) при развмере dad>>600х400 , как я ни бился сжимать не удается, атрибуты качества есть только у jpeg , но они както игнорируются. dad>>Что посоветуешь для сжатия выходных картинок?
R>Странно — у меня скриншот экрана в формате PNG занимает около 50 килобайт при формате 1024х768.
У меня был баг, я в процедуре выбора кодека, написал
if( frm.compare( pImageCodecInfo[j].MimeType ) == 1 )
врезультате чего у меня всегда все сохранялось в едином формате,bmp
поэтому ие и шоп не понимал, только мозила умная
Но cximage все таки получше ужимает, да более явно у него все сделано в том числе и с доп. настройкой качества и весит не много (40-60К) к экзезешничку если статично.
Короче если бы знал, что сделаю с cximage от gdiplus, наверно, отказался бы теперь уже просто некогда либу переписывать под winapi
Спасибо что откликнулся.
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re: GDI+: графика нового поколения
От:
Аноним
Дата:
10.02.05 15:29
Оценка:
Здравствуйте, Виталий Брусенцев, Вы писали:
ВБ>Статья:
ВБ>Авторы: ВБ> Виталий Брусенцев
ВБ>Аннотация: ВБ>В статье рассмотрена работа с растрами средствами GDI+ — новой библиотеки от Microsoft. Описываются методы создания растров из внешних источников, их взаимодействие с устройствами вывода и работа с графическими файлами.
Скажите, пожалуйста, а как создасть кисть GPBrush, реализующую текстурную заливку (элементом GPImage) с заданным значением полупрозрачности (альфа-канала для всех пикселей изображения), эта кисть затем применяется для всевозможных заливок!!!
Хорошо.
Но я бы хотел знать вовсе не то какие существуют классы использующие библиотеку gdiplus.dll.
Мне нужно знать как непосредственно использовать подпрограммы из этой библиотеки.
Я понимаю, что классы разных там языков используют эти подпрограммы.
Но прочитав вашу статью я так и не понял как именно используются сами подпрограммы этой библиотеки.
Во первых — это интереснее, во вторых в голове сразу становится яснее понимание работы компьютера.
К сожалению, я не могу по другому лучше понять использование библиотек API.
ДА И НЕ ХОЧУ В ПРИНЦИПЕ. ВОТ. Где я могу узнать об использовании подпрограмм библиотеки gdiplus32.dll чтобы мне меньше всего начисляло по трафику?
Ну очень хочется узнать как использовать сами подпрограммы.
Представьте себе, если программа составляется на АССЕМБЛЕРЕ, где нет этих классов.
Там нужно записывать в стек определенные параметры инструкциями процессора например
push eax
и затем вызывать нужную подпрограмму библиотеки инструкцией, например
call GdipBitmapSetPixel
Вот так например я могу на АСМе вызвать функцию SetDIBitsToDevice
библиотеки gdi32.dll
Я считаю, что такой путь использования функций графических библиотек понятнее.
Я серьезно говорю. Пусть на меня никто не обидится. Так мы же четко понимаем то что происходит в компьютере. А прочитав использование классов я ничего толком не понимаю.
Подобным вышеприведенным методом можно вызывать все 609 функций библиотеки gdiplus.dll.
Даже если возникает необходимость узнать адрес конкретной функции, это можно сделать имея адреса всего двух API-функций
LoadLibrary — находит библиотеку в памяти или загружает ее и возвр. описатель её в регистре eax ЦП
GetProcAddress — возвращает адрес нужной функции в в регистре eax ЦП.
Затем загнать в четырехбайтную ячейку памяти (например переменная addr) этот адрес и вызвать инструкцию
call addr
А ещё меня просто сводит с ума расширения арифметико-логического устройства процессора SSE и SSE2.
Там такие инструкции...! За одну инструкцию можно выполнить сразу четыре арифметические операции.
Кстати, вот можете скопировать в буфер обмена мое творение на встроенном ассемблере C++ Builder.
Тут используются инструкции SSE2. Я добился ими ускорения вычисления массива изображения в 8 раз по сравнению с обычними командами процессора.
Есть одно несовершенство — разрезание динамически меняющегося изображения.
Но я думаю что эта проблема будет решена.
Здравствуйте, sgi1981, Вы писали:
S>Но я бы хотел знать вовсе не то какие существуют классы использующие библиотеку gdiplus.dll. S>Мне нужно знать как непосредственно использовать подпрограммы из этой библиотеки. S>Я понимаю, что классы разных там языков используют эти подпрограммы. S>Но прочитав вашу статью я так и не понял как именно используются сами подпрограммы этой библиотеки.
В SDK есть такой файл — GdiPlusFlat.h. Там объявлены все функции API. Можете использовать их напрямую без "классов разных там языков".
Здравствуйте, algol, Вы писали:
A>В SDK есть такой файл — GdiPlusFlat.h. Там объявлены все функции API. Можете использовать их напрямую без "классов разных там языков".
ВОт. Теперь первая часть проблемы отпала. Остается только узнать для чего каждый параметр предназначен, а то предназначение не описано в gdiplusflat.h
Везде и всегда должна быть физическая реальность и должен быть здравый смысл
А кто нибудь слышал, что в GF 7900, 7600 есть "полная аппаратная поддержка всех функция GDI+".
Я вот такое в обзоре этих карточек на IXBT увидел.
И вопрос: Все GDI+ радости на этих картах будут очень быстро рисоваться или я
что-то не так понимаю?
И если это так, то кто-нибудь пробовал?
Проблема в том, что при любом FileName функция SaveBitmap выдаёт результат (tRes) равный FileNotFound.
Неважно, корректное или нет имя файла.
В чём проблема?