Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Почему-то не сохраняется bmp! Никак не найду проблему!

249
08 марта 2005 года
DissDoc
639 / / 01.10.2004
Код:
#include "stdafx.h"
#include "testBM.h"
#define MAX_LOADSTRING 100
// Макрос для определения количества байт в выровненной по DWORD строке
// BPP - бит на пиксел
#define BYTESPERLINE(Width, BPP) ((WORD)((((DWORD)(Width)*(DWORD)(BPP)+31) >> 5)) << 2)

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
HDC image_dc;

BITMAP bitmap;
HBITMAP hbitmap;

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;
   
    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_TESTBM, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TESTBM);

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, (LPCTSTR)IDI_TESTBM);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = (LPCTSTR)IDC_TESTBM;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    return RegisterClassEx(&wcex);
}

// Сохранение
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp, HWND hWnd)
{
    BITMAP bmp;
    PBITMAPINFO pbmi;
    WORD cClrBits;

    // Получаем размер картинки
    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
    {
        MessageBox(hWnd, "Размер картинки не получен", "Error", MB_ICONERROR|MB_OK);
        return NULL;
    }
   
    if(bmp.bmBitsPixel > 24) bmp.bmBitsPixel = 24;
    cClrBits = (WORD)(bmp.bmBitsPixel);
    if (cClrBits == 1)
        cClrBits = 1;
    else if (cClrBits <= 4)
        cClrBits = 4;
    else if (cClrBits <= 8)
        cClrBits = 8;
    else if (cClrBits <= 16)
        cClrBits = 16;
    else
        cClrBits = 24;

    if (cClrBits < 16)
        pbmi = (PBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) +
                                      sizeof(RGBQUAD) * (1<<cClrBits)];
    else // палитры нет
        pbmi = (PBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];

    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = bmp.bmWidth;
    pbmi->bmiHeader.biHeight = bmp.bmHeight;
    pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
    pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
    pbmi->bmiHeader.biXPelsPerMeter = 0;
    pbmi->bmiHeader.biYPelsPerMeter = 0;

    if (cClrBits < 16)
        pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
    pbmi->bmiHeader.biCompression = BI_RGB;
    pbmi->bmiHeader.biSizeImage =
        BYTESPERLINE(pbmi->bmiHeader.biWidth, cClrBits) * pbmi->bmiHeader.biHeight;
    // Все цвета изображения важны
    pbmi->bmiHeader.biClrImportant = 0;

    return pbmi;
}

BOOL SaveBitmapToBMPFile(char *fName, HBITMAP &BMP, HDC &hDC, HWND hWnd)
{
    HANDLE hf = NULL;         // указатель на файл
    BITMAPFILEHEADER hdr;     // заголовок BMP-файла
    PBITMAPINFOHEADER pbih;   // заголовок картинки
    BYTE *pBits = NULL;       // указатель на растровые данные
    DWORD dwWidthBytes = 0;   // длина строки растровых данных в байтах
    DWORD dwTmp = 0;          // для временный потребностей

    // Создаем структуру - заголовок растра
    PBITMAPINFO pbmi = CreateBitmapInfoStruct(BMP, hWnd);

    pbih = (PBITMAPINFOHEADER) pbmi;
    // Выделим память
    pBits = new BYTE[pbih->biSizeImage];
    if (!pBits)
    {
        MessageBox(hWnd, "Память не выделена", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }

    // Получаем растровые данные
    if (!GetDIBits(hDC, BMP, 0, (WORD) pbih->biHeight, pBits, pbmi, DIB_RGB_COLORS))
    {
        MessageBox(hWnd, "Растровые данные не получены", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }

    hf = CreateFile(fName, GENERIC_READ|GENERIC_WRITE,
                    (DWORD) 0, (LPSECURITY_ATTRIBUTES) NULL,
                    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                    (HANDLE) NULL);
    if (hf == INVALID_HANDLE_VALUE)
    {
        MessageBox(hWnd, "Файл не создан", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }
    hdr.bfType = 0x4d42;
    // Размер всего файла вместе с заголовком и данными
    hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) +
        pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage);
    hdr.bfReserved1 = 0;
    hdr.bfReserved2 = 0;
    // Смещения до начала растровых данных
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
        pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD);

    // Записываем заголовок файла - структуру BITMAPFILEHEADER
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
        (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))
    {
        MessageBox(hWnd, "Заголовок файла не записан", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }
    //... структуру BITMAPINFOHEADER и палитру RGBQUAD
    if (!WriteFile(hf, (LPVOID)pbih, sizeof(BITMAPINFOHEADER) +
        pbih->biClrUsed * sizeof(RGBQUAD),
        (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))
    {
        MessageBox(hWnd, "Записать палитру и структуру не удалось", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }
    //.... растровые данные
    dwWidthBytes = BYTESPERLINE(pbih->biWidth, pbih->biBitCount);
    LONG i = 0, j = 0;
    BYTE *pCurStr = NULL; // указатель на текущую строку
    pCurStr = pBits;
    for(i = 0; i < pbih->biHeight; i++) // записываем по строкам
    {
        if(!WriteFile(hf, (LPSTR) pCurStr, (int) dwWidthBytes,
            (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))
        {
            MessageBox(hWnd, "Не удалось записать строку", "Error", MB_ICONERROR|MB_OK);
            return FALSE;
        }
        pCurStr += dwWidthBytes;
    }

    if (!CloseHandle(hf))
    {
        MessageBox(hWnd, "Файл не закрыт", "Error", MB_ICONERROR|MB_OK);
        return FALSE;
    }

    // Освобождаем память
    if(pBits!=NULL) delete[] pBits;
    if(pbmi!=NULL) delete[] pbmi;
    return TRUE;
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

// Загрузка файла
void LoadBMTrue(HWND hWnd, char *fin)
{
    hbitmap = (HBITMAP)LoadImage(hInst,"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    if (!hbitmap)
        MessageBox(hWnd, "File 1.bmp do not found", "Error", MB_ICONERROR|MB_OK);
    else
    {  
        GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&bitmap);
        HDC hdc = GetDC(hWnd); // Получаем контекст устройства созданного нами окна
        image_dc = CreateCompatibleDC(hdc);
        // При выборе нового объекта, нужно сохранить старый
        HBITMAP old_hbitmap = (HBITMAP)SelectObject(image_dc,hbitmap);
    }
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_about :
            MessageBox(hWnd, "Program by Myhov Kirill. Program is decriptor.",
                       "About", MB_ICONINFORMATION|MB_OK);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        case ID_FILE_LOADBM:
            LoadBMTrue(hWnd, "1.bmp");
            InvalidateRect(hWnd,0,TRUE);
            break;
        case ID_FILE_SAVEBM:
            SaveBitmapToBMPFile("2.bmp", hbitmap, hdc, hWnd);
            break;
        case ID_SERVICE_MONO:
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // Эта функция отображает картинку.
        BitBlt(hdc,50,50,320,192,image_dc,0,0,SRCCOPY);
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return TRUE;
        }
        break;
    }
    return FALSE;
}
249
10 марта 2005 года
DissDoc
639 / / 01.10.2004
Все! Я разобрался! просто нужно было использовать контекст картинки, а не контекст устройства, тогда палитра загружается корректно =) Всем спасибо за внимание!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог