Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Вывод bmp файла


Автор: MacTep 15.5.2005, 13:12
Привет! Помогите с вопросом: как вывести на экран bmp файл. Работаю в Visual Studio 2003 .NET Проект - Win32 Project. Заранее спасибо!

Автор: Fixin 15.5.2005, 20:03
Как вывести? BitBlt(...). Может ты имеешь ввиду как загрузить?

Автор: MacTep 16.5.2005, 21:12
Цитата
Может ты имеешь ввиду как загрузить?
Ну и как же загрузить? smile

Автор: Fixin 16.5.2005, 22:18
Код
case WM_ONCREATE:
    hBitmap = LoadImage(NULL,"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
break;
case WM_ONPAINT:
{
    PAINTSTRUCT ps;
    BITMAP Bitmap;
    HDC hdc=BeginPaint(hwnd,&ps); 
    GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
    hCompartibleDC = CreateCompatibleDC(hdc);
    hOldBitmap = SelectObject(hCompartibleDC,hBitmap);
    GetClientRect(hwnd,&Rect);
    BitBlt(hdc,0,0,Rect.right,Rect.bottom,hCompartibleDC,0,0,SRCCOPY);
    SelectObject(hCompartibleDC,hOldBitmap);
    DeleteDC(hCompartibleDC);
    EndPaint(hwnd,&ps);
}
break;

HBITMAP hBitmap объявлена глобально в данном случае.
Есть класс на винапи, чтоб джипеги грузила и гифы тоже. Нужно?

Автор: gepard 17.5.2005, 05:54
Грузишь *.bmp файл, затем, имея массив цветов пикселей, выводишь их через CPaintDC на форме, например.

Автор: Fixin 17.5.2005, 17:04
Цитата
выводишь их через CPaintDC
Это уже не ВинАпи.

Автор: MacTep 17.5.2005, 21:02
Цитата
имея массив цветов пикселей
вот именно это мне и нужно получить! Как можно это сделать? Подскажите, плиз! smile

Автор: Fixin 17.5.2005, 21:50
Цитата
вот именно это мне и нужно получить
С этого начинать надо было. GetPixel используй.

Автор: Fixin 17.5.2005, 22:01
Код
COLORREF Mass[][];
for()
for()
Mass[i][j] = GetPixel(BitmapDC, i, j);

Автор: gepard 18.5.2005, 06:40
Цитата(Fixin @ 17.5.2005, 17:04)
Это уже не ВинАпи.

Может на MFC хотел сказать? smile

Автор: Fixin 18.5.2005, 17:36
Да хоть ОВЛ, все равно не Апи. А раздел по !!!Апи!!!

Автор: Дрон 24.5.2005, 03:43
Fixin
Через GetPixel задолбаешься получать smile

Есть какая-то функции GetDIBits или что вроде того... сейчас уже не помню. Правда новичок в ней вряд ли сможет разобраться smile

Автор: Знак 27.5.2005, 17:20
Нужно знать как бмп устроен, а с выводм на поток но проблем если есть ссылка на формат BMP киньте и мне.....



Автор: ManiaK 27.5.2005, 19:07
Могу кинуть к понедельнику. Сам выводил, загружал - ничего сложного нет.

Автор: ManiaK 29.5.2005, 14:57
Так, сканера под рукой нет, текст с книги под чистую сдирать не охота. Потому пишу сразу алгоритм загрузки.

Итак, строение BMP файла:

BITMAPFILEHEADER bmfh;// 14 байт
BITMAPINFOHEADER bmih;// 40 байт
RGBQUAD aColors[];
BYTE aBitmapBits[];

Теперь отдельно каждую:
Код

typedef struct tagBITMAPFILEHEADER {
    UINT bfType;
    DWORD bfSize;
    UINT bfReserved1;
    UINT bfReserved2;
    DWORD bfOffBits;
} BITMAPFILEHEADER;

bfType - содержит ASCII-символы 'B' и 'M'.
bfSize - размер файла в байтах
bfReserved1, bfReserved2 - не используются.
bfOffBits - байтовое смещение до начала растрового изображения (до начала aBitmapBits).

Эту структуру мы грузим целиком от начала файла и проверяем, чтобы поля согласовывались с действительностью. Следом за ней идёт ещё одна структура:
Код

struct BITMAPINFOHEADER {
    DWORD biSize;// обязан содержать 0x28 - размер структуры


    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
};


Поскольку времени на поиск/перепечать мало, даю текст со своей же статьи про ручную загрузку иконок. Разница в дальнейшем между иконками и BMP файлами только в одном - у BMP нет масочного массива (дополнительное чёрнобелое изображение, которое показывает какие биты рисовать, а какие - нет).

Статья http://www.dev.vitgroup.com/print.php?sid=184.

Автор: Еррор 30.5.2005, 13:34
Как работает PatBit() smile

Автор: Fixin 7.6.2005, 21:37
Цитата
Fixin
Через GetPixel задолбаешься получать
Согласен. smile

Цитата
Статья тут.
Cсылка неработает smile smile smile
Мне нужно получить, имея бмп файл и его палитру (8 бит изображение), массив COLORREF`ов.
Пробовал так:
Код
COLOREF * Data = new COLORREF[x*y];
        for (i = 0; i < x*y; i++)
        {            
            Data[i] = *(COLORREF*)(&Pal[ImgData[i]]);
        }
Картинку узнать можно, но выводится она, мягко говоря, плохо. Скорее всего, я не понимаю, как использовать палитру. Объясните, в чем беда?

Автор: ManiaK 9.6.2005, 12:02
Палитру использовать неправильно невозможно smile
В чём "плохость" выводимой картинки?
Желательно брось весь код загрузки - я его проверю.
Добавлено @ 12:06
Ёлки, на кой создавать отдельный топик??..
Запутал блин smile

Автор: Иван4444 19.8.2008, 13:06
Здравствуйте. у меня такая проблемка: имееется изображение формата .ico , хотелось бы ее загрузить и отобразить на экране.
 подскажите как это делается?..
 просмотрел предыдущие темы в форуме не помогло ((

Автор: Andrey44 19.8.2008, 13:48
Код

HICON hIco = (HICON)LoadImage(.............);

DrawIconEx(...............);

Автор: Dem_max 19.8.2008, 19:08
Fixin, 
Цитата

Есть класс на винапи, чтоб джипеги грузила и гифы тоже. Нужно?

Кинь куда нить пожалуйста, посмотрю.

Автор: Andrey44 20.8.2008, 07:20
Цитата(Dem_max @  19.8.2008,  19:08 Найти цитируемый пост)
Fixin, 
Цитата

Есть класс на винапи, чтоб джипеги грузила и гифы тоже. Нужно?

Кинь куда нить пожалуйста, посмотрю. 




Dem_max, это GDI+ 
Код

Gdiplus::Image* img;
img = Gdiplus::Image::FromFile(..................);

Gdiplus::Graphics gr(hdc);
gr.DrawImage(img, 0, 0);

Автор: Dem_max 20.8.2008, 08:24
Andrey44, 
К сожалению у мня на Builder 6.0 GDI+ так и не захотел завестися.
вот топик http://forum.sources.ru/index.php?showtopic=152783

Автор: Andrey44 21.8.2008, 07:23
Dem_max, а ты делаешь при запуске проги такое:
Код

ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


а при выходе такое:
Код

GdiplusShutdown(gdiplusToken);


Если да, тогда не знаю в чем проблема!

Автор: Dem_max 21.8.2008, 08:49
Andrey44, 
Может у тебя проектик под Builder 6.0 имеется ? с GDI+. Скинь я посмотрю, зато я буду точно знать что у когото работает и искать траблы у себя.

Автор: Andrey44 21.8.2008, 08:56
Dem_max, нет, только VS. Builder 6.0 - никогда не пользовался.

Автор: Annihilator 21.8.2008, 15:10
Я так понял, есть файл bmp. Его надо вывести в окошко. Если так, то держи пример, через двойную буферизациюsmile . 
Код

#include <windows.h>
LRESULT CALLBACK DCDemoWndProc(HWND, UINT, UINT, LONG);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR lpCmdLine,int nCmdShow)
{
    HWND hWnd;
    WNDCLASS WndClass;
    MSG Msg;
    char szClassName[] = "DCDemo"; 
    /* Заполняем структуру типа WNDCLASS */
    WndClass.style = CS_HREDRAW|CS_VREDRAW;
    WndClass.lpfnWndProc = DCDemoWndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = "MyMenu";
    WndClass.lpszClassName = szClassName;
    if ( ! RegisterClass (&WndClass) ) /* Регистрируем создаваемые класс    */
    {
        MessageBox(NULL,"Cannot register class","Error",MB_OK);
        return 0;
    }
    
    hWnd = CreateWindow(szClassName, "Program #1",
                    WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,
                    CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance,NULL);
    if (!hWnd)
    {
        MessageBox(NULL,"Cannot create window","Error",MB_OK);
        return 0;
    }
    /*Покажем наше окно*/
    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);
    /*Начало цикла сообщений*/
    while(GetMessage(&Msg,NULL, 0, 0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg) ;
    }
    return Msg.wParam;
}
LRESULT CALLBACK DCDemoWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam)
{
    HDC hDC, hCompatibleDC;
    PAINTSTRUCT PaintStruct;
    HANDLE hBitmap, hOldBitmap;
    RECT Rect;
    BITMAP Bitmap;
    switch (Message)
    {
        case WM_PAINT:
            hDC = BeginPaint(hWnd,&PaintStruct); // Получаем контекст устройства
            // загружаем bitmap, который будет отображаться в окне, из файла
            hBitmap = LoadImage(NULL,"foto.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
            GetObject(hBitmap,sizeof(BITMAP),&Bitmap); // получаем размер загруженного bitmap`а
            // создаем совместимый с контекстом окна контекст в памяти
            hCompatibleDC = CreateCompatibleDC(hDC);
            // делаем загруженный из файла bitmap текущим в совместимом контексте
            hOldBitmap = SelectObject(hCompatibleDC,hBitmap);
            GetClientRect(hWnd,&Rect); // Определяем размер рабочей области окна
            // Копируем bitmap с совместимого в основной контекст с масштабированием
            StretchBlt(hDC,0,0,Rect.right,Rect.bottom,hCompatibleDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,SRCCOPY);
            // вновь делаем старый bitmap текущим
            SelectObject(hCompatibleDC,hOldBitmap);
            DeleteObject(hBitmap); // удаляем загруженный с диска bitmap
            DeleteDC(hCompatibleDC); // Удаляем совместимый контекст
            // Освобождаем основной контекст, завершая перерисовку рабочей области окна
            EndPaint(hWnd,&PaintStruct);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd,Message,wParam,lParam);
}

Автор: Dem_max 21.8.2008, 17:42
Цитата

DeleteObject(hBitmap); // удаляем загруженный с диска bitmap

Прям страшно становиться за такую функцию
ди и вообще
Цитата

        case WM_PAINT:
            // загружаем bitmap, который будет отображаться в окне, из файла
            hBitmap = LoadImage(NULL,"foto.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
 
Загружать файл в этом сообщении самый наилучший способ.


Автор: Annihilator 22.8.2008, 18:38
Цитата(Dem_max @  21.8.2008,  21:42 Найти цитируемый пост)
Прям страшно становиться за такую функцию

Ну не так выразился. Конечно файл-то сам на месте. Удаляем хэндл.

Цитата(Dem_max @  21.8.2008,  21:42 Найти цитируемый пост)
Загружать файл в этом сообщении самый наилучший способ.

Конечно не лучший, совсем не лучший. Это просто учебный пример из книги Румянцева, который я в целях обучения разбирал.

Автор: Dem_max 22.8.2008, 18:56
Цитата

Конечно не лучший, совсем не лучший. Это просто учебный пример из книги Румянцева, который я в целях обучения разбирал.

А потом у нас корявые программы программы появляются, потомучто учились на корявых примерах.

Автор: Annihilator 27.8.2008, 05:21
Цитата(Dem_max @  22.8.2008,  22:56 Найти цитируемый пост)
А потом у нас корявые программы программы появляются, потомучто учились на корявых примерах

А вот тут уже понадобится включать мозг, чтобы уменьшить корявости  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)