Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сохрание BMP файла, Сохрание BMP файла 
:(
    Опции темы
Alexeis
Дата 20.5.2007, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(zkv @  20.5.2007,  01:38 Найти цитируемый пост)
тут опечатка?

Точно! Выше по коду 
Цитата

  long Size = Bitmap.bmWidthBytes * Bitmap.bmHeight;

  Значит Bitmap.bmWidthBytes - это число байт в строке а не ее длина.

Цитата(586 @  20.5.2007,  01:41 Найти цитируемый пост)
строка 22: замени BYTE на RGBTRIPLE, или long Size = Bitmap.bmWidthBytes * Bitmap.bmHeight * sizeof(RGBTRIPLE) 

А вот это уже не верно. Bitmap.bmWidthBytes * Bitmap.bmHeight * sizeof(RGBTRIPLE) будет в 3 раза больше нужного размера. Да и какой смысл использовать RGBTRIPLE, обработки данных на этом этапе нет, только запись в файл, байты как раз точно отражают размер блока данных.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
zkv
Дата 20.5.2007, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(586 @  20.5.2007,  01:41 Найти цитируемый пост)
ong Size = Bitmap.bmWidthBytes * Bitmap.bmHeight * sizeof(RGBTRIPLE) 

 smile 
Size правильно определен:
Цитата(Евгений @  20.5.2007,  00:50 Найти цитируемый пост)
long Size = Bitmap.bmWidthBytes * Bitmap.bmHeight;

так как Bitmap.bmWidthBytes - это длина строки в байтах (уже выровненная)

сорри, не заметил, что еще страница есть.

Это сообщение отредактировал(а) zkv - 20.5.2007, 13:56
PM MAIL   Вверх
Евгений
Дата 20.5.2007, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 14.6.2006
Где: г. Невинномысск

Репутация: нет
Всего: 1



Вот немного переделал, теперь хоть размер сохраняемого файла сходится с исходным. Посмотрите как я передел, но всёравно изображение не открывается.

Код

            GetObject(hBitm,sizeof(BITMAP),(LPVOID) &Bitmap);
    long Size = Bitmap.bmWidth * Bitmap.bmHeight * sizeof(RGBTRIPLE);

    BITMAPFILEHEADER bitfileh;
    memset(&bitfileh,0,sizeof(BITMAPFILEHEADER));
    bitfileh.bfType            =Bitmap.bmType;
    bitfileh.bfSize            =sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+Size;
    bitfileh.bfReserved1    =0;
    bitfileh.bfReserved2    =0;
    bitfileh.bfOffBits        =sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

    BITMAPINFOHEADER bitinfoh;
    memset(&bitinfoh,0,sizeof(BITMAPINFOHEADER));
    bitinfoh.biSize            =sizeof(BITMAPINFOHEADER);
    bitinfoh.biWidth        =Bitmap.bmWidth;
    bitinfoh.biHeight        =Bitmap.bmHeight;
    bitinfoh.biPlanes        =1;
    bitinfoh.biBitCount        =24;

    BYTE *mBits = new BYTE[Size];
    GetBitmapBits(hBitm, Size, mBits);

    FILE *File;
    File = fopen(szFile,"w");
    fwrite(&bitfileh,sizeof(bitfileh),1,File);
    fwrite(&bitinfoh,sizeof(bitinfoh),1,File);
    
    fwrite(mBits,Size,1,File);
    fclose(File);



Это сообщение отредактировал(а) Евгений - 20.5.2007, 21:09
PM MAIL WWW   Вверх
Alexeis
Дата 20.5.2007, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Была еще одна маленькая ошибочка 
 bitfileh.bfType    =Bitmap.bmType;

Bitmap.bmType всегда равна нулю а не сигнатуре битмапа

Правильно будет
  bitfileh.bfType         = 0x4D42;

Вот как только изменил сразу все заработало
Код

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    HDC DC = GetDC(0);
    HBITMAP hBitm = CreateCompatibleBitmap(DC, 512, 512);

    BITMAP Bitmap;
    GetObject(hBitm, sizeof(BITMAP),(LPVOID) &Bitmap);
    long Size = Bitmap.bmWidth * Bitmap.bmHeight * sizeof(RGBTRIPLE);
    BITMAPFILEHEADER bitfileh;
    memset(&bitfileh,0,sizeof(BITMAPFILEHEADER));
    bitfileh.bfType         = 0x4D42;
    bitfileh.bfSize         = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+Size;
    bitfileh.bfReserved1    = 0;
    bitfileh.bfReserved2    = 0;
    bitfileh.bfOffBits      = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    BITMAPINFOHEADER bitinfoh;
    memset(&bitinfoh,0,sizeof(BITMAPINFOHEADER));
    bitinfoh.biSize         = sizeof(BITMAPINFOHEADER);
    bitinfoh.biWidth        = Bitmap.bmWidth;
    bitinfoh.biHeight       = Bitmap.bmHeight;
    bitinfoh.biPlanes       = 1;
    bitinfoh.biBitCount     = 24;
    BYTE *mBits = new BYTE[Size];
    GetBitmapBits(hBitm, Size, mBits);
    FILE *File;
    char szFile[] = "C:\\1.bmp";
    File = fopen(szFile, "w");
    fwrite(&bitfileh,sizeof(bitfileh),1,File);
    fwrite(&bitinfoh,sizeof(bitinfoh),1,File);

    fwrite(mBits,Size,1,File);
    fclose(File);

    DeleteDC(DC);
}



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
zkv
Дата 20.5.2007, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(Евгений @  20.5.2007,  20:55 Найти цитируемый пост)
    long Size = Bitmap.bmWidth * Bitmap.bmHeight * sizeof(RGBTRIPLE);

не учитываешь выравнивание строк, может быть ошибка из за этого вылазит тут:
 
Цитата(Евгений @  20.5.2007,  20:55 Найти цитируемый пост)
   BYTE *mBits = new BYTE[Size];
    GetBitmapBits(hBitm, Size, mBits);

когда не хватает места под растр

раньше у тебя правильно было:
Код

long Size = Bitmap.bmWidthBytes * Bitmap.bmHeight;


А вообще смотри какие значения возвращают функции + GetLastError() юзай
PM MAIL   Вверх
Alexeis
Дата 20.5.2007, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Евгений, WinHex лучший друг программиста smile . Когда не ясно почему файл кривой, всегда можно открыть в нем файл и просмотреть содержимое.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Евгений
Дата 20.5.2007, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 14.6.2006
Где: г. Невинномысск

Репутация: нет
Всего: 1



Alexeis сделал по твоему коду вроде всё ок, только вот при открытии изображения вне моей программы он пишет  "Ошибка при построении изображения". Открыл Paint там кракозябли но изображение! Незнаешь в чем дело?
PM MAIL WWW   Вверх
Alexeis
Дата 20.5.2007, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(Евгений @  20.5.2007,  21:46 Найти цитируемый пост)
Открыл Paint там кракозябли но изображение! Незнаешь в чем дело?

  Если чесно, то функцией GetBitmapBits я ни разу не пользовался и подозреваю, что она работает как-то по другому. Я всегда использовал GetDibBits. Она точно возвращает растр. Если изображение кривое значит не получил битовую карту.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 20.5.2007, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Таки я был прав эта функция работает для совместимости и битмапы больше 64кб видимо ей не по зубам, кроме того я точно вычислил размер буфера данных исходя из документации а не брал его из структуры (там он дан для цвета 32 бита на пиксел)
Вот в итоге получилось так
Код

void __fastcall TForm1::FormPaint(TObject *Sender)
{
    HDC DC = GetDC(0);
    HBITMAP hBitm = CreateCompatibleBitmap(DC, 512, 512);
    HDC BMP_DC = CreateCompatibleDC(DC);
    SelectObject(BMP_DC, hBitm);
    HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
    SelectObject(BMP_DC, pen);
    LineTo(BMP_DC, 512, 512);

    BITMAP Bitmap;
    GetObject(hBitm, sizeof(BITMAP),(LPVOID) &Bitmap);

    long Size = (Bitmap.bmWidth * ((Bitmap.bmHeight * 3 + 3) / 4 * 4) + 3) / 4 * 4;

    BITMAPFILEHEADER bitfileh;
    memset(&bitfileh,0,sizeof(BITMAPFILEHEADER));
    bitfileh.bfType         = 0x4D42;
    bitfileh.bfSize         = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+Size;
    bitfileh.bfReserved1    = 0;
    bitfileh.bfReserved2    = 0;
    bitfileh.bfOffBits      = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

    BITMAPINFOHEADER bitinfoh;
    memset(&bitinfoh, 0, sizeof(BITMAPINFOHEADER));
    bitinfoh.biSize         = sizeof(BITMAPINFOHEADER);
    bitinfoh.biWidth        = Bitmap.bmWidth;
    bitinfoh.biHeight       = Bitmap.bmHeight;
    bitinfoh.biPlanes       = 1;
    bitinfoh.biBitCount     = 24;
    BYTE *mBits = new BYTE[Size];

    GetDIBits(BMP_DC, hBitm, 0, Bitmap.bmHeight, mBits, (BITMAPINFO*)&bitinfoh, DIB_RGB_COLORS);

    FILE *File;
    char szFile[] = "C:\\1.bmp";
    File = fopen(szFile, "w");
    fwrite(&bitfileh,sizeof(bitfileh),1,File);
    fwrite(&bitinfoh,sizeof(bitinfoh),1,File);
    fwrite(mBits,Size,1,File);
    fclose(File);
    DeleteDC(DC);


    delete[] mBits;
    BitBlt(Canvas->Handle, 0, 0, 512, 512, BMP_DC, 0, 0, SRCCOPY);
    DeleteObject(pen);
    DeleteObject(hBitm);
    DeleteDC(BMP_DC);
}



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Евгений
Дата 20.5.2007, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 14.6.2006
Где: г. Невинномысск

Репутация: нет
Всего: 1



Огромное тебе спасибо, Alexeis! Все получилось! Благодаря таким людям и набираешься опыта, разрешишь по всем вопросам обращаться к тебе? 
PM MAIL WWW   Вверх
Alexeis
Дата 21.5.2007, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(Евгений @  20.5.2007,  23:39 Найти цитируемый пост)
Благодаря таким людям и набираешься опыта, разрешишь по всем вопросам обращаться к тебе?  

  Неа, мне работать тоже нужно, ну хоть иногда  smile . Так что на форум. Когда есть время я все равно тут smile .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Евгений
Дата 22.5.2007, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 14.6.2006
Где: г. Невинномысск

Репутация: нет
Всего: 1



Всё равно спасибо! Ещё вопросик, не подскажите что собой представляет mBits, это набор цветов или чего? Про хочу попробовать написать программу самму простую шифрования изображений. Это вообще возможно? Если кто-нибудь знает какой-нибудь простой способ шифрования изображений поделитесь!
PM MAIL WWW   Вверх
Alexeis
Дата 22.5.2007, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(Евгений @  22.5.2007,  20:42 Найти цитируемый пост)
что собой представляет mBits, это набор цветов или чего? 

  Матрица пикселей, т.е. набор строк, в которых данные о цвете пикселов расположены слева направо, снизу вверх. Это значит что массив начнется не с первой строки а с последней (правда бывают исключения). Цвет это либо самого его значение (верно для форматов 16, 24, 32 бита на пиксел) либо индекс цвета в палитре (верно для форматов 1, 4, 8 бит на пиксел).

Цитата(Евгений @  22.5.2007,  20:42 Найти цитируемый пост)
Про хочу попробовать написать программу самму простую шифрования изображений.


А какая разница что шифровать? Файлы все одинаковые, что звук что графика что текст, просто массив байтов.

Цитата(Евгений @  22.5.2007,  20:42 Найти цитируемый пост)
Если кто-нибудь знает какой-нибудь простой способ шифрования изображений поделитесь! 

  В Windows есть CryptoApi.
Первая ссылка в гугле http://www.cryptopro.ru/cryptopro/documentation/capi.htm


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Евгений
Дата 22.5.2007, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 14.6.2006
Где: г. Невинномысск

Репутация: нет
Всего: 1



Я имею ввиду чтобы изображение зашифровалось потом его открыл, а там место нормальной картинки всякая чушь.
PM MAIL WWW   Вверх
Alexeis
Дата 23.5.2007, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Евгений, будет не так просто. Размер шифровки может оказаться больше размера исходных данных, потому вероятно прийдеться перед этим графические данные упаковать, например при помощи библиотеки zLib (идет с виндой), а затем уже зашифровать. Если картинка была со смыслом, а не просто рэндом, то она сожмется неплохо.  После шифровки размер блока растра должен получиться меньше исходного, потому для записи понадобиться дописать падинг (т.е. баласт).

  В MSDN е есть пример использования CryptoApi. Эти методы шифрования проверены и надежны. Т.е. устойчивы при том что алгоритм шифровки/расшифровки известен. http://msdn2.microsoft.com/en-us/library/aa382052.aspx

Это сообщение отредактировал(а) Alexeis - 23.5.2007, 09:39


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1381 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.