Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ?
Контекст задачи: bmp-файл передается по сети на другой компьютер в виде байтового массива. Т.е. на компьютере-приемнике содержимое файла уже находится в памяти.
На ум приходит только вариант с временным файлом (т.е. содержимое памяти сбрасываем в файл, к которому применяем LoadImage штатным образом).
Здравствуйте, Vaynamond, Вы писали:
V>Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ? V>Контекст задачи: bmp-файл передается по сети на другой компьютер в виде байтового массива. Т.е. на компьютере-приемнике содержимое файла уже находится в памяти.
Здравствуйте, Nuzhny, Вы писали:
N>Здравствуйте, Vaynamond, Вы писали:
V>>Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ? V>>Контекст задачи: bmp-файл передается по сети на другой компьютер в виде байтового массива. Т.е. на компьютере-приемнике содержимое файла уже находится в памяти.
N>Просто создать заголовок руками.
Это не совсем то, что нужно. У меня есть полноценный bmp-файл в памяти. Задача — превратить указатель на эту память
в нечто HBITMAP-образное.
Здравствуйте, Vaynamond, Вы писали:
N>>Просто создать заголовок руками. V>Это не совсем то, что нужно. У меня есть полноценный bmp-файл в памяти. Задача — превратить указатель на эту память V>в нечто HBITMAP-образное.
Тогда просто скастить указатели в памяти на PBITMAPINFO, а потом вызвать CreateBitmap (или CreateCompatibleBitmap для конкретного HDC) с твоими данными.
Здравствуйте, Nuzhny, Вы писали:
N>Здравствуйте, Vaynamond, Вы писали:
N>>>Просто создать заголовок руками. V>>Это не совсем то, что нужно. У меня есть полноценный bmp-файл в памяти. Задача — превратить указатель на эту память V>>в нечто HBITMAP-образное.
N>Тогда просто скастить указатели в памяти на PBITMAPINFO, а потом вызвать CreateBitmap (или CreateCompatibleBitmap для конкретного HDC) с твоими данными.
О, завтра попробую.
Здравствуйте, Vaynamond, Вы писали:
V>Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ? V>Контекст задачи: bmp-файл передается по сети на другой компьютер в виде байтового массива. Т.е. на компьютере-приемнике содержимое файла уже находится в памяти. V>На ум приходит только вариант с временным файлом (т.е. содержимое памяти сбрасываем в файл, к которому применяем LoadImage штатным образом).
Функция LoadImage загружает картинку из файла на диске и возвращает дескриптор.
В моём случае файл с картинкой уже загружен в память (как массив байт), и мне нужно каким-то способом
превратить указатель на эту память в дескриптор hBmp.
Здравствуйте, loginx, Вы писали:
L>Здравствуйте, Vaynamond, Вы писали:
V>>HANDLE hBmp = LoadImage(NULL, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
L>интересно, что аналогичная проблемка с запуском ехе на исполнение из памяти, а не с диска...
Возможно, для exe-файла ограничение связано с безопасностью, а вот что помешало для LoadImage сделать
режим LR_LOADFROMMEM, для меня загадка...
Здравствуйте, Vaynamond, Вы писали:
V>Здравствуйте, loginx, Вы писали:
L>>Здравствуйте, Vaynamond, Вы писали:
V>>>HANDLE hBmp = LoadImage(NULL, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
L>>интересно, что аналогичная проблемка с запуском ехе на исполнение из памяти, а не с диска... V>Возможно, для exe-файла ограничение связано с безопасностью, а вот что помешало для LoadImage сделать V>режим LR_LOADFROMMEM, для меня загадка...
вряд ли с безопасностью — так как визуал бэйсик может из текста исполнять и диск форматнуть, ну и C# рефлексия тоже есть
это скорее какая-то религиозная догма у некрософта — все что угодно только не из памяти
Здравствуйте, uuuser, Вы писали:
U>Здравствуйте, Vaynamond, Вы писали:
U>>>куда загрузить? gdi/dgi+/wic/dx ? V>>Сейчас используется такой алгоритм (схематично): V>>HANDLE hBmp = LoadImage(NULL, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
U>ну тогда
U>GlobalAlloc U>GlobalLock U>CreateStreamOnHGlobal U>Bitmap::FromStream() U>Bitmap::GetHBITMAP()
U>тут пример кода, кусок по получению адреса из ресурса выкинуть U>https://www.codeproject.com/Articles/3537/Loading-JPG-PNG-resources-using-GDI
Я смотрел варианты на GDI+, там это можно сделать проще. Меня интересует "чистый" WIN API.
Нашел такой вариант.
В моем случае почти работает. Почему почти — картинка выводится, но в каком-то виде, напоминающем инверсию + часть
сползших цветов.
Здравствуйте, Vaynamond, Вы писали: V>Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ?
Можно создать IStream с помощью CreateStreamOnHGlobal и скормить его в OleLoadPicture.
Получим IPicture, у которой есть Handle, его можно скастить в HBITMAP.
OleLoadPicture поддерживает bmp, gif и jpeg, но не png
Здравствуйте, Vaynamond, Вы писали:
V>В моем случае почти работает. Почему почти — картинка выводится, но в каком-то виде, напоминающем инверсию + часть V>сползших цветов.
Какой формат данных ? 32bpp ? 24 bpp ?
Если 24 bpp — строки выровнены на DWORD ?
The scan lines must be aligned on a DWORD except for RLE-compressed bitmaps.
Здравствуйте, qaz77, Вы писали:
Q>Здравствуйте, Vaynamond, Вы писали: V>>Подскажите, плз, существует-ли элегантный способ загрузки bmp-картинки, которая находится не в файле, а в памяти ?
Q>Можно создать IStream с помощью CreateStreamOnHGlobal и скормить его в OleLoadPicture. Q>Получим IPicture, у которой есть Handle, его можно скастить в HBITMAP.
Q>OleLoadPicture поддерживает bmp, gif и jpeg, но не png
Вообщем, пришлось выкрутиться с помощью GDI+. Но заработало сходу.
Здравствуйте, Vaynamond, Вы писали:
Q>>OleLoadPicture поддерживает bmp, gif и jpeg, но не png V>Вообщем, пришлось выкрутиться с помощью GDI+. Но заработало сходу.
костыли с ручным парсингом bmp проиграли... а гонору-то...
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Vaynamond, Вы писали:
V>>В моем случае почти работает. Почему почти — картинка выводится, но в каком-то виде, напоминающем инверсию + часть V>>сползших цветов.
PD>Какой формат данных ? 32bpp ? 24 bpp ?
8 bpp
Картинка в градациях серого.
Здесь один элемент в массиве вроде как, но это неверно. Их количество в BITMAPINFOHEADER.biClrUsed, и надо все их установить. А в примере , что ты взял, только один поставлен.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Vaynamond, Вы писали:
V>>8 bpp V>>Картинка в градациях серого.
PD>Тогда надо палитру настроить
PD> RGBQUAD bmiColors[1];
PD>https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-tagbitmapinfo
PD>Здесь один элемент в массиве вроде как, но это неверно. Их количество в BITMAPINFOHEADER.biClrUsed, и надо все их установить. А в примере , что ты взял, только один поставлен.
Конструкция bmiColors[1] предполагает, что bmiColors является началом массива RGBQUAD,
который размещается в bmp-файле за заголовками. Подозреваю, что нужно было попробовать наложить
BITMAPINFO на начало BITMAPINFOHEADER.
Здравствуйте, Vaynamond, Вы писали:
L>>интересно, что аналогичная проблемка с запуском ехе на исполнение из памяти, а не с диска... V>Возможно, для exe-файла ограничение связано с безопасностью, а вот что помешало для LoadImage сделать V>режим LR_LOADFROMMEM, для меня загадка...