GIF Image |
The Graphics Interchange Format is a bitmap image format. Each pixel can be represented by number of pixels; the maximum number is 8 bits per pixel. Colors are chosen from a palette with up to 256 colors. The following figure illustrates the basis structure of the GIF file. The color indexes are compressed using the LZW algorithm (Wintempla > Libraries > LZW ). See the GIF specification at http://www.w3.org/Graphics/GIF/spec-gif89a.txt. El Formato de Intercambio de Gráficos es una formato de imágenes bitmap. Cada pixel puede ser representado por un número de pixeles; el número máximo es 8 bits por pixel. Los colores se escogen desde una paleta con hasta 256 colores. Los indeces de los colores están comprimidos usando el algoritmo LZW (Wintempla > Libraries > LZW ). La figura siguiente ilustra la estructura básica del archivo GIF. Vea la especificación para GIF en http://www.w3.org/Graphics/GIF/spec-gif89a.txt. |
Problem 1 |
Create a Wintempla Window application called GifViewer to display the content of a GIF file. Use Wintempla to insert a button and a multiline textbox as shown (In the Window tab, you may activate a vertical scrollbar and a horizontal scrollbar). Cree una aplicación de Ventana usando Wintempla llamada Gif Viewer para mostrar el contenido de un archivo GIF. Use Wintempla para insertar un botón y una caja de texto multi-línea como se muestra (en la pestaña de Window, usted puede activar una barra de desplazamiento vertical y una barra de desplazamiento horizontal). |
GifViewer.cpp |
... void GifViewer::Window_Open(Win::Event& e) { } void GifViewer::btOpen_Click(Win::Event& e) { //_________________________________________________________ 1. Prompt user for filename Win::FileDlg dlg; dlg.Clear(); dlg.SetFilter(L"GIF image files (*.gif)\0*.gif\0\0", 0, L"gif"); if (dlg.BeginDialog(hWnd, L"Open", false) != TRUE) return; //_________________________________________________________ 2. Open the file HANDLE hFile = ::CreateFile(dlg.GetFileNameFullPath(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { this->MessageBox(L"The file could not be open", L"GifViewer", MB_OK | MB_ICONERROR); return; } Win::BusyCursor busyCursor(true); //__________________________________________________________ 3. GIF87a or GIF89a DWORD bytesToRead; DWORD bytesResult; char signature[6]; wchar_t text[256]; size_t i = 0; bytesToRead = 6; ::ReadFile(hFile, (LPVOID)signature, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: GIF87a or GIF89a", L"GifViewer", MB_OK | MB_ICONERROR); ::CloseHandle(hFile); return; } for (i = 0; i < 6; i++) text[i] = (wchar_t)signature[i]; text[6] = '\0'; tbxOutput.Text = text; tbxOutput.Text += L"\r\n"; //__________________________________________________________ 4. gif_width unsigned __int16 gif_width = 0; bytesToRead = 2; ::ReadFile(hFile, (LPVOID)&gif_width, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: gif_width", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); return; } //__________________________________________________________ 5. gif_height unsigned __int16 gif_height = 0; bytesToRead = 2; ::ReadFile(hFile, (LPVOID)&gif_height, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: gif_height", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); return; } //__________________________________________________________ 6. Display image size _snwprintf_s(text, 256, _TRUNCATE, L"Size: %d x %d\r\n", (int)gif_width, (int)gif_height); tbxOutput.Text += text; //__________________________________________________________ 7. flag unsigned __int8 gif_flag = 0; bytesToRead = 1; ::ReadFile(hFile, (LPVOID)&gif_flag, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: flag", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); return; } //______________________________________________ 7.1 Global Color Table Flag const bool globalColorTableFlag = (gif_flag & 0x80) != 0; // 1000 0000 _snwprintf_s(text, 256, _TRUNCATE, L"GCTF: %d\r\n", globalColorTableFlag ? 1 : 0); tbxOutput.Text += text; //______________________________________________ 7.2 Color resolution const int colorResolution = 2L<< ((gif_flag & 0x70) >> 4); // 0111 000 _snwprintf_s(text, 256, _TRUNCATE, L"Color Resolution: %d\r\n", colorResolution); tbxOutput.Text += text; //______________________________________________ 7.3 Sort flag const bool sort_flag = (gif_flag & 0x08) != 0; // 0000 1000 _snwprintf_s(text, 256, _TRUNCATE, L"Sort flag: %d\r\n", sort_flag ? 1 : 0); tbxOutput.Text += text; //______________________________________________ 7.4 Color table size const int colorTableSize = 2L << (gif_flag & 0x07); // 0000 0111 _snwprintf_s(text, 256, _TRUNCATE, L"Color table size: %d\r\n", colorTableSize); tbxOutput.Text += text; //__________________________________________________________ 8. background_color_index unsigned __int8 background_color_index = 0; bytesToRead = 1; ::ReadFile(hFile, (LPVOID)&background_color_index, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: background color index", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); return; } _snwprintf_s(text, 256, _TRUNCATE, L"Background color index: %d\r\n", (int)background_color_index); tbxOutput.Text += text; //__________________________________________________________ 9. Pixel aspect ratio unsigned __int8 pixel_aspect_ratio = 0; bytesToRead = 1; ::ReadFile(hFile, (LPVOID)&pixel_aspect_ratio, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: pixel aspect ratio color index", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); return; } _snwprintf_s(text, 256, _TRUNCATE, L"Pixel aspect ratio: %d\r\n", (int)pixel_aspect_ratio); tbxOutput.Text += text; //__________________________________________________________ 10. Color table if (globalColorTableFlag) { unsigned __int32 value; for (i = 0; i < (size_t)colorTableSize; i++) { bytesToRead = 3; value = 0; ::ReadFile(hFile, (LPVOID)&value, bytesToRead, &bytesResult, NULL); if (bytesToRead != bytesResult) { this->MessageBox(L"Error reading: the color table", L"GifViewer", MB_OK | MB_ICONERROR); if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); if (colorTable != NULL) delete [] colorTable; return; } _snwprintf_s(text, 256, _TRUNCATE, L"%02d. Red, Green, Blue: %d, %d, %d\r\n", (int)(i+1), GetRValue(value), GetGValue(value), GetBValue(value)); tbxOutput.Text += text; } } if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); } |
Problem 2 |
Create a Wintempla Window application called GifShow to display a GIF file. Use Wintempla to activate the Paint event as shown. Cree una aplicación de Ventana usando Wintempla llamada Gif Viewer para mostrar un archivo GIF. Use Wintempla para activar el evento Paint como se muestra. |
GifShow.h |
#pragma once //______________________________________ GifShow.h #include "Resource.h" class GifShow: public Win::Window { public: GifShow() { } ~GifShow() { } CG::DIBitmap bitmap; . . . }; |
GifShow.cpp |
. . . void GifShow::Window_Open(Win::Event& e) { } void GifShow::Window_Paint(Win::Event& e) { CG::Gdi gdi(hWnd, true, false); gdi.DrawBitmap(bitmap, 0, 0); } void GifShow::btOpen_Click(Win::Event& e) { Win::FileDlg dlg; dlg.Clear(); dlg.SetFilter(L"GIF image files (*.gif)\0*.gif\0\0", 0, L"gif"); if (dlg.BeginDialog(hWnd, L"Open", false) == TRUE) { const wchar_t * error = bitmap.Load(dlg.GetFileNameFullPath()); if (error != NULL) this->MessageBox(error, L"GifShow", MB_OK | MB_ICONERROR); } this->Repaint(NULL, true); } |
Problem 2 |
Create a Wintempla Window application called InterchangeFormat to display a GIF file. Use Wintempla to activate the Paint event as shown. Cree una aplicación de Ventana usando Wintempla llamada InterchangeFormat para mostrar un archivo GIF. Use Wintempla para activar el evento Paint como se muestra. |
InterchangeFormat.h |
#pragma once //______________________________________ InterchangeFormat.h #include "Resource.h" class InterchangeFormat: public Win::Window { public: InterchangeFormat() { } ~InterchangeFormat() { } CG::DIBitmap bitmap; . . . }; |
InterchangeFormat.cpp |
. . . void InterchangeFormat::Window_Open(Win::Event& e) { CG::Gif gif; const wchar_t* error = gif.Load(L"C:\\selo\\forest.gif"); if (error != nullptr) { this->MessageBox(error, L"InterchangeFormat", MB_OK | MB_ICONERROR); return; } if (gif.image.size() == 0) return; if (bitmap.Create(gif.image[0].bitsPerPixel, gif.image[0].numColorsInTable, gif.image[0].width, gif.image[0].height, gif.image[0].inverted) == false) { this->MessageBox(L"Error bitmap.Create", L"InterchangeFormat", MB_OK | MB_ICONERROR); return; } valarray<RGBQUAD> colorTable; gif.GetColorTable(colorTable); bitmap.SetColorTable(colorTable); bitmap.SetBits((unsigned char*)gif.image[0].bits.c_str()); this->Repaint(nullptr, true); } void InterchangeFormat::Window_Paint(Win::Event& e) { CG::Gdi gdi(hWnd, true, false); gdi.DrawBitmap(bitmap, 0, 0); } |