Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с BMP-файлами 
:(
    Опции темы
AheFeanare
  Дата 25.12.2006, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



Здраствуйте!!! Помогите начинающему программисту!!! Полазил тут по форуму в поисках ответа на интересующий меня вопрос, но слишком заумно написано, и как начинающему изучать С++ не очень мне дался текст... А вопрос у меня такой: как работать с BMP-файлами в Visual С++??? у меня версия 6.0 стоит, на ней и практикуюсь - миня именно интересует в данный момент как сделать так, чтобы можно было просматривать файлы с таким расширением и потом записывать их же... дома MSDN нетю, искал на сайте который мне советовали - там не нашел... решил обратиться к старичкам в надежде (= Можно просто какие функции нужны для работы с bmp-файлами и какие библиотеки необходимо подключать, а как их юзать я думаю смогу сам выяснить методом научного втыка... (= Заранее спасибо!!! 
З.Ы. Сори, если темка такая с подробным ответом была, я не нашел... (=
PM MAIL   Вверх
zkv
Дата 25.12.2006, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



ну вот, набор функций, который поможет обрисовать картину по работе с BMP'шками, функции брал из книжки, где то что то переделывал, где то что то не доделал, по этому вид у них возможно не самый лучший, но для начала пойдут smile
Код


LPBITMAPINFO        m_pBMI = NULL;    //указатель на информационную структуру
PBYTE                m_pData = NULL;        //указатель на растр


bool LoadBMP(CString FileName)
{
    CFile File; 
    File.Open(FileName, CFile::modeRead); //файл открываем для чтения
    BITMAPFILEHEADER    FI; //для хранения информации 
    File.Read(&FI, sizeof(BITMAPFILEHEADER)); //читаем хидер BMP-шки
    
    if(FI.bfType!= 0x4D42)//"BM" == 0x4D42 ==bitmap image - работаем только с BMP
    { 
        File.Close(); 
        MessageBox(NULL, "Ошибка формата файла","Тип файла не BMP", MB_ICONERROR | MB_OK );    
        return false;
    }

    File.Seek(sizeof(BITMAPFILEHEADER), CFile::begin);//смещаемся к непрочитанному те хидеру растра
    
    m_pBMI=(LPBITMAPINFO)new BYTE[FI.bfOffBits-sizeof(BITMAPFILEHEADER)];//выделяем память под хидер 
    File.Read(m_pBMI, FI.bfOffBits-sizeof(BITMAPFILEHEADER)); //растра и читаем

    if(m_pBMI->bmiHeader.biCompression!=0)//работаем только с несжатыми данными
    { 
        File.Close(); 
        MessageBox(NULL, "Ошибка формата файла","Error - opened file is compressed", MB_ICONERROR | MB_OK );    
    }

    //переход к началу растровых данных
    File.Seek(FI.bfOffBits, CFile::begin);
    LONG DataStrLength = ByteSperLine(    m_pBMI->bmiHeader.biWidth, 
                                                    m_pBMI->bmiHeader.biBitCount);
    if(m_pBMI->bmiHeader.biSizeImage==0)//если неизвестен размер изображения
        m_pBMI->bmiHeader.biSizeImage = DataStrLength * m_pBMI->bmiHeader.biHeight;    

    m_pData= new BYTE[m_pBMI->bmiHeader.biSizeImage]; //выделяем память под растр
    File.Read(m_pData, m_pBMI->bmiHeader.biSizeImage);//читаем его из файла

    File.Close();
    return true;
}

void SaveBMP(CString FileName)
{
    CFile File;
    File.Open(FileName, CFile::modeCreate|CFile::modeWrite); //открываем для записи
    //размер заголовка растра вместе с палитрой
    DWORD SizeOfBMI= (DWORD)m_pBMI->bmiHeader.biSize + 
    m_pBMI->bmiHeader.biClrUsed*sizeof(RGBQUAD);
    
    BITMAPFILEHEADER    FI;
    FI.bfType = 0x4d42;    //формат BMP    
    FI.bfSize = (DWORD) sizeof(BITMAPFILEHEADER) + SizeOfBMI + //размер всего файла
                m_pBMI->bmiHeader.biSizeImage; 
    FI.bfReserved1 = 0; //зарезервированы
    FI.bfReserved2 = 0; //зарезервированы
    FI.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + SizeOfBMI; //смещение до растровых данных
    File.Write(&FI, sizeof(BITMAPFILEHEADER)); //записываем хидер файла
    File.Write(m_pBMI, SizeOfBMI);//записываем все остальное те хидер растра + палитра 
    
    File.Write(m_pData, m_pBMI->bmiHeader.biSizeImage);//+растр
    File.Close();
}

DWORD ByteSperLine(DWORD Width, DWORD BPP) 
{
    DWORD mul    =    Width*BPP; 
    if ( mul%32 )
        return (32-mul%32+mul)>>3;//количество байт в выровненой по DWORD строке
    else
        return mul>>3;
}

//рисуем картинку на контекст
void DrawBitmap(CDC *pDC,    LONG x=0, LONG y=0, LONG cx=0, LONG cy=0,
                                    LONG x0=0, LONG y0=0, LONG cx0=0, LONG cy0=0,
                                    int str_mode=COLORONCOLOR, DWORD rop =SRCCOPY)
{
    if(!m_pBMI|| !m_pData) 
        MessageBox(NULL, "Ошибка формата файла","Error of drawing bitmap - it has not data", MB_ICONERROR | MB_OK );    
    if(cx==0) cx=pBMI->bmiHeader.biWidth;
    if(cy==0) cy=pBMI->bmiHeader.biHeight;
    
    if(cx0==0) cx0=pBMI->bmiHeader.biWidth;
    if(cy0==0) cy0=pBMI->bmiHeader.biHeight;
    HDC  hdc=pDC->GetSafeHdc();
    if(hdc==NULL) return;
    // Установка режима масштабирования
    int oldStretchMode=pDC->SetStretchBltMode(str_mode);
    ::StretchDIBits(hdc,        //дескриптор контекста устройства
        x,    y,    cx,    cy,            // позиция и размеры в области назначения
        x0, y0,    cx0, cy0,        // позиция и размеры в исходной области 
        m_pData,                //данные
        m_pBMI,                    //заголовок растра
        DIB_RGB_COLORS,            // опции говорят что это BMP
        rop);                    // код растровой операции
    if(oldStretchMode!=0)
        pDC->SetStretchBltMode(oldStretchMode);
}


Это сообщение отредактировал(а) zkv - 25.12.2006, 23:43
PM MAIL   Вверх
WERITAS
Дата 25.12.2006, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

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



Вот на WinAPI
Код

# include <windows.h>
//-----------------------------------------------------------------------------------------------
HINSTANCE Instance;
HWND hwnd;
MSG msg;      
WNDCLASS w;  

HBITMAP hBitmap;    //
HDC     hdc;  //


LRESULT WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam);



int WINAPI WinMain(HINSTANCE hInstance,  
                   HINSTANCE hPrevInstance, 
                   LPSTR     lpCmdLine,  
                   int       nCmdShow)   
{
    Instance = hInstance;

    hBitmap = (HBITMAP)LoadImage(0,"riddick.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    hdc = CreateCompatibleDC(0);                                            
    SelectObject(hdc,hBitmap);                                                

    memset(&w, 0, sizeof(WNDCLASS)); 
                                  
    w.style           =    CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    w.lpfnWndProc     =    WndProc; 
    w.hInstance       =    hInstance;
    w.hbrBackground   =    (HBRUSH)GetStockObject(WHITE_BRUSH);
    w.lpszClassName   =    "My Class";
    w.hIcon           =    LoadIcon(NULL,IDI_EXCLAMATION);   
    w.hCursor         =    LoadCursor(NULL,IDC_CROSS);       

    RegisterClass(&w);   
    

    hwnd = CreateWindow("My Class", "RIDDICK",WS_OVERLAPPEDWINDOW, 
                        //250, 200, 550, 400, NULL, NULL, hInstance, NULL);         
                        250, 200, 363, 275, NULL, NULL, hInstance, NULL);         
    
    ShowWindow(hwnd,SW_SHOW);        
    UpdateWindow(hwnd);        

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);       
        DispatchMessage(&msg);
    }

    DeleteDC(hdc);   // 
    DeleteObject(hdc); //
    
    return msg.wParam;  
}
//-----------------------------------------------------------------------------------------------
LRESULT WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch (Message)
        {
        
    case WM_DESTROY:
            {
            PostQuitMessage(0);
            break;
            }
    
    case WM_CLOSE:
            {
            SendMessage(hwnd, WM_DESTROY, NULL, NULL);
            break;
            }

    case WM_PAINT:
            {
            PAINTSTRUCT paint;
            
            BeginPaint(hwnd, &paint); // Подготавливает окно к pаскpаске в ответ на сообщение wm_Paint
         
            BitBlt(paint.hdc,0,0,355,241,hdc,0,0,SRCCOPY); // используется для выполнения операции копирования отдельных битов из области источника изображения в область-получатель
            
            EndPaint(hwnd, &paint); 
            }

    default:
            return DefWindowProc(hwnd, Message, wparam, lparam);
        }
    return 0;
}




--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
Alexeis
Дата 26.12.2006, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Попробуете через CImage (MFC) это по проще должно получиться.


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

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

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


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



Я так понял, что для того чтобы открыть BMP-файл, необходимо сначала узнать его размер, затем его просто тупо считываем и выводим на экран для просмотра, затем если необходимо перезаписать его, то тогда просто перезаписываем его - насколько я понял, хидеры это часть bmp-файла, которую мы считываем и считывая эти хидеры получаем полное изображение - поправьте еси где ошибся... (=
PM MAIL   Вверх
zkv
Дата 26.12.2006, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(AheFeanare @  26.12.2006,  17:25 Найти цитируемый пост)
Я так понял, что для того чтобы открыть BMP-файл, необходимо сначала узнать его размер, затем его просто тупо считываем и выводим на экран для просмотра

чтобы открыть BMP-шку необходимо сначала узнать имя файла, этого достаточно (вам приводили выше пример). Например с CImage дело обстоит так:
Код

 CImage img; 
 img.Load( "example.bmp" );
 img.Save( "example.bmp", ImageFormatBMP );//можно сохранять и в других форматах

а вообще BMP-файл состоит из следующих частей:
1. BITMAPFILEHEADER - хидер файла, здесь метка что файл - bmp, и смещение до растра от начала файла
2. BITMAPINFO - структура включающая в себя хидер растра и палитру, т.е.
Код

struct BITMAPINFO 
{
  BITMAPINFOHEADER biHeader; //тут размеры, количество бит на пиксель и т.д.
  RGBQUAD biColors[1]; //палитра
};

3. растр
это рассказываю потому, что не понимаю сказанного здесь:
Цитата(AheFeanare @  26.12.2006,  17:25 Найти цитируемый пост)
насколько я понял, хидеры это часть bmp-файла, которую мы считываем и считывая эти хидеры получаем полное изображение

хидеры без растра, сами по себе не дают изображения, в них только общие описания. 
PM MAIL   Вверх
AheFeanare
Дата 27.12.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



во, теперь усе понил!!! пафол пробовать че-нить наваять!!! Огромное сенкс всем!!!  smile 
PM MAIL   Вверх
AheFeanare
Дата 6.1.2007, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



Блин усе равно не получаетси написать прогу... могет помочь кто??? как именно в программе должно быть фсе устроено??? а то бьюсь ужо который день...  smile 
PM MAIL   Вверх
zkv
Дата 6.1.2007, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



что именно прога должна делать? что не получается конкретно? где код? 
выкладывай, посмотрим smile 

Это сообщение отредактировал(а) zkv - 6.1.2007, 21:30
PM MAIL   Вверх
AheFeanare
Дата 6.1.2007, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



весь код выше  smile  пробую код:


CImage img; 
 img.Load( "example.bmp" );
 img.Save( "example.bmp", ImageFormatBMP );//можно сохранять и в других форматах

но не работаить, познаний моих не хватаить (= 

а прога должна просто-напросто загружать bmp-файл и потом записывать его (= вся проблема в том что мои познания в графике основываются лишь на том, что я прочитал на этой страничке... (= надеюсь на вашу помощь (=
PM MAIL   Вверх
zkv
Дата 7.1.2007, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



ладно, начнем сначала smile, bmp файл насколько нужен? Необходимо разобраться с его устройством, или просто надо... хм... просто не понимаю зачем нужно файл просто открыть а потом просто закрыть.   Будем считать, что его надо еще и просмотреть, вот попытался сделать как можно более простой проект, там есть недостатки, например мерцание при прорисовке, но это уже совсем другая история, думаю должны появится вопросы, ждемс... smile 

PS естественно просмотреть bmp'шку можно еще неимоверным количеством способов, я пытался найти самый простой с точки зрения новичка smile

Присоединённый файл ( Кол-во скачиваний: 54 )
Присоединённый файл  SimpleBMPViewer.zip 24,93 Kb
PM MAIL   Вверх
AheFeanare
Дата 7.1.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



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

а можно вопрос на чем написано??? у меня в 6 версии не хочет работать... хотя мож я чет не то делаю... но работать не хочет... блин чую зря полез в эти дебри, но разобраться теперь хочется с этим (= 
PM MAIL   Вверх
zkv
Дата 8.1.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(AheFeanare @  7.1.2007,  14:42 Найти цитируемый пост)
а можно вопрос на чем написано???

мда, что то забылся smile визуал 7.1 (2003 студия)
создай проект MFC+MDI+Document/View support (для класса представления укажи базовый CScrollView заместо CView), открывай файлы, ищи отличия, должно что нить получиться smile
PM MAIL   Вверх
AheFeanare
Дата 8.1.2007, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 25.12.2006

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



запустилось (= теперь вопросы: хде должен находиться bmp-файл чтобы можно было его просмотреть??? а то чет указую путь в открыть и ничего, чистый экран... мож файл не туды запихнул??? и как менюшку делать это ладно... меня интересуить сам процесс считывания рисунка.... как он происходит именно??? нигде не нашел проверки на соответствие расширения тому, которое необходимо, выходит этой проверки нет и прога может открыть и jpg файл???  smile пока фсе, остальное уже не соображаетси, спать хосса... и спасибо за помощь!!! с меня причитается  smile 
PM MAIL   Вверх
zkv
Дата 8.1.2007, 03:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(AheFeanare @  8.1.2007,  02:30 Найти цитируемый пост)
нигде не нашел проверки на соответствие расширения тому, которое необходимо
 да я забыл сказать, что при создании каркаса приложения надо было указать тип файла - bmp, но можно сделать это  и сейчас, в редакторе ресурсов открываем String Table, ищем строку 
IDR_SimpleBMPViewerTYPE, надо что бы там появилось нечто такое:
\nSimpleBMPViewer\nSimpleBMPViewer\nBitmap Files (*.bmp)\n.bmp\nSimpleBMPViewer.Document\nSimpleBMPViewer.Document 
но на работоспособность приложения это не влияет, просто не дает пользователю открыть что то левое. 
Цитата(AheFeanare @  8.1.2007,  02:30 Найти цитируемый пост)
хде должен находиться bmp-файл чтобы можно было его просмотреть???

где угодно
Цитата(AheFeanare @  8.1.2007,  02:30 Найти цитируемый пост)
меня интересуить сам процесс считывания рисунка.... как он происходит именно???

смотри внимательно в класс документа, там есть объект класса CImage, при открытии документа в него загружается изображение (виртуальный метод BOOL CSimpleBMPViewerDoc::OnOpenDocument(LPCTSTR lpszPathName)
)
про сохранение документа смотри BOOL CSimpleBMPViewerDoc::OnSaveDocument(LPCTSTR lpszPathName)
подготовка рабочей области и, собственно, сама прорисовка в классе представления, методы 
void CSimpleBMPViewerView::OnInitialUpdate()
и 
void CSimpleBMPViewerView::OnDraw(CDC* pDC)

Цитата(AheFeanare @  8.1.2007,  02:30 Найти цитируемый пост)
прога может открыть и jpg файл???

да, CImage умеет работать с жепегами и не только smile
Цитата(MSDN)

CImage provides enhanced bitmap support, including the ability to load and save images in JPEG, GIF, BMP, and Portable Network Graphics (PNG) formats. 

PS не забудь подключить atlimage.h

PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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