Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Сохрание BMP файла |
Автор: Евгений 19.5.2007, 19:50 |
Всем доброго дня! Уважемые программисты, подскажите как сохранить изображение в BMP файл из имеющегося битмапа! Если можно примерчик! Или функии для этого! Пишу на WinApi. За ранее благодарю и низко кланяюсь! |
Автор: jonie 19.5.2007, 22:04 | ||
|
Автор: ZC1989 19.5.2007, 22:24 |
Евгений, а разве fwrite уже не работает? |
Автор: Евгений 19.5.2007, 23:32 |
Я имел ввиду как записать эти структуры BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; RGBQUAD aColors[]; BYTE aBitmapBits[]; в файл и как их заполнить? |
Автор: Евгений 19.5.2007, 23:43 |
Верно, который создается CreateBitmap! Добавлено через 8 минут и 21 секунду Я понял что структура файла BMP состоит из следущих структур: BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; RGBQUAD aColors[]; BYTE aBitmapBits[]; так перед записью в файл их необходимо какимто образом заполнить, каждой переменной своё! Так вот подскажите как это сделать! |
Автор: Alexeis 19.5.2007, 23:52 |
Тогда сначала нужно извлечь битовую карту. А потом последовательно заполнять структуры и писать их, после записи табицы цветов записать битовую карту и выровнять то что получилось на границу 4х байт. Проблема в записи структур в файл? Добавлено через 2 минуты и 59 секунд О значении каждого из полей и о том что туда писать можно подробно прочитать тут. http://forum.vingrad.ru/index.php?show_type=forum&showtopic=94227&hl= |
Автор: Евгений 19.5.2007, 23:56 | ||
Вот я попробовал сделать как понял из прочитанного из книги:
Исправте пожалуйста если чтото напутал! |
Автор: Alexeis 20.5.2007, 00:07 | ||
bitinfoh.biBitCount =24; это беспалитровый формат так что bitfileh.bfOffBits =sizeof(BITMAPFILEHEADER)+(sizeof(BITMAPINFOHEADER)*24)+sizeof(RGBQUAD); Абсолютно неверно. Верно будет bitfileh.bfOffBits =sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) дальше fwrite(&mBits,sizeof(mBits),1,File); mBits - это указатель, его размер всегда 4 байта, а нужна длинна массива в байтах fwrite(&hColor,sizeof(hColor),1,File); - это тоже не нужно. Добавлено через 2 минуты и 27 секунд кстати, к тому же fwrite(&mBits,sizeof(mBits),1,File); &mBits - это же указатель на указатель ![]() |
Автор: 586 20.5.2007, 00:18 |
строка 17: 24-битный битмап не имеет палитры, т.е. массив RGBQUAD писать не нужно строка 28: fwrite(&mBits,Size,1,File); |
Автор: Евгений 20.5.2007, 00:20 | ||
Что то не пойму, так что надо записывать в файл, только это fwrite(mBits,Size,1,File); или BITMAPFILEHEADER и BITMAPINFOHEADER структуры тоже надо?
А как узнать размер файла? |
Автор: Евгений 20.5.2007, 00:50 | ||
Вроде что то в файл уже записывается но изображение не открывается, посмотрите ещё раз код что тут непраильно, у меня предположение что структуры BITMAPFILEHEADER и BITMAPINFOHEADER заполнены неверно!
|
Автор: Alexeis 20.5.2007, 00:58 |
Вроде уже грубых ошибок не видно, кроме отсутствия fclose(File); |
Автор: zkv 20.5.2007, 01:38 |
тут опечатка? |
Автор: 586 20.5.2007, 01:41 |
строка 22: замени BYTE на RGBTRIPLE, или long Size = Bitmap.bmWidthBytes * Bitmap.bmHeight * sizeof(RGBTRIPLE) |
Автор: Alexeis 20.5.2007, 11:12 | ||||
Точно! Выше по коду
Значит Bitmap.bmWidthBytes - это число байт в строке а не ее длина.
А вот это уже не верно. Bitmap.bmWidthBytes * Bitmap.bmHeight * sizeof(RGBTRIPLE) будет в 3 раза больше нужного размера. Да и какой смысл использовать RGBTRIPLE, обработки данных на этом этапе нет, только запись в файл, байты как раз точно отражают размер блока данных. |
Автор: zkv 20.5.2007, 13:54 |
![]() Size правильно определен: так как Bitmap.bmWidthBytes - это длина строки в байтах (уже выровненная) сорри, не заметил, что еще страница есть. |
Автор: Евгений 20.5.2007, 20:55 | ||
Вот немного переделал, теперь хоть размер сохраняемого файла сходится с исходным. Посмотрите как я передел, но всёравно изображение не открывается.
|
Автор: Alexeis 20.5.2007, 21:30 | ||
Была еще одна маленькая ошибочка bitfileh.bfType =Bitmap.bmType; Bitmap.bmType всегда равна нулю а не сигнатуре битмапа Правильно будет bitfileh.bfType = 0x4D42; Вот как только изменил сразу все заработало
|
Автор: zkv 20.5.2007, 21:32 | ||||||
не учитываешь выравнивание строк, может быть ошибка из за этого вылазит тут:
когда не хватает места под растр раньше у тебя правильно было:
А вообще смотри какие значения возвращают функции + GetLastError() юзай |
Автор: Alexeis 20.5.2007, 21:32 |
Евгений, WinHex лучший друг программиста ![]() |
Автор: Евгений 20.5.2007, 21:46 |
Alexeis сделал по твоему коду вроде всё ок, только вот при открытии изображения вне моей программы он пишет "Ошибка при построении изображения". Открыл Paint там кракозябли но изображение! Незнаешь в чем дело? |
Автор: Alexeis 20.5.2007, 22:00 |
Если чесно, то функцией GetBitmapBits я ни разу не пользовался и подозреваю, что она работает как-то по другому. Я всегда использовал GetDibBits. Она точно возвращает растр. Если изображение кривое значит не получил битовую карту. |
Автор: Alexeis 20.5.2007, 22:43 | ||
Таки я был прав эта функция работает для совместимости и битмапы больше 64кб видимо ей не по зубам, кроме того я точно вычислил размер буфера данных исходя из документации а не брал его из структуры (там он дан для цвета 32 бита на пиксел) Вот в итоге получилось так
|
Автор: Евгений 20.5.2007, 23:39 |
Огромное тебе спасибо, Alexeis! Все получилось! Благодаря таким людям и набираешься опыта, разрешишь по всем вопросам обращаться к тебе? |
Автор: Alexeis 21.5.2007, 00:11 | ||
Неа, мне работать тоже нужно, ну хоть иногда ![]() ![]() |
Автор: Евгений 22.5.2007, 20:42 |
Всё равно спасибо! Ещё вопросик, не подскажите что собой представляет mBits, это набор цветов или чего? Про хочу попробовать написать программу самму простую шифрования изображений. Это вообще возможно? Если кто-нибудь знает какой-нибудь простой способ шифрования изображений поделитесь! |
Автор: Alexeis 22.5.2007, 21:20 | ||||
Матрица пикселей, т.е. набор строк, в которых данные о цвете пикселов расположены слева направо, снизу вверх. Это значит что массив начнется не с первой строки а с последней (правда бывают исключения). Цвет это либо самого его значение (верно для форматов 16, 24, 32 бита на пиксел) либо индекс цвета в палитре (верно для форматов 1, 4, 8 бит на пиксел).
А какая разница что шифровать? Файлы все одинаковые, что звук что графика что текст, просто массив байтов.
В Windows есть CryptoApi. Первая ссылка в гугле http://www.cryptopro.ru/cryptopro/documentation/capi.htm |
Автор: Евгений 22.5.2007, 22:19 |
Я имею ввиду чтобы изображение зашифровалось потом его открыл, а там место нормальной картинки всякая чушь. |
Автор: Alexeis 23.5.2007, 09:38 |
Евгений, будет не так просто. Размер шифровки может оказаться больше размера исходных данных, потому вероятно прийдеться перед этим графические данные упаковать, например при помощи библиотеки zLib (идет с виндой), а затем уже зашифровать. Если картинка была со смыслом, а не просто рэндом, то она сожмется неплохо. После шифровки размер блока растра должен получиться меньше исходного, потому для записи понадобиться дописать падинг (т.е. баласт). В MSDN е есть пример использования CryptoApi. Эти методы шифрования проверены и надежны. Т.е. устойчивы при том что алгоритм шифровки/расшифровки известен. http://msdn2.microsoft.com/en-us/library/aa382052.aspx |