User Tools

Site Tools


tutorials:gfx

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
tutorials:gfx [2012/04/04 18:00]
pburgess [Graphics Primitives]
tutorials:gfx [2012/05/10 17:08]
pburgess [Overview]
Line 1: Line 1:
 ====== Overview ====== ====== Overview ======
  
-The Adafruit_GFX library for Arduino provides a common syntax and set of graphics functions for all of our color LCD and OLED displays. This allows Arduino sketches to easily be adapted between display types with minimal fuss…and any new features, performance improvements and bug fixes will immediately apply across our complete offering of color displays.+The Adafruit_GFX library for Arduino provides a common syntax and set of graphics functions for all of our LCD and OLED displays. This allows Arduino sketches to easily be adapted between display types with minimal fuss…and any new features, performance improvements and bug fixes will immediately apply across our complete offering of color displays.
  
-The Adafruit_GFX library works together with a second library provided for each specific display type — for example, the ST7735 1.8" color LCD requires installing both the Adafruit_GFX and Adafruit_ST7735 libraries. [[http://​www.ladyada.net/​library/​arduino/​libraries.html|For information how to use and install libraries, see our tutorial!]]+The Adafruit_GFX library works together with a second library provided for each specific display type — for example, the ST7735 1.8" color LCD requires installing both the Adafruit_GFX and Adafruit_ST7735 libraries. ​The following libraries now operate in this manner: 
 + 
 +  * [[https://​github.com/​adafruit/​RGB-matrix-Panel|RGBmatrixPanel]],​ for our [[http://​www.adafruit.com/​products/​420|16x32]] and [[http://​www.adafruit.com/​products/​607|32x32]] RGB LED matrix panels. 
 +  * [[https://​github.com/​adafruit/​TFTLCD-Library|Adafruit_TFTLCD]],​ for our 2.8" [[http://​www.adafruit.com/​products/​335|TFT LCD touchscreen breakout]] and [[http://​www.adafruit.com/​products/​376|TFT Touch Shield for Arduino]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit-HX8340B|Adafruit_HX8340B]],​ for our [[http://​www.adafruit.com/​products/​797|2.2"​ TFT Display with microSD]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit-ST7735-Library|Adafruit_ST7735]],​ for our [[http://​www.adafruit.com/​products/​358|1.8"​ TFT Display with microSD]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit-PCD8544-Nokia-5110-LCD-library|Adafruit_PCD8544]],​ for the [[http://​www.adafruit.com/​products/​338|Nokia 5110/3310 monochrome LCD]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit-Graphic-VFD-Display-Library|Adafruit-Graphic-VFD-Display-Library]],​ for our [[https://​www.adafruit.com/​products/​773|128x64 Graphic VFD]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit-SSD1331-OLED-Driver-Library-for-Arduino|Adafruit-SSD1331-OLED-Driver-Library-for-Arduino]] for the [[http://​www.adafruit.com/​products/​684|0.96"​ 16-bit Color OLED w/microSD Holder]]. 
 +  * [[https://​github.com/​adafruit/​Adafruit_SSD1306|Adafruit_SSD1306]] for the Monochrome [[https://​www.adafruit.com/​products/​326|128x64]] and [[https://​www.adafruit.com/​products/​661|128x32]] OLEDs. 
 + 
 +[[http://​www.ladyada.net/​library/​arduino/​libraries.html|For information how to use and install libraries, see our tutorial!]]
  
 The libraries are written in C++ for Arduino but could easily be ported to any microcontroller by rewriting the low-level pin access functions. The libraries are written in C++ for Arduino but could easily be ported to any microcontroller by rewriting the low-level pin access functions.
 +
 ====== Coordinate System and Units ====== ====== Coordinate System and Units ======
  
-Pixels — picture elements, the blocks comprising a digital image — are addressed by their horizontal (X) and vertical (Y) coordinates. The coordinate system places the origin (0,0) at the top left corner, with positive X increasing to the right and positive Y increasing downward. This is upside-down relative to the standard Cartesian coordinate system of mathematics,​ but is established practice in many computer graphics systems (a throwback to the days of raster-scan CRT graphics, which worked top-to bottom). To use a tall “portrait” layout rather than wide “landscape” format, or if physical constraints dictate the orientation of a display in an enclosure, one of four rotation settings can also be applied, indicating which corner of the display represents the top left.+Pixels — picture elements, the blocks comprising a digital image — are addressed by their horizontal (X) and vertical (Y) coordinates. The coordinate system places the origin (0,0) at the top left corner, with positive X increasing to the right and positive Y increasing downward. This is upside-down relative to the standard Cartesian coordinate system of mathematics,​ but is established practice in many computer graphics systems (a throwback to the days of raster-scan CRT graphics, which worked top-to-bottom). To use a tall “portrait” layout rather than wide “landscape” format, or if physical constraints dictate the orientation of a display in an enclosure, one of four rotation settings can also be applied, indicating which corner of the display represents the top left.
  
 Also unlike the mathematical Cartesian coordinate system, points here have dimension — they are always one full integer pixel wide and tall. Also unlike the mathematical Cartesian coordinate system, points here have dimension — they are always one full integer pixel wide and tall.
  
-(Coordinate system diagram will go here)+{{ :​tutorials:​gfx:​coordsys.png?​nolink&​ |}}
  
-Coordinates are always expressed in pixel units; there is no implicit scale to a real-world measure like millimeters or inches, and the size of a displayed graphic will be a function of that specific display’s //dot pitch// or pixel density. If seeking ​specific ​real-world dimension, you’ll need to scale your coordinates to suit. Dot pitch can often be found in the device datasheet, or by measuring the screen width and dividing the number of pixels across by this measurement.+Coordinates are always expressed in pixel units; there is no implicit scale to a real-world measure like millimeters or inches, and the size of a displayed graphic will be a function of that specific display’s //dot pitch// or pixel density. If you’re aiming for a real-world dimension, you’ll need to scale your coordinates to suit. Dot pitch can often be found in the device datasheet, or by measuring the screen width and dividing the number of pixels across by this measurement.
  
-Colors ​are represented as unsigned 16-bit values. Some displays may physically be capable of more or fewer bits than this, but the library operates with 16-bit values…these are easy for the Arduino to work with while also providing a consistent data type across all the different displays. The primary color components — red, green and blue — are all “packed” into a single 16-bit variable, with the most significant 5 bits conveying red, middle 6 bits conveying green, and least significant 5 bits conveying blue.+For color-capable displays, colors ​are represented as unsigned 16-bit values. Some displays may physically be capable of more or fewer bits than this, but the library operates with 16-bit values…these are easy for the Arduino to work with while also providing a consistent data type across all the different displays. The primary color components — red, green and blue — are all “packed” into a single 16-bit variable, with the most significant 5 bits conveying red, middle 6 bits conveying green, and least significant 5 bits conveying blue. That extra bit is assigned to green because our eyes are most sensitive to green light. //​Science!//​
  
-(Color bit-packing diagram will go here)+{{ :​tutorials:​gfx:​colorpack.png?​nolink&​ |}}
  
 For the most common primary and secondary colors, we have this handy cheat-sheet that you can include in your own code. Of course, you can pick any of 65,536 different colors, but this basic list may be easiest when starting out: For the most common primary and secondary colors, we have this handy cheat-sheet that you can include in your own code. Of course, you can pick any of 65,536 different colors, but this basic list may be easiest when starting out:
Line 32: Line 44:
 #define WHITE    0xFFFF</​code>​ #define WHITE    0xFFFF</​code>​
  
 +For monochrome (single-color) displays, colors are always specified as simply ''​1''​ (set) or ''​0''​ (clear). The semantics of set/clear are specific to the type of display: with something like a luminous OLED display, a “set” pixel is lighted, whereas with a reflective LCD display, a “set” pixel is typically dark. There may be exceptions, but generally you can count on ''​0''​ (clear) representing the default background state for a freshly-initialized display, whatever that works out to be.
 ====== Graphics Primitives ====== ====== Graphics Primitives ======
  
 Each device-specific display library will have its own constructors and initialization functions. These are documented in the individual tutorials for each display type, or oftentimes are evident in the specific library header file. The remainder of this tutorial covers the common graphics functions that work the same regardless of the display type. Each device-specific display library will have its own constructors and initialization functions. These are documented in the individual tutorials for each display type, or oftentimes are evident in the specific library header file. The remainder of this tutorial covers the common graphics functions that work the same regardless of the display type.
  
 +The function descriptions below are merely //​prototypes//​ — there’s an assumption that a display object is declared and initialized as needed by the device-specific library. Look at the example code with each library to see it in actual use. For example, where we show ''​print(1234.56)'',​ your actual code would place the object name before this, e.g. it might read ''​screen.print(1234.56)''​ (if you have declared your display object with the name ''​screen''​).
  
 +===== Drawing pixels (points) =====
  
-  * Point +First up is the most basic pixel pusher. You can call this with X, Y coordinates ​and a color and it will make a single dot: 
-  * Line +
-  * Rect +
-  * Filled rect +
-  * Circle +
-  * Filled circle +
-  * Rounded rect +
-  * Filled rounded rect +
-  * Char and text (print/​println/​etc)+
  
 +<code C>void drawPixel(uint16_t x, uint16_t y, uint16_t color);</​code>​
  
 +[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735pixel.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735pixel_t.jpg?​nolink&​500x301 ​ |}}]]
  
-----+===== Drawing lines =====
  
 +You can also draw lines, with a starting and end point and color:
  
-==== Graphics Library ​ ====+<code C>void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);</​code>​
  
 +{{ :​tutorials:​gfx:​line.png?​nolink&​ |}}
  
 +[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735lines.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735lines_t.jpg?​nolink&​500x321 ​ |}}]]
  
 +For horizontal or vertical lines, there are optimized line-drawing functions that avoid the angular calculations:​
  
 +<code C>void drawFastVLine(uint16_t x0, uint16_t y0, uint16_t length, uint16_t color);
  
 +void drawFastHLine(uin86_t x0, uin86_t y0, uint8_t length, uint16_t color);</​code>​
  
 +===== Rectangles =====
  
 +Next up, rectangles and squares can be drawn and filled using the following procedures. Each accepts an X, Y pair for the top-left corner of the rectangle, a width and height (in pixels), and a color. ''​drawRect()''​ renders just the frame (outline) of the rectangle — the interior is unaffected — while ''​fillRect()''​ fills the entire area with a given color:
  
 +<code C>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);</​code>​
  
 +{{ :​tutorials:​gfx:​rect.png?​nolink&​ |}}
  
-**Drawing pixels**+[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735squares.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735squares_t.jpg?​nolink&​500x309 ​ |}}]]
  
-[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735pixel.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735pixel_t.jpg?​nolink&​500x301 ​ |}}]]+To create a solid rectangle with a contrasting outline, use fillRect() first, then drawRect() over it.
  
 +===== Circles =====
  
 +Likewise, for circles, you can draw and fill. Each function accepts an X, Y pair for the center point, a radius in pixels, and a color:
  
-First up is the most basic pixel pusher. You can call this with two coordinates and a color and it will make a dot: +<code C>void drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t ​color);
  
-<code C> void drawPixel(uint16_t ​x, uint16_t ​y, uint16_t color);</​code>​[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735lines.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735lines_t.jpg?​nolink&​500x321 ​ |}}]]+void fillCircle(uint16_t ​x0, uint16_t ​y0, uint16_t r, uint16_t color);</​code>​
  
 +{{ :​tutorials:​gfx:​circle.png?​nolink&​ |}}
  
 +[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735circles.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735circles_t.jpg?​nolink&​500x311 ​ |}}]]
  
-You can also draw lines, with a starting and end point and color+===== Rounded rectangles =====
  
-<code C>void drawLine(uint16_t x0uint16_t y0uint16_t x1uint16_t y1uint16_t color);</​code>​+For rectangles with rounded cornersboth draw and fill functions are again available. Each begins with an XYwidth and height (just like normal rectangles)then there’s a corner radius (in pixelsand finally the color value:
  
-If your lines are vertical or horizontalyou can call an optimized drawing function that doesn'​t do all the angular calculations.+<code C>void drawRoundRect(uint16_t x0uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);
  
-<code C>void drawVerticalLine(uint16_t x0, uint16_t y0, uint16_t ​length, uint16_t color);+void fillRoundRect(uint16_t x0, uint16_t y0, uint16_t ​w, uint16_t h, uint16_t radius, uint16_t color);</​code>​
  
-void drawHorizontalLine(uin86_t x0, uin86_t y0, uint8_t length, uint16_t color);</​code>​[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735squares.jpg|{{  http://​www.ladyada.net/​images/​18tftbreakout/​st7735squares_t.jpg?​nolink&​500x309  ​|}}]]+{{ :tutorials:​gfx:​roundrect.png?​nolink&​ |}}
  
 +Here’s an added bonus trick: because the circle functions are always drawn relative to a center pixel, the resulting circle diameter will always be an odd number of pixels. If an even-sized circle is required (which would place the center point //between// pixels), this can be achieved using one of the rounded rectangle functions: pass an identical width and height that are even values, and a corner radius that’s exactly half this value.
  
 +===== Triangles =====
  
-Next uprectangles ​and squares can be drawn and filled using the following proceduresIf you want recangle that has a contrasting outline color, **fillRect** first, then **drawRect** over it +With trianglesonce again there are the draw and fill functionsEach requires ​full seven parametersthe XY coordinates ​for three corner points defining the trianglefollowed by a color:
- +
-<code C>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);</​code>​[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735circles.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735circles_t.jpg?​nolink&​500x311 ​ |}}]] +
- +
- +
- +
-Likewise, for circlesyou can draw and fill +
- +
-<code C>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);</​code>​[[http://​www.ladyada.net/​images/​18tftbreakout/​st7735text.jpg|{{ ​ http://​www.ladyada.net/​images/​18tftbreakout/​st7735text_t.jpg?​nolink&​500x514 ​ |}}]]+
  
 +<code C>void drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_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);</​code>​
  
 +{{ :​tutorials:​gfx:​triangle.png?​nolink&​ |}}
 +===== Characters and text =====
  
-If you need to add some text, we have two basic string drawing procedures. The first is just for a single character. You can place the character ​anywhere, ​and with any color. ​We only have one font to save on spaceand its meant to be 5x8 pixels. If you pass **size** as 1 or if you don't put down a size, that will be what is used. If you need bigger text, the code can scale the font up by passing in a larger **size** ​(integer). It's a little blocky but this keeps the flash usage down so we don't need multiple fonts+There are two basic string drawing procedures ​for adding text. The first is just for a single character. You can place this character ​at any location ​and with any color. ​There’s ​only one font (to save on spaceand it’s ​meant to be 5x8 pixels, but an optional ​size parameter can be passed which scales ​the font by this factor ​(e.g. size=2 will render the text at 10x16 pixels per character). Its a little blocky but having just a single font helps keep the program size down.
  
 <code C>void drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint8_t size);</​code>​ <code C>void drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint8_t size);</​code>​
  
-Text is a little different. Instead of one procedure, ​you will set up the text size, color and location ​and then **print()** (just like Serial.print()!)+{{ :​tutorials:​gfx:​char.png?​nolink&​ |}} 
 + 
 +Text is very flexible but operates ​bit differently. Instead of one procedure, the text size, color and position are set up in separate functions ​and then the ''​print()''​ function is used — this makes it easy and provides all of the same string and number formatting capabilities of the familiar ''​Serial.print()''​ function!
  
 <code C>void setCursor(uint16_t x0, uint16_t y0); <code C>void setCursor(uint16_t x0, uint16_t y0);
Line 115: Line 135:
 void setTextColor(uint16_t color, uint16_t backgroundcolor);​ void setTextColor(uint16_t color, uint16_t backgroundcolor);​
 void setTextSize(uint8_t size); void setTextSize(uint8_t size);
 +void setTextWrap(boolean w);
 </​code>​ </​code>​
  
-First start with **setCursor(x,​ y)** this will place the top right corner of the text where-ever ​you please. Initially, its set to (0, 0). Then set the text color with **setTextColor(color)** by default ​its white. ​If you call **setTextColor(colorbackground)** it will also set a background color for the text (otherwise, the background is 'clear'. Finally, ​set the 'size' ​with **setTextSize(size)** this will 'multiply' the text by a scaling ​factor. Below you can see scales of 1 (default), 2 and 3. This is because we only ship the library with a simple font, to save space. You can just scale it to get bigger text without requiring a new font+Begin with ''​setCursor(x,​ y)'',​ which will place the top left corner of the text wherever ​you please. Initially ​this is set to (0,0) (the top-left corner of the screen). Then set the text color with ''​setTextColor(color)''​ — by default ​this is white. ​Text is normally drawn “clear” — the open parts of each character show the original background contents, but if you want the text to block out what’s underneath, a background color can be specified as an optional second parameter to ''​setTextColor()''​. Finally, ''​setTextSize(size)'' ​will multiply the scale of the text by a given integer ​factor. Below you can see scales of 1 (the default), 2 and 3. It appears blocky at larger sizes because we only ship the library with a single ​simple font, to save space.
  
 [[http://​www.ladyada.net/​images/​tftshield/​text.jpg|{{ ​ http://​www.ladyada.net/​images/​tftshield/​text_t.jpg?​nolink&​500x385 ​ |}}]] [[http://​www.ladyada.net/​images/​tftshield/​text.jpg|{{ ​ http://​www.ladyada.net/​images/​tftshield/​text_t.jpg?​nolink&​500x385 ​ |}}]]
  
-Finally, you can use **print()** or **println() ​**just like you do with **Serial**! For example, to print a string, use **print("​Hello world"​) ​**- that's the first line of the image above. ​To print variables, you can also use **print()** the second line is **print(1234.56)** and the third line is **print(0xDEADBEEF,​ HEX)**+After setting everything up, you can use ''​print()'' ​or ''​println()''​ — //just like you do with Serial ​printing!// For example, to print a string, use ''​print("​Hello world"​)'' ​- thats the first line of the image above. ​You can also use ''​print()''​ for numbers and variables — the second line above is the output of ''​print(1234.56)'' ​and the third line is ''​print(0xDEADBEEF,​ HEX)''​.
  
 +By default, long lines of text are set to automatically “wrap” back to the leftmost column. To override this behavior (so text will run off the right side of the display — useful for scrolling marquee effects), use setTextWrap(false). The normal wrapping behavior is restored with setTextWrap(true).
 +===== Bitmaps =====
  
 +You can draw small monochrome (single color) bitmaps, good for sprites and other mini-animations or icons:
  
-You can also rotate your drawing. Note that this will not rotate what you already drewbut it will relocate any new drawing. ​+<code C>void drawbitmap(uint8_t xuint8_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color);</​code>​
  
-[[http://​www.ladyada.net/​images/​tftshield/​rotated.jpg|{{ ​ http://​www.ladyada.net/​images/​tftshield/​rotated_t.jpg?​nolink&​500x385 ​ |}}]]+(Extended description is forthcoming — this is a somewhat advanced function that relies on ''​PROGMEM'',​ so beginners are best advised to steer clear of this for now.)
  
-<code C> void rotate(uint8_t rotation);</​code>​The rotation variable can be 0, 1, 2 or 3. Rotation 0 makes it so that the display is in portrait mode, with the USB jack in the top right. Rotation 2 is portrait, with the USB jack in the bottom left. Rotation 1 is landscape mode, with the USB jack in the bottom right and rotation 3 is also landscape, with the USB jack in the top left.+===== Clearing ​or filling ​the screen =====
  
-When you rotate, ​the origin point moves with you. You may need to reference the size of the screenwhich changes between portrait and landscape, use **width() **and **height()**! To get the size.+The fillScreen() function will set the entire display ​to a given colorerasing any existing content:
  
-<code C>uint16_t width();  +<code C>void fillScreen(uint16_t ​color);</​code>​
-uint16_t ​height();</​code>​+
  
 +===== Rotating the display =====
  
-You can draw small monochrome (single color) bitmapsgood for sprites and other mini-animations ​or icons +You can also rotate your drawing. Note that this will //not// rotate what you already drewbut it will change the coordinate system ​for any new drawing. This can be really handy if you had to turn your board or display sideways or upside down to fit in a particular enclosure. In most cases this only needs to be done once, inside ''​setup()''​.
-<code C> +
-void drawbitmap(uint8_t x, uint8_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color)+
-</​code>​+
  
 +[[http://​www.ladyada.net/​images/​tftshield/​rotated.jpg|{{ ​ http://​www.ladyada.net/​images/​tftshield/​rotated_t.jpg?​nolink&​500x385 ​ |}}]]
 +
 +<code C>void rotate(uint8_t rotation);</​code>​
 +
 +The rotation parameter can be 0, 1, 2 or 3. For displays that are part of an Arduino shield, rotation value 0
 +sets the display to a //​portrait//​ (tall) mode, with the USB jack at the top right. Rotation value 2 is also a portrait mode, with the USB jack at the bottom left. Rotation 1 is //​landscape//​ (wide) mode, with the USB jack at the bottom right, while rotation 3 is also landscape, but with the USB jack at the top left.
 +
 +When rotating, the origin point (0,0) changes — the idea is that it should be arranged at the top-left of the display for the other graphics functions to make consistent sense (and match all the function descriptions above).
 +
 +If you need to reference the size of the screen (which will change between portrait and landscape modes), use ''​width()''​ and ''​height()''​.
 +
 +<code C>​uint16_t width(); ​
 +uint16_t height();</​code>​
  
 +Each returns the dimension (in pixels) of the corresponding axis, adjusted for the display’s current rotation setting.
/home/ladyada/public_html/wiki/data/pages/tutorials/gfx.txt · Last modified: 2016/01/28 18:05 (external edit)