Trong lập trình, các pixel màu có thể lưu trữ ở dạng mãng 2 chiều hoặc 1 chiều. Tuy nhiên, để thuận tiện trong xử lý, nhất là với ngôn ngữ C/C++, ta thay mãng 2 chiều bằng mãng 1 chiều
Image structure
enum EImagePixelFormat { EIMAGE_FORMAT_R8G8B8, EIMAGE_FORMAT_R8G8B8A8, }; class CImage { public: CImage(int width, int height, EImagePixelFormat format); virtual ~CImage(); __UINT32 GetDataSize(); __UINT32 GetWidth() {return this->m_iWidth;} __UINT32 GetHeight() {return this->m_iHeight;} EImagePixelFormat GetPixelFormat() {return m_eFormat;} protected: __UINT32 m_iWidth; __UINT32 m_iHeight; EImagePixelFormat m_eFormat; __UINT8 *m_pData; };
Vị trí vùng nhớ của pixel tại dòng row, cột col được tính:
offset = (row*m_iWidth + col)*size_of_pixel_format;
Bước đầu làm quen với cấu trúc ảnh, ta cung cấp 3 hàm cơ bản tương tác ảnh:
CImage.h
#ifndef __CIMAGE_H__ #define __CIMAGE_H__ #include "Header.h" #include "SGraphics.h" namespace GameTutor { enum EImagePixelFormat { EIMAGE_FORMAT_R8G8B8, EIMAGE_FORMAT_R8G8B8A8, }; class CImage { public: CImage(int width, int height, EImagePixelFormat format); virtual ~CImage(); __UINT32 GetDataSize() { return GetPixelSize()*m_iWidth*m_iHeight; } __UINT32 GetPixelSize() { switch (m_eFormat) { case EIMAGE_FORMAT_R8G8B8: return 3; case EIMAGE_FORMAT_R8G8B8A8: return 4; default: return 0; } } void GetPixel(__UINT32 row, __UINT32 col, SColor<__UINT8> &c); void SetPixel(__UINT32 row, __UINT32 col, SColor<__UINT8> c); void ClearColor(SColor<__UINT8> c); __UINT32 GetWidth() {return this->m_iWidth;} __UINT32 GetHeight() {return this->m_iHeight;} EImagePixelFormat GetPixelFormat() {return m_eFormat;} protected: __UINT32 m_iWidth; __UINT32 m_iHeight; EImagePixelFormat m_eFormat; __UINT8 *m_pData; }; }
CImage.cpp
#include "CImage.h" #include "CGLPipelineDriver.h" namespace GameTutor { CImage::CImage(int width, int height, EImagePixelFormat format ):m_iWidth(width), m_iHeight(height), m_eFormat(format), m_pData(0) { int dataSize = GetDataSize(); m_pData = new __UINT8[dataSize]; } CImage::~CImage() { SAFE_DEL(m_pData); } void CImage::GetPixel(__UINT32 row, __UINT32 col, SColor<__UINT8> &c) { int offset = 0; if (row >= 0 && row < m_iHeight && col >= 0 && col c) { int offset = 0; if (row >= 0 && row < m_iHeight && col >= 0 && col c) { int dataSize = GetDataSize(); switch (m_eFormat) { case EIMAGE_FORMAT_R8G8B8: for (int i = 0; i < dataSize; i+=3) { memcpy(m_pData + i, &c, 3); } break; case EIMAGE_FORMAT_R8G8B8A8: for (int i = 0; i < dataSize; i+=4) { memcpy(m_pData + i, &c, 4); } break; } } }
#endif