一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

一、序言:在图像处理的学习过程中,我们会经常使用到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 }

至此,我们的图像处理类就实现完成了

posted on 2022-02-21 13:46  一杯清酒邀明月  阅读(729)  评论(0编辑  收藏  举报