一、序言:在图像处理的学习过程中,我们会经常使用到C++中比较著名的一些图像处理库中的图像类或矩阵类,如OpenCV中的Mat等。今天,我们就来实现自己的图像类。
二、需求:
1.一个完整的图像处理类通常包括以下属性:
(1)Width 宽
(2)Height 高
(3)nBitCount 一个像素的所需的字节数
(4)BytesPerLine 图像每行锁占用的字节数
(5)Data 存储图像数据的指针
(6)Format 图像的格式
2.我们同样还需要实现和处理该图像类的方法,常用方法如下:
1.一个没有输入参数的构造函数,构造一个空的图像类
2.输入参数为 data,width,height,format的构造函数
3.由于我的整个教程是基于Qt的,所以还需要一个将QImage转化为MyImage的构造函数
4.将MyImage转化为QImage的函数
三、详细步骤:
接下来我们就来实现我们的图像类:
1.首先定义一个图像格式的枚举类型:
1 public:
2 enum format{
3 GRAY8,
4 RGB32,
5 EMPTY
6 };
2.在MyImage的定义中定义如下属性:
1 public:
2 int m_width;
3 int m_height;
4 int m_nBitCount;
5 int m_bytesPerLine;
6 enum format m_format;
7 unsigned char* m_data;
3.然后定义该类的方法
1 public:
2 MyImage();
3 MyImage(unsigned char* data,int width,int height,enum format fmt);
4 MyImage(MyImage* Scr);
5 MyImage(const QImage &qimage);
6 ~MyImage();
7
8 static QImage* MyImage2QImage(const MyImage &myimage);
4.以上方法的实现如下:
1 MyImage::MyImage()
2 {
3 m_width = 0;
4 m_height = 0;
5 m_nBitCount = 0;
6 m_bytesPerLine = 0;
7 m_data = NULL;
8 m_format = format::EMPTY;
9 }
10
11 MyImage::MyImage(unsigned char *data, int width, int height, enum format fmt)
12 {
13 m_width = width;
14 m_height = height;
15 m_format = fmt;
16
17 switch(fmt)
18 {
19 case format::GRAY8:
20 m_nBitCount = 8;
21 break;
22 case format::RGB32:
23 m_nBitCount = 32;
24 break;
25 }
26
27 m_bytesPerLine = (width*m_nBitCount +31)/32*4;
28 m_data = new unsigned char[m_bytesPerLine*height];
29 memcpy(m_data,data,m_bytesPerLine*height);
30 }
31
32 MyImage::MyImage(MyImage *Scr)
33 {
34 m_width = Scr->m_width;
35 m_height = Scr->m_height;
36 m_nBitCount = Scr->m_nBitCount;
37 m_bytesPerLine = Scr->m_bytesPerLine;
38 m_format = Scr->m_format;
39 m_bytesPerLine = (m_width*m_nBitCount +31)/32*4;
40 m_data = new unsigned char[m_bytesPerLine*m_height];
41 memcpy(m_data,Scr->m_data,m_bytesPerLine*m_height);
42 }
43
44 MyImage::MyImage(const QImage &qimage)
45 {
46 m_width = qimage.width();
47 m_height = qimage.height();
48 m_nBitCount = qimage.byteCount();
49 m_bytesPerLine = qimage.bytesPerLine();
50
51 if(qimage.format()==QImage::Format_RGB32)
52 m_format = format::RGB32;
53 else if(qimage.format()==QImage::Format_Grayscale8)
54 m_format = format::GRAY8;
55
56 m_data = new unsigned char[m_bytesPerLine*m_height];
57 memcpy(m_data,qimage.bits(),m_bytesPerLine*m_height);
58 }
59
60 MyImage::~MyImage()
61 {
62 if(m_data != NULL)
63 delete m_data;
64 }
65
66 QImage* MyImage::MyImage2QImage(const MyImage &myimage)
67 {
68 QImage *qimage;
69
70 if(myimage.m_format == MyImage::format::GRAY8)
71 {
72 qimage = new QImage(myimage.m_data,
73 myimage.m_width,
74 myimage.m_height,
75 myimage.m_bytesPerLine,
76 QImage::Format_Grayscale8);
77 }
78 else if(myimage.m_format == MyImage::format::RGB32)
79 {
80 qimage = new QImage(myimage.m_data,
81 myimage.m_width,
82 myimage.m_height,
83 myimage.m_bytesPerLine,
84 QImage::Format_RGB32);
85 }
86
87 return qimage;
88 }
至此,我们的图像处理类就实现完成了