CamImage.cpp

Go to the documentation of this file.
00001 /*
00002 *       This file contains class that load images from specified file.
00003 *
00004 *       Author:
00005 *                       Tomas Mrkvicka
00006 *                       xmrkvi03@stud.fit.vutbr.cz
00007 *
00008 */
00009 
00010 #include "StdAfx.h"
00011 #include "CamImage.h"
00012 
00013 #include <cstdlib>
00014 #include <cstring>
00015 #include <cmath>
00016 
00017 ////////////////////////////////////////////////////////////////////////////////
00018 ////////////////////////////////////////////////////////////////////////////////
00019 ////////////////////////////////////////////////////////////////////////////////
00020 // TCameraImage
00021 
00022 /** Funkce pro vytvoreni tridy a preneseni ven z DLL.
00023 *
00024 *       \warning        Muze vratit NULL pri chybe.
00025 *
00026 *       \param  filename        [in] jmeno souboru s obrazkem
00027 */
00028 extern "C" TCameraAbstract*     CreateCamera(const char * filename)
00029 {
00030         return TCameraImage::CreateCamera(filename);
00031 }
00032 
00033 /** Tato staticka metoda vytvori kameru.
00034 *
00035 *       \warning        Vraci NULL pri chybe.
00036 *
00037 *       \param  filename        [in] jmeno souboru s obrazkem
00038 */
00039 TCameraImage* TCameraImage::CreateCamera(const char * filename)
00040 {
00041         //vytvorime objekt
00042         TCameraImage * cam = new TCameraImage;
00043 
00044         //inicializujeme
00045         if ( cam->Initialize( filename ) )
00046         {
00047                 //ok - kamera inicializovana v poradku
00048                 return cam;
00049         }
00050         else
00051         {
00052                 //nejaka chyba
00053                 delete cam;
00054                 return NULL;
00055         }
00056 }
00057 
00058 /** Soukromy konstruktor.
00059 *
00060 *       Pouze vytvori tridu. Ta musi byt inicializovana metodou Initialize() !!!
00061 */
00062 TCameraImage::TCameraImage(void)
00063 {
00064         m_data = NULL;
00065 }
00066 
00067 /** Soukromy destruktor.
00068 */
00069 TCameraImage::~TCameraImage(void)
00070 {
00071         delete [] m_data;
00072         m_data = NULL;
00073 }
00074 
00075 /** Tato metoda inicializuje tridu po vytvoreni.
00076 *
00077 *       \param  filename        [in] jmeno souboru s nacitanym obrazkem
00078 */
00079 bool TCameraImage::Initialize( const char * filename)
00080 {
00081         // inicializace GDI+
00082         GdiplusStartupInput gdiplusStartupInput;
00083         ULONG_PTR           gdiplusToken;
00084         GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
00085 
00086         //prevod na WCHAR
00087         size_t len = strlen( filename );
00088         size_t bytes = mbstowcs( NULL, filename, strlen( filename ) ) + 1;
00089         wchar_t * str_dst = new wchar_t[bytes];
00090         mbstowcs( str_dst, filename, strlen( filename ) + 1 );
00091 
00092         //musime nacist obrazek
00093         Bitmap * bmp = Bitmap::FromFile( str_dst );
00094 
00095         delete [] str_dst;
00096 
00097         if ( ! bmp )
00098         {
00099                 //nejaky chyba pri nacitani obrazku
00100 
00101                 GdiplusShutdown(gdiplusToken);
00102 
00103                 return false;
00104         }
00105 
00106         //ok - mame obraz
00107         int width = (int)bmp->GetWidth();
00108         int height = (int)bmp->GetHeight();
00109         
00110         //vytvorime pomocny obraz
00111         Bitmap * bmpTemp = new Bitmap( width, height, PixelFormat24bppRGB );
00112         if ( ! bmpTemp )
00113         {
00114                 delete bmp;
00115 
00116                 GdiplusShutdown(gdiplusToken);
00117 
00118                 return false;
00119         }
00120 
00121         //nyni vykreslime nacteny obraz na nas obraz
00122         Graphics * graph = Graphics::FromImage( bmpTemp );
00123         if ( ! graph )
00124         {
00125                 delete bmp;
00126                 delete bmpTemp;         
00127 
00128                 GdiplusShutdown(gdiplusToken);
00129 
00130                 return false;
00131         }
00132 
00133         graph->DrawImage( bmp, 0, 0 );
00134 
00135         delete graph;
00136         delete bmp;
00137 
00138         //precteme data z obrazku ve formatu RGB
00139         Rect rect( 0, 0, width, height );
00140         BitmapData data;
00141         if ( Ok == bmpTemp->LockBits( &rect, ImageLockModeRead, PixelFormat24bppRGB , &data ) )
00142         {
00143                 const DWORD rowSize = data.Width * 3;   //delka radku obrazu v bajtech
00144                 const DWORD pitch = (DWORD) abs(data.Stride);
00145 
00146                 m_width         = (int)data.Width;
00147                 m_height        = (int)data.Height;
00148 
00149                 //kopirujeme data
00150                 m_data = new unsigned char[ 3 * m_width * m_height ];
00151                 const char * m_source = (const char *) data.Scan0;
00152 
00153                 //zalezi na usporadani radku
00154                 if ( data.Stride >= 0 )
00155                 {
00156                         //radky jsou ulozeny odshora dolu
00157                         for ( int y = 0 ; y < height ; y++ ) // pro kazdy radek
00158                         {                       
00159                                 memcpy( &m_data[ y * m_width * 3 ], &m_source[ y * pitch ], rowSize );
00160                         }
00161                 }
00162                 else
00163                 {
00164                         //radky jsou ulozeny odspoda nahoru
00165                         DWORD offsetSrc = 0;
00166                         for ( int y = (height - 1)  ; y >= 0 ; y-- ) // pro kazdy radek
00167                         {       
00168                                 memcpy( &m_data[ y * m_width * 3 ], &m_source[ offsetSrc ], rowSize );
00169 
00170                                 offsetSrc += pitch;
00171                         }
00172                 }
00173 
00174                 bmpTemp->UnlockBits( &data );
00175                 delete bmpTemp;
00176 
00177                 GdiplusShutdown(gdiplusToken);
00178 
00179                 return true;
00180         }
00181         else
00182         {
00183                 //nepodarilo se zamknout bitmapu
00184                 delete bmpTemp;
00185 
00186                 GdiplusShutdown(gdiplusToken);
00187 
00188                 return false;
00189         }
00190 }
00191 
00192 /** Velikost obrazku v bajtech.
00193 */
00194 DWORD TCameraImage::GetDataSize(void)
00195 {
00196         return this->GetWidth() * this->GetHeight() * 3;
00197 }
00198 
00199 /** Ulozi data do pripraveneho bufferu.
00200 *
00201 *       \param  dest    [in out] buffer pro data obrazku o velikosti minimalne TCameraImage::GetDataSize
00202 */
00203 void TCameraImage::GetData(void * dest)
00204 {
00205         memcpy( dest, m_data, this->GetDataSize() );
00206 }
00207 
00208 /** Vrati sirku obrazku v pixelech.
00209 */
00210 int TCameraImage::GetWidth(void)
00211 {
00212         return m_width;
00213 }
00214 
00215 /** Vrati vysku obrazku v pixelech.
00216 */
00217 int TCameraImage::GetHeight(void)
00218 {
00219         return m_height;
00220 }
00221 
00222 /** Zrusi tento objekt.
00223 */
00224 void TCameraImage::Destroy(void)
00225 {
00226         delete this;
00227 }
00228 
00229 // TCameraImage
00230 ////////////////////////////////////////////////////////////////////////////////
00231 ////////////////////////////////////////////////////////////////////////////////
00232 ////////////////////////////////////////////////////////////////////////////////

Generated on Sat Nov 17 16:23:33 2007 for Image Processing Pipeline - Camera Sources Implementation by  doxygen 1.4.6-NO