Advertisement
Sooldierr

WinAPI - graphics filters

Nov 29th, 2017
3,059
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <assert.h>
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <exception>
  5.  
  6. TCHAR NazwaAplikacji[] = TEXT("Przetwarzanie obrazu");
  7. TCHAR NazwaKlasy[] = TEXT("OKNOGLOWNE");
  8.  
  9. char *Rysunek = 0;
  10. char *Filtrowany = 0;
  11. DWORD RozmiarRysunku = 0;
  12. unsigned char NrFiltru = 0;
  13. double CzasFiltrowania = 0.0;
  14.  
  15. struct RGB { unsigned char B, G, R; };
  16.  
  17. inline unsigned int RoundUp4(const unsigned int i)
  18. {
  19.     return (i+3)&(~3);
  20. }
  21.  
  22. static void AplikujFiltr()
  23. {
  24.     assert(sizeof(RGB) == 3);
  25.     BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Filtrowany);
  26.     BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Filtrowany + sizeof(BITMAPFILEHEADER));
  27.     if ((bi->bmiHeader.biBitCount != 24) && (bi->bmiHeader.biBitCount != 32)) throw std::exception();
  28.     RGB *Raster = reinterpret_cast<RGB*>(Filtrowany + bfh->bfOffBits);
  29.     RGB *Punkt;
  30.     register int Wiersz, Kolumna;
  31.     switch (NrFiltru) {
  32.         case 1:
  33.             for (Wiersz = 0; Wiersz < bi->bmiHeader.biHeight; ++Wiersz) {
  34.                 Punkt = Raster + RoundUp4(Wiersz * bi->bmiHeader.biWidth * sizeof(RGB)) / sizeof(RGB);
  35.                 for (Kolumna = 0; Kolumna < bi->bmiHeader.biWidth; ++Kolumna) {
  36.                     Punkt->R = 255 - Punkt->R;
  37.                     Punkt->G = 255 - Punkt->G;
  38.                     Punkt->B = 255 - Punkt->B;
  39.                     ++Punkt;
  40.                 }
  41.             }
  42.             break;
  43.         case 2:
  44.             Sleep(3);
  45.             break;
  46.         case 3:
  47.             Sleep(5);
  48.             break;
  49.         case 4:
  50.             Sleep(7);
  51.             break;
  52.         case 5:
  53.             Sleep(9);
  54.             break;
  55.         case 6:
  56.             Sleep(11);
  57.             break;
  58.     }
  59. }
  60.  
  61. static void KopiujFiltrowany()
  62. {
  63.     if (Filtrowany == 0) Filtrowany = new char [RozmiarRysunku];
  64.     memcpy(Filtrowany, Rysunek, RozmiarRysunku);
  65. }
  66.  
  67. static void Tworz(const HWND Okno)
  68. {
  69.     register const HANDLE Plik = CreateFile(TEXT("Obraz.bmp"), GENERIC_READ, FILE_SHARE_READ,
  70.         NULL, OPEN_EXISTING, 0, NULL);
  71.     if (Plik == INVALID_HANDLE_VALUE) {
  72.         MessageBox(Okno, TEXT("Błąd w trakcie otwierania pliku Obraz.bmp"),
  73.             NazwaAplikacji, MB_ICONEXCLAMATION | MB_OK);
  74.         return;
  75.     }
  76.     RozmiarRysunku = GetFileSize(Plik, NULL);
  77.     Rysunek = new char [RozmiarRysunku];
  78.     DWORD Odczytano;
  79.     ReadFile(Plik, Rysunek, RozmiarRysunku, &Odczytano, NULL);
  80.     CloseHandle(Plik);
  81.     KopiujFiltrowany();
  82. }
  83.  
  84. static void Rysuj(const HWND Okno)
  85. {
  86.     RECT Rozmiar;
  87.     TCHAR Tekst[64];
  88.     PAINTSTRUCT PS;
  89.     unsigned int dl;
  90.     GetClientRect(Okno, &Rozmiar);
  91.     const HDC DC = BeginPaint(Okno, &PS);
  92.     if (Rysunek != 0) {
  93.         BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Filtrowany);
  94.         BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Filtrowany + sizeof(BITMAPFILEHEADER));
  95.         SetStretchBltMode(DC, HALFTONE);
  96.         StretchDIBits(DC, 0, 0, Rozmiar.right, Rozmiar.bottom, 0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
  97.             static_cast<void*>(Filtrowany + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
  98.         dl = swprintf(Tekst, TEXT("Czas filtrowania: %.2lf ms"), CzasFiltrowania);
  99.         TextOut(DC, 5, 5, Tekst, dl);
  100.     }
  101.     EndPaint(Okno, &PS);
  102. }
  103.  
  104. static void Znak(const HWND Okno, const TCHAR Znak)
  105. {
  106.     if (Znak >= TEXT('0') && Znak <= TEXT('9')) {
  107.         SYSTEMTIME S1, S2;
  108.         NrFiltru = Znak - TEXT('0');
  109.         SetWindowText(Okno, TEXT("TRWA FILTROWANIE..."));
  110.         KopiujFiltrowany();
  111.         GetSystemTime(&S1);
  112.         if (NrFiltru > 0 && NrFiltru <= 9)
  113.             for (unsigned int i = 0; i < 500; ++i) AplikujFiltr();
  114.         GetSystemTime(&S2);
  115.         CzasFiltrowania = 3600.0 * (S2.wHour - S1.wHour) + 60.0 * (S2.wMinute - S1.wMinute)
  116.             + (S2.wSecond - S1.wSecond) + 0.001 * (S2.wMilliseconds - S1.wMilliseconds);
  117.         CzasFiltrowania *= 2.0;
  118.         InvalidateRect(Okno, NULL, FALSE);
  119.         SetWindowText(Okno, NazwaAplikacji);
  120.         UpdateWindow(Okno);
  121.     }
  122. }
  123.  
  124. static LRESULT CALLBACK FunkcjaOkienkowa(HWND Okno, UINT Komunikat, WPARAM wParam, LPARAM lParam)
  125. {
  126.     switch (Komunikat) {
  127.         case WM_CREATE:
  128.             Tworz(Okno);
  129.             break;
  130.         case WM_CHAR:
  131.             Znak(Okno, static_cast<TCHAR>(wParam));
  132.             break;
  133.         case WM_PAINT:
  134.             Rysuj(Okno);
  135.             break;
  136.         case WM_DESTROY:
  137.             delete [] Rysunek;
  138.             delete [] Filtrowany;
  139.             PostQuitMessage(0);
  140.             break;
  141.         default:
  142.             return DefWindowProc(Okno, Komunikat, wParam, lParam);
  143.     }
  144.     return 0;
  145. }
  146.  
  147. static bool RejestrujKlasy()
  148. {
  149.     WNDCLASSEX wc;
  150.     wc.cbSize = sizeof(WNDCLASSEX);
  151.     wc.cbClsExtra = wc.cbWndExtra = 0;
  152.     wc.hbrBackground = (HBRUSH) (1 + COLOR_WINDOW);
  153.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  154.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  155.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  156.     wc.hInstance = GetModuleHandle(NULL);
  157.     wc.lpfnWndProc = &FunkcjaOkienkowa;
  158.     wc.lpszClassName = NazwaKlasy;
  159.     wc.lpszMenuName = NULL;
  160.     wc.style = CS_HREDRAW | CS_VREDRAW;
  161.     return (RegisterClassEx(&wc) != 0);
  162. }
  163.  
  164. static void WyrejestrujKlasy()
  165. {
  166.     UnregisterClass(NazwaKlasy, GetModuleHandle(NULL));
  167. }
  168.  
  169. int WINAPI WinMain(HINSTANCE Instancja, HINSTANCE Poprzednia, LPSTR Parametry, int Widocznosc)
  170. {
  171.     // Zarejestruj klasę. Protestuj, jeżeli wystąpił błąd.
  172.     if (!RejestrujKlasy()) {
  173.         MessageBox(NULL, TEXT("Nie udało się zarejestrować klasy okna!"),
  174.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  175.         return 1;
  176.     }
  177.     // Stwórz główne okno. Również protestuj, jeżeli wystąpił błąd.
  178.     HWND GlowneOkno = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE,
  179.         NazwaKlasy, NazwaAplikacji, WS_OVERLAPPEDWINDOW,
  180.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  181.         NULL, NULL, Instancja, NULL);
  182.     if (GlowneOkno == NULL) {
  183.         MessageBox(NULL, TEXT("Nie udało się stworzyć głównego okna!"),
  184.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  185.         return 2;
  186.     }
  187.     // Wyświetl i uaktualnij nowo stworzone okno.
  188.     ShowWindow(GlowneOkno, Widocznosc);
  189.     UpdateWindow(GlowneOkno);
  190.     // Główna pętla komunikatów wątku.
  191.     MSG Komunikat;
  192.     while (GetMessage(&Komunikat, NULL, 0, 0) > 0) {
  193.         TranslateMessage(&Komunikat);
  194.         DispatchMessage(&Komunikat);
  195.     }
  196.     // Zwolnij pamięć klas i zakończ proces.
  197.     WyrejestrujKlasy();
  198.     return static_cast<int>(Komunikat.wParam);
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement