mirror of
https://github.com/pimoroni/st7735-python.git
synced 2025-01-05 22:40:25 +03:00
Python 3 fixes, and fixes to support pillow library.
This commit is contained in:
@@ -22,8 +22,8 @@ import numbers
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
import Image
|
||||
import ImageDraw
|
||||
from PIL import Image
|
||||
from PIL import ImageDraw
|
||||
|
||||
import Adafruit_GPIO as GPIO
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
@@ -94,233 +94,233 @@ ILI9341_RED = 0xF800
|
||||
ILI9341_GREEN = 0x07E0
|
||||
ILI9341_CYAN = 0x07FF
|
||||
ILI9341_MAGENTA = 0xF81F
|
||||
ILI9341_YELLOW = 0xFFE0
|
||||
ILI9341_YELLOW = 0xFFE0
|
||||
ILI9341_WHITE = 0xFFFF
|
||||
|
||||
|
||||
def color565(r, g, b):
|
||||
"""Convert red, green, blue components to a 16-bit 565 RGB value. Components
|
||||
should be values 0 to 255.
|
||||
"""
|
||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
|
||||
"""Convert red, green, blue components to a 16-bit 565 RGB value. Components
|
||||
should be values 0 to 255.
|
||||
"""
|
||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
|
||||
|
||||
def image_to_data(image):
|
||||
"""Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
|
||||
#NumPy is much faster at doing this. NumPy code provided by:
|
||||
#Keith (https://www.blogger.com/profile/02555547344016007163)
|
||||
pb = np.array(image.convert('RGB')).astype('uint16')
|
||||
color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
|
||||
return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
|
||||
"""Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
|
||||
#NumPy is much faster at doing this. NumPy code provided by:
|
||||
#Keith (https://www.blogger.com/profile/02555547344016007163)
|
||||
pb = np.array(image.convert('RGB')).astype('uint16')
|
||||
color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
|
||||
return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
|
||||
|
||||
class ILI9341(object):
|
||||
"""Representation of an ILI9341 TFT LCD."""
|
||||
"""Representation of an ILI9341 TFT LCD."""
|
||||
|
||||
def __init__(self, dc, spi, rst=None, gpio=None, width=ILI9341_TFTWIDTH,
|
||||
height=ILI9341_TFTHEIGHT):
|
||||
"""Create an instance of the display using SPI communication. Must
|
||||
provide the GPIO pin number for the D/C pin and the SPI driver. Can
|
||||
optionally provide the GPIO pin number for the reset pin as the rst
|
||||
parameter.
|
||||
"""
|
||||
self._dc = dc
|
||||
self._rst = rst
|
||||
self._spi = spi
|
||||
self._gpio = gpio
|
||||
self.width = width
|
||||
self.height = height
|
||||
if self._gpio is None:
|
||||
self._gpio = GPIO.get_platform_gpio()
|
||||
# Set DC as output.
|
||||
self._gpio.setup(dc, GPIO.OUT)
|
||||
# Setup reset as output (if provided).
|
||||
if rst is not None:
|
||||
self._gpio.setup(rst, GPIO.OUT)
|
||||
# Set SPI to mode 0, MSB first.
|
||||
spi.set_mode(0)
|
||||
spi.set_bit_order(SPI.MSBFIRST)
|
||||
spi.set_clock_hz(64000000)
|
||||
# Create an image buffer.
|
||||
self.buffer = Image.new('RGB', (width, height))
|
||||
def __init__(self, dc, spi, rst=None, gpio=None, width=ILI9341_TFTWIDTH,
|
||||
height=ILI9341_TFTHEIGHT):
|
||||
"""Create an instance of the display using SPI communication. Must
|
||||
provide the GPIO pin number for the D/C pin and the SPI driver. Can
|
||||
optionally provide the GPIO pin number for the reset pin as the rst
|
||||
parameter.
|
||||
"""
|
||||
self._dc = dc
|
||||
self._rst = rst
|
||||
self._spi = spi
|
||||
self._gpio = gpio
|
||||
self.width = width
|
||||
self.height = height
|
||||
if self._gpio is None:
|
||||
self._gpio = GPIO.get_platform_gpio()
|
||||
# Set DC as output.
|
||||
self._gpio.setup(dc, GPIO.OUT)
|
||||
# Setup reset as output (if provided).
|
||||
if rst is not None:
|
||||
self._gpio.setup(rst, GPIO.OUT)
|
||||
# Set SPI to mode 0, MSB first.
|
||||
spi.set_mode(0)
|
||||
spi.set_bit_order(SPI.MSBFIRST)
|
||||
spi.set_clock_hz(64000000)
|
||||
# Create an image buffer.
|
||||
self.buffer = Image.new('RGB', (width, height))
|
||||
|
||||
def send(self, data, is_data=True, chunk_size=4096):
|
||||
"""Write a byte or array of bytes to the display. Is_data parameter
|
||||
controls if byte should be interpreted as display data (True) or command
|
||||
data (False). Chunk_size is an optional size of bytes to write in a
|
||||
single SPI transaction, with a default of 4096.
|
||||
"""
|
||||
# Set DC low for command, high for data.
|
||||
self._gpio.output(self._dc, is_data)
|
||||
# Convert scalar argument to list so either can be passed as parameter.
|
||||
if isinstance(data, numbers.Number):
|
||||
data = [data & 0xFF]
|
||||
# Write data a chunk at a time.
|
||||
for start in range(0, len(data), chunk_size):
|
||||
end = min(start+chunk_size, len(data))
|
||||
self._spi.write(data[start:end])
|
||||
def send(self, data, is_data=True, chunk_size=4096):
|
||||
"""Write a byte or array of bytes to the display. Is_data parameter
|
||||
controls if byte should be interpreted as display data (True) or command
|
||||
data (False). Chunk_size is an optional size of bytes to write in a
|
||||
single SPI transaction, with a default of 4096.
|
||||
"""
|
||||
# Set DC low for command, high for data.
|
||||
self._gpio.output(self._dc, is_data)
|
||||
# Convert scalar argument to list so either can be passed as parameter.
|
||||
if isinstance(data, numbers.Number):
|
||||
data = [data & 0xFF]
|
||||
# Write data a chunk at a time.
|
||||
for start in range(0, len(data), chunk_size):
|
||||
end = min(start+chunk_size, len(data))
|
||||
self._spi.write(data[start:end])
|
||||
|
||||
def command(self, data):
|
||||
"""Write a byte or array of bytes to the display as command data."""
|
||||
self.send(data, False)
|
||||
def command(self, data):
|
||||
"""Write a byte or array of bytes to the display as command data."""
|
||||
self.send(data, False)
|
||||
|
||||
def data(self, data):
|
||||
"""Write a byte or array of bytes to the display as display data."""
|
||||
self.send(data, True)
|
||||
def data(self, data):
|
||||
"""Write a byte or array of bytes to the display as display data."""
|
||||
self.send(data, True)
|
||||
|
||||
def reset(self):
|
||||
"""Reset the display, if reset pin is connected."""
|
||||
if self._rst is not None:
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.005)
|
||||
self._gpio.set_low(self._rst)
|
||||
time.sleep(0.02)
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.150)
|
||||
def reset(self):
|
||||
"""Reset the display, if reset pin is connected."""
|
||||
if self._rst is not None:
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.005)
|
||||
self._gpio.set_low(self._rst)
|
||||
time.sleep(0.02)
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.150)
|
||||
|
||||
def _init(self):
|
||||
# Initialize the display. Broken out as a separate function so it can
|
||||
# be overridden by other displays in the future.
|
||||
self.command(0xEF)
|
||||
self.data(0x03)
|
||||
self.data(0x80)
|
||||
self.data(0x02)
|
||||
self.command(0xCF)
|
||||
self.data(0x00)
|
||||
self.data(0XC1)
|
||||
self.data(0X30)
|
||||
self.command(0xED)
|
||||
self.data(0x64)
|
||||
self.data(0x03)
|
||||
self.data(0X12)
|
||||
self.data(0X81)
|
||||
self.command(0xE8)
|
||||
self.data(0x85)
|
||||
self.data(0x00)
|
||||
self.data(0x78)
|
||||
self.command(0xCB)
|
||||
self.data(0x39)
|
||||
self.data(0x2C)
|
||||
self.data(0x00)
|
||||
self.data(0x34)
|
||||
self.data(0x02)
|
||||
self.command(0xF7)
|
||||
self.data(0x20)
|
||||
self.command(0xEA)
|
||||
self.data(0x00)
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_PWCTR1) # Power control
|
||||
self.data(0x23) # VRH[5:0]
|
||||
self.command(ILI9341_PWCTR2) # Power control
|
||||
self.data(0x10) # SAP[2:0];BT[3:0]
|
||||
self.command(ILI9341_VMCTR1) # VCM control
|
||||
self.data(0x3e)
|
||||
self.data(0x28)
|
||||
self.command(ILI9341_VMCTR2) # VCM control2
|
||||
self.data(0x86) # --
|
||||
self.command(ILI9341_MADCTL) # Memory Access Control
|
||||
self.data(0x48)
|
||||
self.command(ILI9341_PIXFMT)
|
||||
self.data(0x55)
|
||||
self.command(ILI9341_FRMCTR1)
|
||||
self.data(0x00)
|
||||
self.data(0x18)
|
||||
self.command(ILI9341_DFUNCTR) # Display Function Control
|
||||
self.data(0x08)
|
||||
self.data(0x82)
|
||||
self.data(0x27)
|
||||
self.command(0xF2) # 3Gamma Function Disable
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_GAMMASET) # Gamma curve selected
|
||||
self.data(0x01)
|
||||
self.command(ILI9341_GMCTRP1) # Set Gamma
|
||||
self.data(0x0F)
|
||||
self.data(0x31)
|
||||
self.data(0x2B)
|
||||
self.data(0x0C)
|
||||
self.data(0x0E)
|
||||
self.data(0x08)
|
||||
self.data(0x4E)
|
||||
self.data(0xF1)
|
||||
self.data(0x37)
|
||||
self.data(0x07)
|
||||
self.data(0x10)
|
||||
self.data(0x03)
|
||||
self.data(0x0E)
|
||||
self.data(0x09)
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_GMCTRN1) # Set Gamma
|
||||
self.data(0x00)
|
||||
self.data(0x0E)
|
||||
self.data(0x14)
|
||||
self.data(0x03)
|
||||
self.data(0x11)
|
||||
self.data(0x07)
|
||||
self.data(0x31)
|
||||
self.data(0xC1)
|
||||
self.data(0x48)
|
||||
self.data(0x08)
|
||||
self.data(0x0F)
|
||||
self.data(0x0C)
|
||||
self.data(0x31)
|
||||
self.data(0x36)
|
||||
self.data(0x0F)
|
||||
self.command(ILI9341_SLPOUT) # Exit Sleep
|
||||
time.sleep(0.120)
|
||||
self.command(ILI9341_DISPON) # Display on
|
||||
def _init(self):
|
||||
# Initialize the display. Broken out as a separate function so it can
|
||||
# be overridden by other displays in the future.
|
||||
self.command(0xEF)
|
||||
self.data(0x03)
|
||||
self.data(0x80)
|
||||
self.data(0x02)
|
||||
self.command(0xCF)
|
||||
self.data(0x00)
|
||||
self.data(0XC1)
|
||||
self.data(0X30)
|
||||
self.command(0xED)
|
||||
self.data(0x64)
|
||||
self.data(0x03)
|
||||
self.data(0X12)
|
||||
self.data(0X81)
|
||||
self.command(0xE8)
|
||||
self.data(0x85)
|
||||
self.data(0x00)
|
||||
self.data(0x78)
|
||||
self.command(0xCB)
|
||||
self.data(0x39)
|
||||
self.data(0x2C)
|
||||
self.data(0x00)
|
||||
self.data(0x34)
|
||||
self.data(0x02)
|
||||
self.command(0xF7)
|
||||
self.data(0x20)
|
||||
self.command(0xEA)
|
||||
self.data(0x00)
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_PWCTR1) # Power control
|
||||
self.data(0x23) # VRH[5:0]
|
||||
self.command(ILI9341_PWCTR2) # Power control
|
||||
self.data(0x10) # SAP[2:0];BT[3:0]
|
||||
self.command(ILI9341_VMCTR1) # VCM control
|
||||
self.data(0x3e)
|
||||
self.data(0x28)
|
||||
self.command(ILI9341_VMCTR2) # VCM control2
|
||||
self.data(0x86) # --
|
||||
self.command(ILI9341_MADCTL) # Memory Access Control
|
||||
self.data(0x48)
|
||||
self.command(ILI9341_PIXFMT)
|
||||
self.data(0x55)
|
||||
self.command(ILI9341_FRMCTR1)
|
||||
self.data(0x00)
|
||||
self.data(0x18)
|
||||
self.command(ILI9341_DFUNCTR) # Display Function Control
|
||||
self.data(0x08)
|
||||
self.data(0x82)
|
||||
self.data(0x27)
|
||||
self.command(0xF2) # 3Gamma Function Disable
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_GAMMASET) # Gamma curve selected
|
||||
self.data(0x01)
|
||||
self.command(ILI9341_GMCTRP1) # Set Gamma
|
||||
self.data(0x0F)
|
||||
self.data(0x31)
|
||||
self.data(0x2B)
|
||||
self.data(0x0C)
|
||||
self.data(0x0E)
|
||||
self.data(0x08)
|
||||
self.data(0x4E)
|
||||
self.data(0xF1)
|
||||
self.data(0x37)
|
||||
self.data(0x07)
|
||||
self.data(0x10)
|
||||
self.data(0x03)
|
||||
self.data(0x0E)
|
||||
self.data(0x09)
|
||||
self.data(0x00)
|
||||
self.command(ILI9341_GMCTRN1) # Set Gamma
|
||||
self.data(0x00)
|
||||
self.data(0x0E)
|
||||
self.data(0x14)
|
||||
self.data(0x03)
|
||||
self.data(0x11)
|
||||
self.data(0x07)
|
||||
self.data(0x31)
|
||||
self.data(0xC1)
|
||||
self.data(0x48)
|
||||
self.data(0x08)
|
||||
self.data(0x0F)
|
||||
self.data(0x0C)
|
||||
self.data(0x31)
|
||||
self.data(0x36)
|
||||
self.data(0x0F)
|
||||
self.command(ILI9341_SLPOUT) # Exit Sleep
|
||||
time.sleep(0.120)
|
||||
self.command(ILI9341_DISPON) # Display on
|
||||
|
||||
def begin(self):
|
||||
"""Initialize the display. Should be called once before other calls that
|
||||
interact with the display are called.
|
||||
"""
|
||||
self.reset()
|
||||
self._init()
|
||||
|
||||
def set_window(self, x0=0, y0=0, x1=None, y1=None):
|
||||
"""Set the pixel address window for proceeding drawing commands. x0 and
|
||||
x1 should define the minimum and maximum x pixel bounds. y0 and y1
|
||||
should define the minimum and maximum y pixel bound. If no parameters
|
||||
are specified the default will be to update the entire display from 0,0
|
||||
to 239,319.
|
||||
"""
|
||||
if x1 is None:
|
||||
x1 = self.width-1
|
||||
if y1 is None:
|
||||
y1 = self.height-1
|
||||
self.command(ILI9341_CASET) # Column addr set
|
||||
self.data(x0 >> 8)
|
||||
self.data(x0) # XSTART
|
||||
self.data(x1 >> 8)
|
||||
self.data(x1) # XEND
|
||||
self.command(ILI9341_PASET) # Row addr set
|
||||
self.data(y0 >> 8)
|
||||
self.data(y0) # YSTART
|
||||
self.data(y1 >> 8)
|
||||
self.data(y1) # YEND
|
||||
self.command(ILI9341_RAMWR) # write to RAM
|
||||
def begin(self):
|
||||
"""Initialize the display. Should be called once before other calls that
|
||||
interact with the display are called.
|
||||
"""
|
||||
self.reset()
|
||||
self._init()
|
||||
|
||||
def display(self, image=None):
|
||||
"""Write the display buffer or provided image to the hardware. If no
|
||||
image parameter is provided the display buffer will be written to the
|
||||
hardware. If an image is provided, it should be RGB format and the
|
||||
same dimensions as the display hardware.
|
||||
"""
|
||||
# By default write the internal buffer to the display.
|
||||
if image is None:
|
||||
image = self.buffer
|
||||
# Set address bounds to entire display.
|
||||
self.set_window()
|
||||
# Convert image to array of 16bit 565 RGB data bytes.
|
||||
# Unfortunate that this copy has to occur, but the SPI byte writing
|
||||
# function needs to take an array of bytes and PIL doesn't natively
|
||||
# store images in 16-bit 565 RGB format.
|
||||
pixelbytes = list(image_to_data(image))
|
||||
# Write data to hardware.
|
||||
self.data(pixelbytes)
|
||||
def set_window(self, x0=0, y0=0, x1=None, y1=None):
|
||||
"""Set the pixel address window for proceeding drawing commands. x0 and
|
||||
x1 should define the minimum and maximum x pixel bounds. y0 and y1
|
||||
should define the minimum and maximum y pixel bound. If no parameters
|
||||
are specified the default will be to update the entire display from 0,0
|
||||
to 239,319.
|
||||
"""
|
||||
if x1 is None:
|
||||
x1 = self.width-1
|
||||
if y1 is None:
|
||||
y1 = self.height-1
|
||||
self.command(ILI9341_CASET) # Column addr set
|
||||
self.data(x0 >> 8)
|
||||
self.data(x0) # XSTART
|
||||
self.data(x1 >> 8)
|
||||
self.data(x1) # XEND
|
||||
self.command(ILI9341_PASET) # Row addr set
|
||||
self.data(y0 >> 8)
|
||||
self.data(y0) # YSTART
|
||||
self.data(y1 >> 8)
|
||||
self.data(y1) # YEND
|
||||
self.command(ILI9341_RAMWR) # write to RAM
|
||||
|
||||
def clear(self, color=(0,0,0)):
|
||||
"""Clear the image buffer to the specified RGB color (default black)."""
|
||||
width, height = self.buffer.size
|
||||
self.buffer.putdata([color]*(width*height))
|
||||
def display(self, image=None):
|
||||
"""Write the display buffer or provided image to the hardware. If no
|
||||
image parameter is provided the display buffer will be written to the
|
||||
hardware. If an image is provided, it should be RGB format and the
|
||||
same dimensions as the display hardware.
|
||||
"""
|
||||
# By default write the internal buffer to the display.
|
||||
if image is None:
|
||||
image = self.buffer
|
||||
# Set address bounds to entire display.
|
||||
self.set_window()
|
||||
# Convert image to array of 16bit 565 RGB data bytes.
|
||||
# Unfortunate that this copy has to occur, but the SPI byte writing
|
||||
# function needs to take an array of bytes and PIL doesn't natively
|
||||
# store images in 16-bit 565 RGB format.
|
||||
pixelbytes = list(image_to_data(image))
|
||||
# Write data to hardware.
|
||||
self.data(pixelbytes)
|
||||
|
||||
def draw(self):
|
||||
"""Return a PIL ImageDraw instance for 2D drawing on the image buffer."""
|
||||
return ImageDraw.Draw(self.buffer)
|
||||
def clear(self, color=(0,0,0)):
|
||||
"""Clear the image buffer to the specified RGB color (default black)."""
|
||||
width, height = self.buffer.size
|
||||
self.buffer.putdata([color]*(width*height))
|
||||
|
||||
def draw(self):
|
||||
"""Return a PIL ImageDraw instance for 2D drawing on the image buffer."""
|
||||
return ImageDraw.Draw(self.buffer)
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
from ILI9341 import *
|
||||
from .ILI9341 import *
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
import Image
|
||||
from PIL import Image
|
||||
|
||||
import Adafruit_ILI9341 as TFT
|
||||
import Adafruit_GPIO as GPIO
|
||||
@@ -44,12 +44,12 @@ disp = TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_h
|
||||
disp.begin()
|
||||
|
||||
# Load an image.
|
||||
print 'Loading image...'
|
||||
print('Loading image...')
|
||||
image = Image.open('cat.jpg')
|
||||
|
||||
# Resize the image and rotate it so it's 240x320 pixels.
|
||||
image = image.rotate(90).resize((240, 320))
|
||||
|
||||
# Draw the image on the display hardware.
|
||||
print 'Drawing image'
|
||||
print('Drawing image')
|
||||
disp.display(image)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
import Image
|
||||
from PIL import Image
|
||||
import time
|
||||
import Adafruit_ILI9341 as TFT
|
||||
import Adafruit_GPIO as GPIO
|
||||
@@ -44,19 +44,19 @@ disp = TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_h
|
||||
disp.begin()
|
||||
|
||||
# Load an image.
|
||||
print 'Loading image...'
|
||||
print('Loading image...')
|
||||
image = Image.open('cat.jpg')
|
||||
|
||||
# Resize the image and rotate it so it's 240x320 pixels.
|
||||
image = image.rotate(90).resize((240, 320))
|
||||
|
||||
print 'Press Ctrl-C to exit'
|
||||
print('Press Ctrl-C to exit')
|
||||
while(True):
|
||||
# Draw the image on the display hardware.
|
||||
print 'Drawing image'
|
||||
print('Drawing image')
|
||||
start_time = time.time()
|
||||
disp.display(image)
|
||||
end_time = time.time()
|
||||
print 'Time to draw image: ' + str(end_time - start_time)
|
||||
print('Time to draw image: ' + str(end_time - start_time))
|
||||
disp.clear((0, 0, 0))
|
||||
disp.display()
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
import Image
|
||||
import ImageDraw
|
||||
import ImageFont
|
||||
from PIL import Image
|
||||
from PIL import ImageDraw
|
||||
from PIL import ImageFont
|
||||
|
||||
import Adafruit_ILI9341 as TFT
|
||||
import Adafruit_GPIO as GPIO
|
||||
@@ -77,21 +77,21 @@ font = ImageFont.load_default()
|
||||
#font = ImageFont.truetype('Minecraftia.ttf', 16)
|
||||
|
||||
# Define a function to create rotated text. Unfortunately PIL doesn't have good
|
||||
# native support for rotated fonts, but this function can be used to make a
|
||||
# native support for rotated fonts, but this function can be used to make a
|
||||
# text image and rotate it so it's easy to paste in the buffer.
|
||||
def draw_rotated_text(image, text, position, angle, font, fill=(255,255,255)):
|
||||
# Get rendered font width and height.
|
||||
draw = ImageDraw.Draw(image)
|
||||
width, height = draw.textsize(text, font=font)
|
||||
# Create a new image with transparent background to store the text.
|
||||
textimage = Image.new('RGBA', (width, height), (0,0,0,0))
|
||||
# Render the text.
|
||||
textdraw = ImageDraw.Draw(textimage)
|
||||
textdraw.text((0,0), text, font=font, fill=fill)
|
||||
# Rotate the text image.
|
||||
rotated = textimage.rotate(angle, expand=1)
|
||||
# Paste the text into the image, using it as a mask for transparency.
|
||||
image.paste(rotated, position, rotated)
|
||||
# Get rendered font width and height.
|
||||
draw = ImageDraw.Draw(image)
|
||||
width, height = draw.textsize(text, font=font)
|
||||
# Create a new image with transparent background to store the text.
|
||||
textimage = Image.new('RGBA', (width, height), (0,0,0,0))
|
||||
# Render the text.
|
||||
textdraw = ImageDraw.Draw(textimage)
|
||||
textdraw.text((0,0), text, font=font, fill=fill)
|
||||
# Rotate the text image.
|
||||
rotated = textimage.rotate(angle, expand=1)
|
||||
# Paste the text into the image, using it as a mask for transparency.
|
||||
image.paste(rotated, position, rotated)
|
||||
|
||||
# Write two lines of white text on the buffer, rotated 90 degrees counter clockwise.
|
||||
draw_rotated_text(disp.buffer, 'Hello World!', (150, 120), 90, font, fill=(255,255,255))
|
||||
|
||||
11
setup.py
11
setup.py
@@ -9,12 +9,23 @@ from ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
classifiers = ['Development Status :: 4 - Beta',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Intended Audience :: Developers',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Software Development',
|
||||
'Topic :: System :: Hardware']
|
||||
|
||||
setup(name = 'Adafruit_ILI9341',
|
||||
version = '1.5.0',
|
||||
author = 'Tony DiCola',
|
||||
author_email = 'tdicola@adafruit.com',
|
||||
description = 'Library to control an ILI9341 TFT LCD display.',
|
||||
license = 'MIT',
|
||||
classifiers = classifiers,
|
||||
url = 'https://github.com/adafruit/Adafruit_Python_ILI9341/',
|
||||
dependency_links = ['https://github.com/adafruit/Adafruit_Python_GPIO/tarball/master#egg=Adafruit-GPIO-0.6.5'],
|
||||
install_requires = ['Adafruit-GPIO>=0.6.5'],
|
||||
|
||||
Reference in New Issue
Block a user