极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 28702|回复: 8

发一个 绘图 Adafruit GFX图形库

[复制链接]
发表于 2015-12-14 02:52:32 | 显示全部楼层 |阅读模式
本帖最后由 老来疯 于 2015-12-14 03:27 编辑

u8g lib  大家 比较 熟悉了,Adafruit GFX 图形库 使用的还不多,相比较而言,Adafruit GFX图形库支持的 屏幕还不多,而且需要单独下载 Adafruit GFX图形库与屏幕相适应的 屏幕初始化 库文件,比如:Adafruit_SSD1306-master  ,但是他的使用方法比较符合一般程序语法的规则,程序容易看懂。

下面是我以 中式 英语 翻译结果,一看便懂。  有图,但是我 插不到文字中间。

Adafruit GFX图形库       Adafruit GFX Graphics Library


file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1C1.tmp.jpg
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A1.tmp.jpg
指南的内容      Guide Contents

概述                      Overview
坐标系统和单位    Coordinate System and Units
图形语法              Graphics Primitives
画点(点)           Drawing pixels (points)
画线                     Drawing lines
矩形                      Rectangles
圆                         Circles
圆角矩形              Rounded rectangles
三角形                 Triangles
字符和文本          Characters and text
位图                     Bitmaps
清除或填充屏幕  Clearing or filling the screen
旋转屏幕             Rotating the Display


file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A2.tmp.jpg

基于Arduinoadafruit_gfx库提供了一个通用的语法来绘制图形,以适应所有的LCDOLED显示器功能。他允许Arduino IDE,很容易的适应显示器类型,性能改进和bug修复将立即适用于我们的完整产品。


下载adafruit_gfx库  

adafruit_gfx是和显示屏驱动库文件(头文件)一起工作的,显示屏驱动库程序提供具体的显示屏类型-
例如,ST7735 1.8“彩色液晶显示器需要安装的adafruit_gfxadafruit_st7735驱动程序库。

adafruit_ssd1306http://adafru.it/ahq)为单色显示屏  还支持:

RGBmatrixPanel (http://adafru.it/aHj), for our 16x32 (http://adafru.it/420) and 32x32 (http://adafru.it/607) RGB LED matrix panels.

Adafruit_TFTLCD (http://adafru.it/aHk), for our 2.8" TFT LCD touchscreen
breakout (http://adafru.it/335) and TFT Touch Shield for Arduino (http://adafru.it/376).

Adafruit_HX8340B (http://adafru.it/aHl), for our 2.2" TFT Display with microSD (http://adafru.it/797).

Adafruit_ST7735 (http://adafru.it/aHm), for our 1.8" TFT Display with microSD (http://adafru.it/358).

Adafruit_PCD8544 (http://adafru.it/aHn), for the Nokia 5110/3310 monochrome LCD (http://adafru.it/338).

Adafruit-Graphic-VFD-Display-Library (http://adafru.it/aHo), for our 128x64 GraphicVFD (http://adafru.it/773).

Adafruit-SSD1331-OLED-Driver-Library-for-Arduino (http://adafru.it/aHp) for the 0.96"  16-bit Color OLED w/microSD Holder http://adafru.it/684).

坐标系统和单位   Coordinate System and Units

屏幕以像素为单位,包括数字图像处理的横坐标(X)和垂直(Y)坐标。坐标系统的原点(0,0)在屏幕左的上角,x方向向右,Y的正方向向下。他相对标准的笛卡尔坐标系统是颠倒的,这是建立在许多计算机图形系统上的。

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A3.tmp.jpg
坐标是以像素为单位表示的;不存在现实世界使用的如毫米或英寸,显示的图形是一个函数相对于特定大小的显示器的点距或像素密度相对应的。

如果你的目标是现实的维度,这需要你配合屏幕,以点距大小和设备数据表,通过测量屏幕宽度和分辨像素数值安排你的参数。

彩色显示,颜色为无符号的16位值。一些显示器可能有更多或更少的比特值,我们这个程序工作在16位值……这是简单的Arduino对于不同的显示器提供的一个一致的数据类型。

主要颜色成分- 红色,绿色和蓝色  都是“包装”到一个16位的变量,其中5分配给红色,6位分配给绿色,剩下的5分配给蓝色。额外的位分配给绿色是因为眼睛对绿色光最敏感。这是符合科学的!

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A4.tmp.jpg
最常见的原发性(如:红,绿蓝三原色)和继发性(三原色的混合)的颜色,我们有个方便的小表,你可以在你自己的代码中任意选择65536种不同的颜色,但这个基本的列表可能是最简单的开始:
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A5.tmp.pngfile:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A6.tmp.jpg  
黑白(单色)显示屏,色彩始终被指定为简单的1set_设置0clear_清除)。

语法中的设置 / 清除相对特定的显示类型:像一个发光的OLED显示屏与反射式液晶显示屏,一个被“初始化”的像素点通常是与背景一致的。一般来说可以以0clear)代表一个新的初始化显示默认背景状态。可能会有例外



绘图语法
每个设备的具体显示库将有它自己的构造函数,初始化函数。这些都记录在每个显示类型中,经常是显式的包含在特定的头文件库中。本教程是与之相适应的图形功能,工作时不区分显示器类型。

下面的函数描述仅仅是原型- 有一个假设显示对象的声明和初始化以设备特定的程序需要。实际使用中请查看每一个库文件的实例代码。

例如,我们要显示打印show print(1234.56),你的实际代码可能会在对象名称之前先读取屏幕打印screen.print。1234.56)。

画 点 函数  Drawingpixels (points)

首先是最基本的像素点显示。你可以称之为XY坐标和 颜色值,它将形成一个点:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A7.tmp.jpg
void drawPixel(uint16_t x, uint16_t y, uint16_t color);

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A8.tmp.jpg
画线 函数 Drawing lines

你也可以画线,参数有 起点x0, y0 终点 x1, y1和 颜色值:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1A9.tmp.jpg
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AA.tmp.jpg
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AB.tmp.jpg
有专门划线的功能函数,水平或垂直的线,要避免角的计算:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AC.tmp.jpg
画 水平线                     length =长度
void drawFastVLine(uint16_t x0, uint16_t y0, uint16_t length, uint16_t color);

画 垂直线                    length =长度
void drawFastHLine(uin86_t x0, uin86_t y0, uint8_t length, uint16_t color);

画 矩形 函数 Rectangles
接下来,长方形和正方形可以得出,使用下面的语句。

    一个X0,y0为矩形的左上角,宽度和高度(指像素),和一个颜色值。drawRect()显示一个像素的线宽(轮廓),矩形框的内部是不填充的,而fillrect()用一个给定的颜色填充整个矩形:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AD.tmp.jpg
void drawRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);
void fillRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AE.tmp.jpg
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1AF.tmp.jpg
如图:先创造一个实芯的矩形使用fillrect(),然后再drawrect()它。产生对比的轮廓。

画 园 函数Circles

画园,可以是绘制和填充。每个函数接受一个以x0,y0为中心点,r为半径,和color:绘制是以一个像素为线宽的,

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B0.tmp.jpg
void drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);
void fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B1.tmp.jpg
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B2.tmp.jpg

圆角矩形函数   Rounded rectangles

圆角矩形的绘制和填充功能,
XY是指以圆角矩形的左上角为坐标原点,再给定宽度和高度(就像正常的矩形)参数,然后给定圆角的圆半径(以像素为单位)和 最后的颜色值:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B3.tmp.jpg
空心圆角矩形:
void drawRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);

实心圆角矩形:
void fillRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);

W = 圆角矩形的宽
h = 圆角矩形的高
Radius = 圆角的半径

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B4.tmp.jpg
这里有一个额外的技巧:画园
因为画圆函数总是相对于中心像素画的,由此产生的圆的直径都是像素的奇数。可以使用一个圆角矩形函数来实现这个功能:通过画一个相同宽度和高度的圆角矩形,将圆角半径设为圆的半径就行了。

画 三角形 函数   void drawTriangle( , , , , , , )
画三角形,也有绘制和填充函数。每个函数都需要完整的七个参数:包括(X0,Y0X1, Y1, X2, Y2 ) 坐标定义三角形的三个角点,和颜色:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B5.tmp.jpg
void drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint1 6_t y2, uint16_t color);
void fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);


file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B6.tmp.jpg
字符和文本  Characters and text
有两种基本的方法可以在绘图程序中添加文本字符串。

第一种方法是绘制一个单一的字符。你可以将这个字符放在任何地点和置任一颜色。(为了节省空间只有一种字体,注:没有汉字,需另外制作),字符的大小是5x8像素,可以通过一个可选的尺寸参数通过表的字体的因子(如大小= 2就可以产生10x16 的文本字符,以像素为单位)。这是一个非常小的程序空间,只有一个单一的字体,这有助于保持程序的大小。(有一个专门的字符文件)

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B7.tmp.jpg
void drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B8.tmp.jpg
   文本是非常灵活的,但操作稍有不同,他不是一个程序。文本的大小,颜色和位置的设置分别在单独的函数里,然后使用print () 函数 ,并提供所有相同的字符串和数字格式,熟悉的 Serial.print() 设置功能!



file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1B9.tmp.jpg
void setCursor(uint16_t x0, uint16_t y0);
void setTextColor(uint16_t color);  或
void setTextColor(uint16_t color, uint16_t backgroundcolor); backgroundcolor = 背景颜色
void setTextSize(uint8_t size);  size = 0 1 2
void setTextWrap(boolean w);  
如setTextWrap(false)   Wrap = 循环

操作步骤:

首先设置坐标原点(x0,y0),请将文本的左上角放在哪里。最初,这是设置为(0,0)(屏幕的左上角)。
然后设置文本颜色用SetTextColorColor-默认情况下是白色的。文本通常是“清晰地”的显示在原来的黑背景上,但是如果你想让文本的背景改变颜色,可以指定一个可选的第二参数tosettextcolor()

最后,设置绘制文字的字号大小(尺寸)。由给定的整数因子决定,这会增加文本的规模。你可以看到下面的图:1(默认大小),2(2倍大小)和3(4倍大小)。它会显示更大的尺寸,因为我们的库只提供一个单一的简单的字体,以节省空间。

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BA.tmp.jpg
设置完毕以后,你就可以使用print()println()函数 -就像你用串口输出一样!例如,
1.    打印一个字符串,使用 print(“Hello World”)-这是上图的第一行。
2.    你也可以使用printin()数字或变量-上面的第二行是输出(1234.56
3.    或第三行printin(0xDEADBEEF, HEX)。

默认情况下,长行文本设置为自动"左移" setTextWrap(true).用于滚动字幕效果。使用 setTextWrap(false),从左向右显示。要恢复正常的换行行为, 再次使用setTextWrap(true


位图  Bitmaps
你可以画(单色)位图,图画和其他小型 动画图标:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BB.tmp.jpg
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);

这是一个连续的块位显示,对应1的位 填入像素的颜色,而像素为0的点被跳过。XY是绘制位图的左上角坐标,WH是像素的宽度和高度。

位图数据必须使用PROGMEM指令  在程序存储器位置。这是一些先进的功能,初学者最好参考(HTTP/ / adafru/ AMW)。
介绍对于使用Arduino教程  (http://adafru.it/aMw)


清除或填满屏幕
fillscreen() 函数将设置整个显示为一个给定的颜色,清除任何现有的内容:

file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BC.tmp.jpg
void fillScreen(uint16_t color);     fillScreen = 填充屏幕


旋转显示    Rotating the Display

你也可以旋转你的画面。请注意,这不是连续转动,
它更改新的绘图坐标系统。使文字或位图旋转,这可以非常方便的把你的显示屏幕横放或颠倒到一个适合的特定外壳中。在大多数实例中,只需在setup()指令中做一次。

我们只能旋转090180270度,在一个Arduino计算软件中没有什么是不可能的。
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BD.tmp.jpg
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BE.tmp.jpg
void setRotation(uint8_t rotation);     rotation = 0123
旋转参数可以是 012 3
旋转值 0 设置显示为纵向模式。默认值
旋转值 1 横幅模式,
旋转值 2 也是纵向模式。
旋转值 3 横幅模式。

请尝试所有的4个旋转找出他们最终的效果,调整将取决于每个显示器的不同,一般的旋转方向是将显示内容按逆时针方向旋转。请重试所有 4 轮换,以弄清楚他们如何最终作为旋转对齐方式,其他的显示,将取决于每个显示器,
旋转时,原点(0,0)变化的想法是,它应该被安排在这对于其他的图形函数作出一致的意义上的显示左上(和匹配所有的功能描述以上)。


如果你需要引用(参考)屏幕的尺寸,使用width()height()
file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ksohtml\wps1BF.tmp.jpg
uint16_t width();
uint16_t height();
是按调整后的显示方向返回的屏幕尺寸(以像素为单位)。
当前的旋转设置,对应相应的坐标轴。

回复

使用道具 举报

发表于 2016-2-3 09:25:43 | 显示全部楼层
楼主这个讲解不错,但是  图片的地址是什么意思   上传失败了吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-3 23:44:02 | 显示全部楼层
xw123789 发表于 2016-2-3 09:25
楼主这个讲解不错,但是  图片的地址是什么意思   上传失败了吗

是,我一直不会把文字和图片穿插着编辑
回复 支持 反对

使用道具 举报

发表于 2016-2-5 15:26:21 | 显示全部楼层
楼主,我是新手。
我买了个0.96寸的OLED屏,在学习SSD1306库里面的例子,例子里用到了Adafruit_GFX.h、Adafruit_SSD1306.h这两个库里面的函数,看不懂!我又翻了WIKI里那个“为Arduino编写函数库”的教程
按照教程里教的,引用库函数不应该是Adafruit_GFX.drawPixel ()或者Adafruit_SSD1306.drawPixel.drawPixel ( )吗
为什么例子里面都是
  display.drawPixel(10, 10, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();
这个display. 是哪个库里面的啊


回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-6 01:28:37 | 显示全部楼层
我不是专家,试着给你解释一下。

arduino IDE 是建立在 C/ C++ 语言基础上的,我们通常说他是 arduino C。

arduino C 在构建库文件时,一般要定义两个文件,一个是  .h 头文件,另一个是 .cpp 文件,是 C++格式,以 类 的方式定义各个功能模块,其中对 端口的定义大致如下:

Adafruit_SSD1306::Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) {
  cs = CS;
  rst = RST;
  dc = DC;
  sclk = SCLK;
  sid = SID;
  hwSPI = false;
}

注意 那两个 双冒号,其后的 函数是属于前面那个 Adafruit_SSD1306 的,这是一个 构造函数,并且允许重新构造。

在实际的程序中,他是这样引用的:

// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

请注意 红色的部分,第一个逗号前面端口定义有改变,而绿色的那个 display  是重新取的名   称之为   对象 名,意思是    定义 Adafruit_SSD1306 类的 对象 display ,其他的 函数是这个 对象的 成员,

使用格式就是:  对象 . 成员 。

C++的这种方式非常绕,其优点就是非常灵活,功能强大。注意范例中的 那个 绿色的 名字就行了。








回复 支持 反对

使用道具 举报

发表于 2016-2-6 11:44:22 来自手机 | 显示全部楼层
还是Adafruit_SSD1306 类,就是名字改成了display,是吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-6 17:20:47 | 显示全部楼层
本帖最后由 老来疯 于 2016-2-6 17:46 编辑
xw123789 发表于 2016-2-6 11:44
还是Adafruit_SSD1306 类,就是名字改成了display,是吧?


库里定义的  类 ,里面有一个 构造函数 ,在程序中使用时要把这个构造函数定义成  对象 ,其他的内容如  函数,是这个对象的成员,你在程序中使用这些函数(成员)时,要指明是哪个对象的,

为什么要把 构造函数 另行定义成 对象呢,这是因为 C++ 允许以 相同的名字 定义多个构造函数,只要它们的 签名不同就行,另一个重要的原因是 即便是 同一个 构造函数 当你多次 引用他时,冠以不同的 对象名,其函数(成员)就可以针对不同的 对象 进行操作,

例如:

// 假如这是你定义的第一个屏幕
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// 现在定义第二个 屏幕
#define OLED_MOSI_1  2
#define OLED_CLK_1   3
#define OLED_DC_1    4
#define OLED_CS_1    5
#define OLED_RESET_1 6
Adafruit_SSD1306 display_1(OLED_MOSI_1, OLED_CLK_1, OLED_DC_1, OLED_RESET_1, OLED_CS_1);

当你操作第一个屏幕时 对象名是 display,如:display.drawPixel(10, 10, WHITE);  // 操作第一个屏幕

当你操作第二个屏幕时 对象名是 display_1, 如: display_1.drawPixel(10, 10, WHITE);  // 操作第二个屏幕

当然还可以使用 其他的 构造函数,比如 使用 硬件 SPI ,或 使用  IIC 串行方式 驱动屏幕,只要给它们 取一个 不同的  对象名就行了。而它们的 成员(函数) 是一样的。这样就可以用相同的函数以不同的对象名来操作不同的设备,这是 C++ 的 优势。







回复 支持 反对

使用道具 举报

发表于 2016-2-6 23:51:25 来自手机 | 显示全部楼层
学习了,这例子真好,感谢楼主耐心讲解!
回复 支持 反对

使用道具 举报

发表于 2016-4-15 10:38:24 | 显示全部楼层
学习了,谢谢楼主分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 05:02 , Processed in 0.057135 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表