Complete LUA graphics API: lines, rectangles, semi-transparent rectangles, circles, ellipses, text, images, on-screen/off-screen images (SD/U-disk), screenshots. The core mechanism ison_draw(screen, control)control-level self-drawing callback - all draw_xxx instructions must be called in on_draw to take effect. Applicable to HMI&M series & Dx series.
1. Complete list of graphics API
| functions | parameters | descriptions |
|---|---|---|
set_pen_color(color) | RGB565 color | Set the brush foreground color, which affects line/border/outline/text strokes |
draw_line(x0,y0,x1,y1,width) | width 1~10 | Draw a line, with color taken from the current brush |
draw_rect(x0,y0,x1,y1,fill) | fill 1=fill/0=border | Rectangle, x0,y0 top left corner, x1,y1 bottom right corner |
draw_rect_alpha(x0,y0,x1,y1,alpha) | alpha 0~255 | Semi-transparent solid rectangle, 0=fully transparent/255=opaque, used as a mask layer |
draw_circle(x,y,r,fill) | fill 0=solid/non-0=hollow (value is line width) | Draw a circle, x,y for the center, r for the radius |
draw_ellipse(x0,y0,x1,y1,fill) | Outer rectangle corners, fill as above | Draw an ellipse tangent to the rectangle |
draw_image(image_id,frame_id,dstx,dsty,w,h,srcx,srcy) | image_id Check build/image.xml; frame_id animation frame | Draw engineering image resources, supports scaling and cropping |
draw_text(text,x,y,w,h,font_id,size,color,align,charcode) | align 0 left/1 center/2 right; charcode 0=UTF-8/1=GBK | Draw text within the area |
load_surface(filename) | JPEG/PNG path | Load external image and return handle (not through image.bin) |
draw_surface(surface,dstx,dsty,w,h,srcx,srcy) | surface handle | draws loaded external images, supports cropping and scaling,must be called in on_draw |
destroy_surface(surface) | handle | to release a single layer resource |
destroy_all_surface() | - | batch release all loaded layers |
get_surface_size(surface) | handle | to get the original pixel width and height of the layer |
clear_image_buffer() | - | release internal image resource cache |
screen_shoot(filepath) | full path including extension | save the current screen as JPEG |
2. on_draw trigger mechanism (must understand first)
on_draw(screen_id, control_id) is a system callback of, and users are not allowed to directly call. The control_id must be ≠ 0; otherwise, the custom drawing function will be invalid. Trigger conditions:
- The screen contains dynamic elements such as animations, videos, and RTC refresh
- Users touch/operate screen controls
- Scripts set_xxx update control properties
- Serial port/LUA changes registers causing changes in control state
- Actively calling redraw()
Multi-layer mechanism: HMI uses the Z-axis order of controls (the order of controls stacked in the editor) for layer management. on_draw is triggered independently for each redrawable control, and determines which layer to draw to based on the control_id. Example: A blue rectangle with ID=10 draws "fruit" on the lower layer, and a yellow rectangle with ID=11 draws "island" on the upper layer, with the yellow covering the blue part.
function on_draw(screen_id, control_id)
if screen_id == 0 and control_id == 1 then
draw_surface(surface[1], 293, 88, 222, 353, 0, 0) -- 裁剪显示
elseif screen_id == 0 and control_id == 2 then
draw_surface(surface[2], 314, 158, 180, 250, 0, 0)
end
end3. Color: RGB565
All color parameters are 16-bit RGB565: high 5 bits for Red (0~31), middle 6 bits for Green (0~63), and low 5 bits for Blue (0~31), with a range of 0x0000~0xFFFF.
| Color | RGB(888) | RGB565 | Recommended Lua constants |
|---|---|---|---|
| Red | (255,0,0) | 0xF800 | COLOR_RED = 0xF800 |
| Green | (0,255,0) | 0x07E0 | COLOR_GREEN = 0x07E0 |
| Blue | (0,0,255) | 0x001F | COLOR_BLUE = 0x001F |
| White | (255,255,255) | 0xFFFF | COLOR_WHITE = 0xFFFF |
| Black | (0,0,0) | 0x0000 | COLOR_BLACK = 0x0000 |
4. Application Cases: 15 Drawing Type Switches
4.1 Engineering Configuration
15 character setting buttons are all associated with LW6101, with constant values 1~15 corresponding to: Line/Rectangle/Semi-transparent Rectangle/Circle/Ellipse/Image ID/Text/On-screen Image/Destroy Image/Destroy All Images/Get Image Size/Video Window Screenshot/Screen Screenshot/Draw SD Image/Draw U-disk Image. 15 bit status indicators are associated with LW6100 to switch brush colors.
4.2 Framework: Mode Table + Switch Distribution
penColor = {0xF800, 0x001F} -- 红、蓝
CUR_COLOR = 0xF800 -- 初始颜色
draw_type = 0 -- 当前绘制类型
mode = { -- 绘制类型表
line = 1, rect = 2, rect_alpha = 3, circle = 4, ellipse = 5,
imageId = 6, text = 7, surface_path3 = 8, destroyOne = 9,
destroyAll = 10, getSurface = 11, videoShoot = 12,
screenShoot = 13, surface_pathsd = 14, surface_pathusb = 15
}
function on_update(slave, vtype, addr)
if addr == 0x6100 then
CUR_COLOR = penColor[get_uint16(VT_LW, addr) + 1] -- 切画笔
elseif addr == 0x6101 then
draw_type = get_uint16(VT_LW, addr) -- 切绘制类型
end
redraw() -- 触发重绘
end
function on_draw(screen_id, control_id)
set_pen_color(CUR_COLOR)
local switch = {
[mode.line] = function(control) -- 键值1
draw_line(225, 253, 405, 253) -- 默认宽度1
draw_line(508, 128, 508, 378, 5) -- 宽度5
end,
[mode.rect] = function(control) -- 键值2
draw_rect(225, 128, 225+180, 128+250, 0) -- 不填充
draw_rect(418, 163, 418+180, 128+180, 1) -- 填充
end,
[mode.rect_alpha] = function(control) -- 键值3
draw_rect_alpha(225, 128, 225+180, 128+250, 200) -- 透明度200
draw_rect_alpha(418, 163, 418+180, 128+180, 230) -- 透明度230
end,
[mode.circle] = function(control) -- 键值4
draw_circle(300, 253, 100, 0) -- 实心
draw_circle(450, 253, 150, 1) -- 空心(线宽1)
end,
[mode.ellipse] = function(control) -- 键值5
draw_ellipse(225, 128, 225+180, 128+250, 0) -- 实心
draw_ellipse(418, 163, 418+180, 128+180, 1) -- 空心
end,
[mode.text] = function(control) -- 键值7
draw_text("VisualHMI", 100, 300, 200, 40,
0, 24, CUR_COLOR, 1, 0) -- 居中 UTF-8
end,
}
if switch[draw_type] then
switch[draw_type](control)
end
end5. External Images (SD/U-disk) and Screenshots
-- 加载 SD 卡图片(load_surface 支持 JPEG/PNG)
if draw_type == mode.surface_pathsd then
surface[1] = load_surface("1:/pic.png")
redraw()
end
-- on_draw 里绘制
if draw_type == mode.surface_pathsd then
if surface[1] then
draw_surface(surface[1], 225, 128, 180, 250, 0, 0)
end
end
-- 截图到 SD 卡
if draw_type == mode.screenShoot then
screen_shoot("1:/shot.jpg")
endExternal images loaded with load_surfacedo not enter the project's image.binand are read from the file system during runtime. They must be released with destroy_surface after use, otherwise memory leaks will occur; large images or PNGs with transparent channels consume a lot of memory.
This is adapted from the VisualHMI development documentation of Guangzhou Dacai Technology (hmi-doc.gz-dc.com), LUA tutorial "Drawing", and the copyright belongs to Dacai Technology.
Leave a Reply