Здравствуйте, Аноним, Вы писали:
А>Возник вопрос по использованию GDI+ А>Проблема в том, что при любом FileName функция SaveBitmap выдаёт результат (tRes) равный FileNotFound. А>Неважно, корректное или нет имя файла.
Здесь ошибка в том, что GetRawFormat() получает GUID формата изображения (котороый сохраняется в переменной Main, как я понял), а в методе Save() нужно указывать CLSID энкодера для нужного формата изображения, а не сам формат. В MSDN для получения CLSID энкодера приводится функция GetEncoderClsid(), которую легко переделать, чтобы находить CLSID не по MimeType (как в примерах), а по FormatID.
И еще, BSTR в Save() не требуется, в функциях GDI+ обычно используются просто WCHAR*.
Re[3]: GDI+: графика нового поколения
От:
Аноним
Дата:
08.04.06 14:03
Оценка:
Здравствуйте, algol, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Возник вопрос по использованию GDI+ А>>Проблема в том, что при любом FileName функция SaveBitmap выдаёт результат (tRes) равный FileNotFound. А>>Неважно, корректное или нет имя файла.
A>Здесь ошибка в том, что GetRawFormat() получает GUID формата изображения (котороый сохраняется в переменной Main, как я понял), а в методе Save() нужно указывать CLSID энкодера для нужного формата изображения, а не сам формат.
Большое спасибо!! Я торопился и перепутал
теперь всё работает.
В MSDN для получения CLSID энкодера приводится функция GetEncoderClsid(), которую легко переделать, чтобы находить CLSID не по MimeType (как в примерах), а по FormatID.
Взгляну. A>И еще, BSTR в Save() не требуется, в функциях GDI+ обычно используются просто WCHAR*.
Это просто привычка.
Огромное спасибо. Очень торопился и всё напутал.
FonBalrog
ВБ>Авторы: ВБ> Виталий Брусенцев
ВБ>Аннотация: ВБ>В статье рассмотрена работа с растрами средствами GDI+ — новой библиотеки от Microsoft. Описываются методы создания растров из внешних источников, их взаимодействие с устройствами вывода и работа с графическими файлами.
Хорошо.
Я прочитал эту статью и нашел все АПИ-функции, действия которых соответствует действиям классов, примеры работы с которыми описаны в статье.
Но просматривая АПИ-функции включаемого файла я нашел интересную особенность этой библиотеки.
В ней есть функции предназначенные для загрузки изображений из файлов.
Пока я нашел вот такие из этих функций.
GdipLoadImageFromStream(IStream* stream, GpImage **image);
Загружают изображение image из потока.
GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
Загружают изображение image из файла.
GdipLoadImageFromStreamICM(IStream* stream, GpImage **image);
Загружают изображение image из потока используя ICM.
GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename, GpImage **image);
Загружают изображение image из файла, используя ICM.
Приведенные выше функции читают файл или поток на предмет нахождения изображения в нем,
распознают декомпрессор этого изображения,
выделяют блок памяти для указателя *image (в саму функцию передается уже указатель на указатель на будущий блок памяти, тем самым обеспечивается возврат значения указателя), в котором содержится некоторый объект хранящий все пикселыизображения и све его свойства.
Это понятно.
Но в этой же библиотеке есть ещё и такие функции для загрузки изображений из файлов
GdipCreateBitmapFromStream(IStream* stream, GpBitmap **bitmap);
загружает BITMAP из потока
GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
загружает BITMAP из файла
GdipCreateBitmapFromStreamICM(IStream* stream, GpBitmap **bitmap);
загружает BITMAP из потока методом ICM
GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
загружает BITMAP из файла методом ICM
Эти функции уже загружают изображение не в объект image, а в объект BITMAP.
Возникает вопрос.
А чем отличаются друг от друга эти объекты ?
Ну думая, над этим вопросом, я пришел к мысли о нескольких различиях.
Во первых BITMAP — это объект содержащий меньше информации об изображении, чем объект image.
Но если допустить (может я не прав), что оба эти объекта хранят значения пикселов изображения, а не его сжатый вид,
то зачем создавать дополнительный "урезанный" объект BITMAP ? Ведь image содержит все то же самое и даже больше.
Ещё один вопрос в том, как перевести image в BITMAP. Функций прямого перевода я не нашел во включаемом файле.
Дело в том, что мне нужно получить прямой доступ к пикселам изображения в сжатом формате из файла.
Функции, которая бы давала массив значений цветов пикселов из объекта image я не нашел.
Я нашел только нужную функцию, которая дает этот массив из объекта BITMAP.
GdipBitmapLockBits(GpBitmap* bitmap,
GDIPCONST GpRect* rect,
UINT flags,
PixelFormat format,
BitmapData* lockedBitmapData);
Значит для загрузки изображения нужно применить функцию GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
Но если файл содержит несколько кадров, а не один, то как мне получить в массиве пикселов только нужный кадр ?
Везде и всегда должна быть физическая реальность и должен быть здравый смысл
Здравствуйте, sgi1981, Вы писали:
S> .....? ... ? .....................?
Возможно, я Вас очень сильно удивлю, если подскажу, что кроме подключаемых файлов и вышеупомянутой статьи есть такой ресурс в инете, как msdn.microsoft.com. И там есть ответы на все Ваши вопросы: и про отличие Image от Bitmap, и про доступ к отдельным пикселям, и про многокадровые изображения, и даже на те вопросы, которые у Вас ещё не возникли. Так что, смелее!
Здравствуйте, romson, Вы писали:
R>Здравствуйте, sgi1981, Вы писали:
S>> .....? ... ? .....................?
R>Возможно, я Вас очень сильно удивлю, если подскажу, что кроме подключаемых файлов и вышеупомянутой статьи есть такой ресурс в инете, как msdn.microsoft.com.
Я хорошо знаю, что этот ресур есть.
Но :
во первых — веб страницы того сайта имеют большой размер и мне на денежный балланс за интернет идет большое уменьшение,
во вторых — язык мне тот не родной, думать я на нем не собираюсь и не хочу,
в третьих — для чего создавался тогда сайт http://rsdn.ru если есть сайт http://msdn.com ?
Может и всех форумчан так можно послать на http://msdn.com ?
Чего они забивают вопросами этот сайт, если на майкрософтовском сайте инфы дочЁрта ?
Вот пусть и читают там.
Кто что думает об этом... ?
Везде и всегда должна быть физическая реальность и должен быть здравый смысл
Здравствуйте, sgi1981, Вы писали:
S>во первых — веб страницы того сайта имеют большой размер и мне на денежный балланс за интернет идет большое уменьшение,
Есть еще оффлайновая версия MSDN, ставится на компьютере.
S>во вторых — язык мне тот не родной, думать я на нем не собираюсь и не хочу,
Думать не надо, а читать все-таки придется.
S>Кто что думает об этом... ?
Если по существу вопроса, то Image (GpImage) это базовый класс для Bitmap (GpBitmap) и Metafile (GpMetafile). Функции Image поддерживают оба типа изображений. Тип конкретного экземпляра можно узнать через GdipGetImageType(). Если тип ImageTypeBitmap, то GpImage* может быть приведен к GpBitmap* и использован в функциях Bitmap. GpBitmap* может быть использован везде как GpImage*.
Если вы посмотрите исходники класса Bitmap, то увидите, что указатель на GDI+ объект определен в базовом классе Image как GpImage* nativeImage. В конструкторах туда пишется GpBitmap*, а в методах Bitmap он приводится обратно в GpBitmap*:
static_cast<GpBitmap*>(nativeImage)
Для работы с отдельными пикселами есть GdipBitmapLockBits() и GdipBitmapGetPixel()/GdipBitmapSetPixel().
Для выбора нужного кадра можно использовать GdipImageGetFrameCount() и GdipImageSelectActiveFrame().
Здравствуйте, sgi1981, Вы писали:
S>Я хорошо знаю, что этот ресур есть. S>Но : S>во первых — веб страницы того сайта имеют большой размер и мне на денежный балланс за интернет идет большое уменьшение, S>во вторых — язык мне тот не родной, думать я на нем не собираюсь и не хочу, S>в третьих — для чего создавался тогда сайт http://rsdn.ru если есть сайт http://msdn.com ? S>Может и всех форумчан так можно послать на http://msdn.com ? S>Чего они забивают вопросами этот сайт, если на майкрософтовском сайте инфы дочЁрта ? S>Вот пусть и читают там. S>Кто что думает об этом... ?
Т.е. Вы хотите, чтобы кто-то за Вас полез на MSDN, нашёл нужную инфу, перевёл её на Ваш родной язык и выложил Вам на блюдечке? Оригинально! Я думаю, Вам всё же не помешает потратить немного Вашего драгоценного интернетного баланса на прочтение рекомендаций данного форума:
Прежде, чем задавать технический вопрос по электронной почте или в дискуссионную группу, в чате или на форуме, сделайте следующее:
1. Попытайтесь найти ответ с помошью поиска в Web.
2. Попытайтесь найти ответ в руководстве.
...
Здравствуйте, algol, Вы писали:
A>Если по существу вопроса, то Image (GpImage) это базовый класс для Bitmap (GpBitmap) и Metafile (GpMetafile). Функции Image поддерживают оба типа изображений. Тип конкретного экземпляра можно узнать через GdipGetImageType(). Если тип ImageTypeBitmap, то GpImage* может быть приведен к GpBitmap* и использован в функциях Bitmap. GpBitmap* может быть использован везде как GpImage*.
ВОТ СПАСИБО !
Теперь я проверил на АСМЕ.
Вместо объекта image можно задавать функции вывода изображения GdipDrawImageI объект bitmap.
push offset graphics;указатель на указатель на будущий объект graphics
push WND;описатель окна
call GdipCreateFromHWND;создать объект graphics по описателю WND окна
push offset bitmap1;теперь будем создавать объект bitmap1 (БИТМАП) из файла, имя которого
push ps1;здесь
call GdipCreateBitmapFromFile;читаем файл и создаем БИТМАП
push y3;а теперь будем выводить БИТМАП в окно - пишем в стек координаты начала вывода
push x3;
push bitmap1;задаем наш БИТМАП
push graphics;задаем объект graphics, в который выводится будет
call GdipDrawImageI;и WINDOWS рисует в нашем окне изображение
push 0;
push graphics;
call GdipFlush;
A>Для работы с отдельными пикселами есть GdipBitmapLockBits() и GdipBitmapGetPixel()/GdipBitmapSetPixel(). A>Для выбора нужного кадра можно использовать GdipImageGetFrameCount() и GdipImageSelectActiveFrame().
Да, ещё буду экспериментировать.
Везде и всегда должна быть физическая реальность и должен быть здравый смысл
Re[5]: GDI+: графика нового поколения
От:
Аноним
Дата:
12.04.06 12:06
Оценка:
Здравствуйте, algol, Вы писали:
A>Для работы с отдельными пикселами есть GdipBitmapLockBits() и GdipBitmapGetPixel()/GdipBitmapSetPixel(). A>Для выбора нужного кадра можно использовать GdipImageGetFrameCount() и GdipImageSelectActiveFrame().
написано
...
При этом, если указать формат временного буфера (PixelFormat), отличный от формата исходного растра, вызовы LockBits/UnlockBits потребуют дополнительных преобразований.
...
Так вот, незнаю, как на самом деле работает функция LockBits у класса.
Но когда я загружал 8-битный BMP-файл функцией
GdipCreateBitmapFromFile
и потом пытался преобразовать формат пикселов из 8-ми битного в 24-битный функцией
GdipBitmapLockBits, то
ничего не получилось и функция GdipBitmapLockBits выдала значение 2 — неправильно задан параметр.
удавалось таким образом выполнять преобразования
из 24-битного формата в 32-битный
из 16-битного в 32-битный.
Но из 8-битного в 32-битный никак та функция не преобразовывает.
Так что мне нужно специально сохранять изображение другим кодеком в файл в другом формате, а потом из файла опять его читать ?
ВБ>Авторы: ВБ> Виталий Брусенцев
ВБ>Аннотация: ВБ>В статье рассмотрена работа с растрами средствами GDI+ — новой библиотеки от Microsoft. Описываются методы создания растров из внешних источников, их взаимодействие с устройствами вывода и работа с графическими файлами.
Преогромнейшее спасибо! Статья помогла мне разобраться с возможностями этой графической библиотеки, особенно признателен за приложение — пример. Респект и уважуха!