Image Processing


Image Processing

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. See the GIF specification at http://www.w3.org/Graphics/GIF/spec-gif89a.txt.
El Formato de Intercambio de Gráficos es un 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. 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.

16-bit Bitmap

This format supports 65,536 distinct colors and stores each pixel per 2-bytes (WORD or unsigned __int16). Each WORD variable defines the alpha, red, green and blue values of the pixel. This format is not very common.
Este formato soporta 65536 colores distintos y almacena cada pixel usando 2-bytes (WORD o unsigned __int16). Cada variable WORD define los valores del alfa, rojo, verde y azul del pixel. Este formato no es muy común.

24-bit Bitmap

This format supports 16,777,216 distinct colors and stores 1 pixel value per 3 bytes. Each pixel is defined by three values: 8 bits for red, 8 bits for green and 8 bits for blue. This type of bitmap is very common.
Este formato suporta 16,777,216 colores distintos y almacena un pixel usando 3 bytes. Cada pixel está definido por tres valores: 8 bits para el rojo, 8 bits para el verde y 8 bits para el azul. Este tipo de bitmap es muy común.

32-bit Bitmap

This format supports 4,294,967,296 distinct colors and stores 1 pixel value per 4 bytes. Each pixel is defined by four values: 8 bits for alpha, 8 bits for red, 8 bits for green and 8 bits for blue.
Este formato suporta 4,294,967,296 colores distintos y almacena un pixel usando 4 bytes. Cada pixel está definido por cuatro valores: 8 bits para la transparencia, 8 bits para el rojo, 8 bits para el verde y 8 bits para el azul.

Problem 1
Create a Wintempla Window application called ImgProcessor to process a BMP image using the Gaussian Smooth Filter. After creating the application, insert a button as shown below; then double click the blank area in Wintempla editor to mark the Paint event in Event Tab as shown. In the Window Tab, mark the Resizing Border.
Cree una aplicación de Ventana usando Wintempla llamada ImgProcessor para procesar una imagen BMP usando el Filtro de Suavizado de Gauss. Después de crear la aplicación, inserta un botón cómo se muestra debajo; entonces has doble clic en el área vacía del editor de Wintempla para marcar el evento de Paint en la pestaña de Event cómo se muestra. En la pestaña de Window, marque la opción de Resizing Border.FIGPGN GaussianSmoothFilter

ImgProcessorGui

PaintEvent

ResizingBorder

Step A
Select the Open button, and click on the Dock button to dock the button to the right and the bottom as shown.
Seleccione el botón de Open, y haz clic en el botón de Dock para anclar el botón a la derecha y a la parte inferior como se muestra.

ButtonDock

ImgProcessor.h
#pragma once //______________________________________ ImgProcessor.h
#include "Resource.h"
class ImgProcessor: public Win::Dialog
{
public:
     ImgProcessor()
     {
     }
     ~ImgProcessor()
     {
     }
     const wchar_t* Process();
     CG::DIBitmap bitmapOriginal;
     CG::DIBitmap bitmapModified;
protected:
     ...
};

ImgProcessor.cpp
...
void ImgProcessor::Window_Open(Win::Event& e)
{
}

void ImgProcessor::btOpen_Click(Win::Event& e)
{
     //_________________________________________________________ 1. Prompt user for filename
     Win::FileDlg dlg;
     dlg.Clear();
     dlg.SetFilter(L"Bitmap image files (*.bmp)\0*.bmp\0\0", 0, L"bmp");
     if (dlg.BeginDialog(hWnd, L"Open", false) != TRUE) return;
     //_________________________________________________________ 2. Load the bitmap from file
     const wchar_t* error = bitmapOriginal.Load(dlg.GetFileNameFullPath());
     if (error != NULL)
     {
          this->MessageBox(error, L"ImgProcessor", MB_OK | MB_ICONERROR);
          return;
     }
     //_________________________________________________________ 3. Copy the bitmap so that both images are the same size and resolution
     bitmapModified = bitmapOriginal;
     //_________________________________________________________ 4. Modify the image
     error = Process();
     if (error != NULL)
     {
          this->MessageBox(error, L"ImgProcessor", MB_OK | MB_ICONERROR);
          return;
     }
     this->Repaint(NULL, false);
}

const wchar_t* ImgProcessor::Process()
{
     //_______________________________________________________________ 1. Check for 24 bits per pixel images
     const int bitsPerPixel = bitmapOriginal.GetBitsPerPixel();
     if (bitsPerPixel != 16 && bitsPerPixel != 24 && bitsPerPixel != 32) return L"The bitmap must have 24 bits per pixel";
     //_______________________________________________________________ 2. Check for compression
     const int compression = bitmapOriginal.GetCompression();
     if (compression != 0) return L"The bitmap must be uncompressed";
     //_______________________________________________________________ 3. Get image dimension
     const int image_width = bitmapOriginal.GetWidth();
     const int image_height = bitmapOriginal.GetHeight();
     //_______________________________________________________________ 5. Process the image
     const size_t count = image_width*image_height;
     if (bitsPerPixel == 16)
     {
          // NOT IMPLEMENTED
     }
     else if (bitsPerPixel == 24)
     {
          RGBTRIPLE* pixelOriginal = (RGBTRIPLE*)bitmapOriginal.GetBits();
          RGBTRIPLE* pixelModified = (RGBTRIPLE*)bitmapModified.GetBits();
          size_t i;
          size_t row = 0;
          size_t col = 0;
          RGBTRIPLE *left, *top, *bottom, *right;
          for (i = 0; i < count; i++, col++, pixelOriginal++, pixelModified++)
          {
               //________________________________________________________________ 1. Compute row and column
               if (col == image_width)
               {
                    col = 0;
                    row++;
               }
               //_________________________________________________________________ 2. Process only internal pixels
               if (row != 0 && row != image_height-1 && col != 0 && col != image_width -1)
               {
                    //_______________________________________________________________ 3. Original surrounding pixels positions
                    left = pixelOriginal - 1;
                    top = pixelOriginal - image_width;
                    bottom = pixelOriginal + image_width;
                    right = pixelOriginal + 1;
                    //_______________________________________________________________ 4. Apply filter
                    pixelModified->rgbtRed = (4*pixelOriginal->rgbtRed + left->rgbtRed + top->rgbtRed + right->rgbtRed + bottom->rgbtRed)>>3;
                    pixelModified->rgbtGreen = (4*pixelOriginal->rgbtGreen + left->rgbtGreen + top->rgbtGreen + right->rgbtGreen + bottom->rgbtGreen)>>3;
                    pixelModified->rgbtBlue = (4*pixelOriginal->rgbtBlue + left->rgbtBlue + top->rgbtBlue + right->rgbtBlue + bottom->rgbtBlue)>>3;
               }
          }
     }
     else if (bitsPerPixel == 32)
     {
          RGBQUAD* pixelOriginal = (RGBQUAD*)bitmapOriginal.GetBits();
          RGBQUAD* pixelModified = (RGBQUAD*)bitmapModified.GetBits();
          size_t i;
          size_t row = 0;
          size_t col = 0;
          RGBQUAD *left, *top, *bottom, *right;
          BYTE redx, greenx, bluex;
          for (i = 0; i < count; i++, col++, pixelOriginal++, pixelModified++)
          {
               //________________________________________________________________ 1. Compute row and column
               if (col == image_width)
               {
                    col = 0;
                    row++;
               }
               //_________________________________________________________________ 2. Process only internal pixels
               if (row != 0 && row != image_height-1 && col != 0 && col != image_width -1)
               {
                    //_______________________________________________________________ 3. Original surrounding pixels positions
                    left = pixelOriginal - 1;
                    top = pixelOriginal - image_width;
                    bottom = pixelOriginal + image_width;
                    right = pixelOriginal + 1;
                    //_______________________________________________________________ 4. Apply filter
                    redx = (4*pixelOriginal->rgbRed + left->rgbRed + top->rgbRed+ right->rgbRed+ bottom->rgbRed)>>3;
                    greenx = (4*pixelOriginal->rgbGreen + left->rgbGreen + top->rgbGreen+ right->rgbGreen+ bottom->rgbGreen)>>3;
                    bluex = (4*pixelOriginal->rgbBlue + left->rgbBlue + top->rgbBlue+ right->rgbBlue+ bottom->rgbBlue)>>3;
                    pixelModified->rgbRed = redx;
                    pixelModified->rgbGreen = greenx;
                    pixelModified->rgbBlue = bluex;
               }
          }
     }
     this->Repaint(NULL, true);
     return NULL;
}

void ImgProcessor::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     int y = 0;
     gdi.DrawBitmap(bitmapOriginal, 0, y);
     y += bitmapOriginal.GetHeight();
     gdi.DrawBitmap(bitmapModified, 0, y);
}


Problem 2
Create a Wintempla Dialog application called ImgMask to process a BMP image using the filter function of the CG::DIBitmap class (Smooth, Gaussian Smooth, Shapening, Laplasian and Enboss). After creating the application, insert six radio buttons and a button as shown below; then double click the blank area in Wintempla editor to mark the Paint event in Event Tab as shown. In the Window Tab, mark the Resizing Border.
Cree una aplicación de Diálogo usando Wintempla llamada ImgMask para procesar una imagen BMP usando la función filter de la clase CG::DIBitmap (Smooth, Gaussian Smooth, Shapening, Laplasian and Enboss). Después de crear la aplicación, inserta seis radio buttons y un botón cómo se muestra debajo; entonces has doble clic en el área vacía del editor de Wintempla para marcar el evento de Paint en la pestaña de Event cómo se muestra. En la pestaña de Window, marque la opción de Resizing Border.

ImgMaskRun1

ImgMaskRun2

ImgMaskGui

MaskPaintEvent

MaskResizingBorder

Step A
Select the radio buttons and the Process button, and click on the Dock button to dock the buttons to the right and the bottom as shown.
Seleccione los radio buttons y el botón de Process, y haz clic en el botón de Dock para anclar los botones a la derecha y a la parte inferior como se muestra.

MaskButtonDock

ImgMask.h
#pragma once //______________________________________ ImgMask.h
#include "Resource.h"
class ImgMask: public Win::Dialog
{
public:
     ImgMask()
     {
     }
     ~ImgMask()
     {
     }
     CG::DIBitmap bitmapOriginal;
     CG::DIBitmap bitmapModified;
protected:
     ...
};

ImgMask.cpp
...
void ImgMask::Window_Open(Win::Event& e)
{
     radioGaussian.Checked = true;
}

void ImgMask::btProcess_Click(Win::Event& e)
{
     //_________________________________________________________ 1. Prompt user for filename
     Win::FileDlg dlg;
     dlg.Clear();
     dlg.SetFilter(L"Bitmap image files (*.bmp)\0*.bmp\0\0", 0, L"bmp");
     if (dlg.BeginDialog(hWnd, L"Open", false) != TRUE) return;
     //_________________________________________________________ 2. Load the bitmap from file
     const wchar_t* error = bitmapOriginal.Load(dlg.GetFileNameFullPath());
     if (error != NULL)
     {
          this->MessageBox(error, L"ImgProcessor", MB_OK | MB_ICONERROR);
          return;
     }
     if (radioGaussian.Checked == true)
     {
          bitmapOriginal.Filter(0, 1, 0, 1, 4, 1, 0, 1, 0, 8, 0, bitmapModified);
     }
     else if (radioSmooth.Checked == true)
     {
          bitmapOriginal.Filter(1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 0, bitmapModified);
     }
     else if (radioSharpening.Checked == true)
     {
          bitmapOriginal.Filter(0, -1, 0, -1, 9, -1, 0, -1, 0, 5, 0, bitmapModified);
     }
     else if (radioLaplasian.Checked == true)
     {
          bitmapOriginal.Filter(-1, -1, -1, -1, 0, -1, -1, -1, -1, 1, 128, bitmapModified);
     }
     else if (radioEmboss90.Checked == true)
     {
          bitmapOriginal.Filter(0, 1, 0, 0, 0, 0, 0, -1, 0, 2, 128, bitmapModified);
     }
     else if (radioEmboss135.Checked == true)
     {
          bitmapOriginal.Filter(1, 0, 0, 0, 0, 0, 0, 0, -1, 1, 128, bitmapModified);
     }
     this->Repaint(NULL, false);
}

void ImgMask::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     int y = 0;
     gdi.DrawBitmap(bitmapOriginal, 0, y);
     y += bitmapOriginal.GetHeight();
     gdi.DrawBitmap(bitmapModified, 0, y);
}

© Copyright 2000-2019 Wintempla selo. All Rights Reserved. Sep 05 2019. Home