framebuf --- การจัดการบัฟเฟอร์เฟรม

โมดูล framebuf ให้บัฟเฟอร์พิกเซลขนาดเล็กที่ไม่ต้องจองหน่วยความจำ พร้อมการดำเนินการวาดพื้นฐาน โดยมีจุดประสงค์เพื่อขับเคลื่อนจอแสดงผลภายนอก (OLED, LCD, e-paper เป็นต้น)

Note

สำหรับงานประมวลผลภาพบนเฟรมที่ถ่ายได้ ให้ใช้คลาส image.Image ของ OpenMV ที่มีฟีเจอร์หลากหลายกว่ามากแทน เนื่องจากมี primitive การวาด, การแปลงสี และฟีเจอร์การวิเคราะห์มากกว่า framebuf อย่างมาก

class FrameBuffer

A FrameBuffer wraps a user-supplied buffer-protocol object (typically a bytearray) and exposes methods to draw pixels, lines, rectangles, ellipses, polygons, text and other FrameBuffers into it.

ตัวอย่าง:

import framebuf

# FrameBuffer needs 2 bytes for every RGB565 pixel.
fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)

fbuf.fill(0)
fbuf.text("MicroPython!", 0, 0, 0xffff)
fbuf.hline(0, 9, 96, 0xffff)

Constructor

class framebuf.FrameBuffer(buffer: Any, width: int, height: int, format: int, stride: int | None = None, /)

สร้างออบเจ็กต์ FrameBuffer

  • buffer -- ออบเจ็กต์ใด ๆ ที่รองรับ buffer protocol ต้องมีขนาดใหญ่พอที่จะรองรับพิกเซล stride * height ที่ format ที่เลือก

  • width -- ความกว้างของบัฟเฟอร์เฟรมเป็นพิกเซล

  • height -- ความสูงของบัฟเฟอร์เฟรมเป็นพิกเซล

  • format -- รูปแบบพิกเซล; ค่าใดค่าหนึ่งในค่าคงที่ที่ระบุไว้ใน ค่าคงที่ ด้านล่าง รูปแบบนี้กำหนดทั้งขนาดของแต่ละพิกเซลใน buffer และวิธีที่จำนวนเต็มสี c ที่ส่งไปยังเมธอดวาดใด ๆ จะถูกตีความ

  • stride -- จำนวนพิกเซลต่อแถวแนวนอน รวมถึง padding ใด ๆ ค่าเริ่มต้นคือ width กำหนดค่านี้เพื่อใช้ส่วนย่อยของบัฟเฟอร์ที่ใหญ่กว่า

การส่ง buffer ที่เล็กเกินไป หรือมิติที่ไม่ถูกต้องจะให้ผลลัพธ์ที่ไม่กำหนด เนื่องจาก constructor ไม่ตรวจสอบทุกการรวมกัน

เมธอดการวาด

FrameBuffer.fill(c: int) None

เติมบัฟเฟอร์เฟรมทั้งหมดด้วยสี c

FrameBuffer.fill_rect(x: int, y: int, w: int, h: int, c: int) None

เติมสี่เหลี่ยม w x h ที่ (x, y) ด้วยสี c เทียบเท่ากับ rect() ที่มี f=True

FrameBuffer.pixel(x: int, y: int, c: int | None = None) int | None

หากไม่มีอาร์กิวเมนต์ c จะคืนค่าสีของพิกเซลที่ (x, y) หากมี c จะกำหนดพิกเซลนั้นเป็นสี c

FrameBuffer.hline(x: int, y: int, w: int, c: int) None
FrameBuffer.vline(x: int, y: int, h: int, c: int) None
FrameBuffer.line(x1: int, y1: int, x2: int, y2: int, c: int) None

วาดเส้นหนา 1 พิกเซลด้วยสี c hline() และ vline() วาดเส้นแนวนอน/แนวตั้งตามความยาวที่กำหนด; line() วาดเส้นระหว่างสองจุดใด ๆ

FrameBuffer.rect(x: int, y: int, w: int, h: int, c: int, f: bool = False) None

วาดสี่เหลี่ยมที่ (x, y) ขนาด w x h ด้วยสี c หาก f เป็น True สี่เหลี่ยมจะถูกเติม; มิฉะนั้นจะวาดเฉพาะเส้นกรอบ 1 พิกเซล

FrameBuffer.ellipse(x: int, y: int, xr: int, yr: int, c: int, f: bool = False, m: int = 0) None

วาดวงรีที่มีจุดศูนย์กลางที่ (x, y) โดยมีรัศมี x คือ xr และรัศมี y คือ yr ด้วยสี c รัศมีที่เท่ากันจะสร้างวงกลม f=True เติมรูปทรงแทนที่จะเพียงแค่วาดเส้นกรอบ

m คือ bitmask ที่จำกัดการวาดไปยัง quadrant เฉพาะ (ลำดับทวนเข็มนาฬิกาจากด้านขวาบน):

Bit

Quadrant

บริเวณ

bit 0

Q1

ขวาบน

bit 1

Q2

ซ้ายบน

bit 2

Q3

ซ้ายล่าง

bit 3

Q4

ขวาล่าง

ค่าเริ่มต้น m=0 วาดทั้งสี่ quadrant

FrameBuffer.poly(x: int, y: int, coords: Any, c: int, f: bool = False) None

วาดรูปหลายเหลี่ยมปิดแบบใด ๆ (นูนหรือเว้า) ที่ offset (x, y) ด้วยสี c coords ต้องเป็น array ของจำนวนเต็มแบบมีเครื่องหมาย 16 บิตที่จัดวางเป็น array('h', [x0, y0, x1, y1, ..., xn, yn]) f=True เติมรูปหลายเหลี่ยมแทนที่จะเพียงแค่วาดเส้นกรอบ

FrameBuffer.text(s: str, x: int, y: int, c: int = 1) None

วาดสตริง s โดยมีมุมบนซ้ายที่ (x, y) ด้วยสี c แบบอักษรที่ฝังไว้มีขนาดคงที่ 8x8 พิกเซลและไม่สามารถเปลี่ยนได้ c มีค่าเริ่มต้นเป็น 1

FrameBuffer.scroll(xstep: int, ystep: int) None

เลื่อนเนื้อหาบัฟเฟอร์ด้วย (xstep, ystep) พิกเซลที่เลื่อนเข้ามาจากนอกบัฟเฟอร์ไม่ถูกล้าง ดังนั้นอาจมี "เงา" ของเนื้อหาก่อนหน้าค้างอยู่ที่ขอบท้าย

FrameBuffer.blit(fbuf: FrameBuffer | Tuple, x: int, y: int, key: int = -1, palette: FrameBuffer | None = None) None

วาดบัฟเฟอร์เฟรมอื่น fbuf ทับบัฟเฟอร์นี้ โดยมีมุมบนซ้ายที่ (x, y)

หากมี key พิกเซล source ใด ๆ ที่ตรงกับค่าสีนั้นจะถูกถือว่าโปร่งใสและไม่ถูกวาด เมื่อมี palette การเปรียบเทียบจะทำกับ output ของ palette ไม่ใช่ค่า fbuf ดิบ

fbuf สามารถเป็น instance ของ FrameBuffer หรือ tuple/list ที่ตรงกับ signature ของ constructor:

(buffer, width, height, format)
(buffer, width, height, format, stride)

เมื่อ source เป็น tuple/list buffer อาจเป็น read-only ได้

palette อนุญาตให้ blit ระหว่างบัฟเฟอร์ที่มีรูปแบบต่างกัน -- ตัวอย่างเช่น การ render glyph โทนเดียวลงในบัฟเฟอร์ RGB565 มันเป็น FrameBuffer ที่มีรูปแบบตรงกับปลายทาง โดยมีความสูง 1 และความกว้างเท่ากับจำนวนสี source (2**N สำหรับ source แบบ N-bit-per-pixel) ค่าพิกเซล source i จะถูกแทนที่ด้วยสีที่ palette[i, 0] ก่อนวาด

ค่าคงที่

ค่า format ต่อไปนี้รองรับโดย constructor คอลัมน์ "bytes per pixel" คือตัวคูณที่ต้องการเมื่อจัดขนาดบัฟเฟอร์รองรับ

ค่าคงที่

ไบต์/พิกเซล

รูปแบบพิกเซล

MONO_VLSB

0.125

Monochrome (1 บิต) แต่ละไบต์รองรับ 8 พิกเซลที่วางแนวตั้งโดยมี bit 0 อยู่ใกล้ด้านบนสุด แถวของ 8 พิกเซลเดินหน้าจากซ้ายไปขวาในบัฟเฟอร์ จากนั้น wrap ไปยังแถว 8 พิกเซลถัดไป

MONO_HLSB

0.125

Monochrome (1 บิต) แต่ละไบต์รองรับ 8 พิกเซลแนวนอนโดยมี bit 7 อยู่ซ้ายสุด แถวเลื่อนทีละพิกเซลในแนวตั้ง

MONO_HMSB

0.125

Monochrome (1 บิต) เหมือน MONO_HLSB แต่มี bit 0 อยู่ซ้ายสุด

GS2_HMSB

0.25

ระดับสีเทา 2 บิต (4 ระดับ) บรรจุในแนวนอนโดย most-significant bit ก่อน

GS4_HMSB

0.5

ระดับสีเทา 4 บิต (16 ระดับ) บรรจุในแนวนอนโดย most-significant nibble ก่อน

GS8

1

ระดับสีเทา 8 บิต (256 ระดับ)

RGB565

2

RGB 16 บิต ด้วย 5 บิตแดง, 6 บิตเขียว และ 5 บิตน้ำเงิน

framebuf.MVLSB เป็น alias ที่ถูก deprecated สำหรับ framebuf.MONO_VLSB; ควรใช้ตัวหลังในโค้ดใหม่

Constructor แบบเดิม

framebuf.FrameBuffer1(buffer: Any, width: int, height: int, stride: int | None = None, /) FrameBuffer

ทางลัดที่ถูก deprecated สำหรับ FrameBuffer(buffer, width, height, framebuf.MONO_VLSB, stride) เก็บไว้เพื่อความเข้ากันได้แบบย้อนหลัง; ใช้ constructor ของ FrameBuffer แบบเต็มแทน