VisualHMI drawing: on_draw/redraw/drawing API and layered drawing

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

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

functionsparametersdescriptions
set_pen_color(color)RGB565 colorSet the brush foreground color, which affects line/border/outline/text strokes
draw_line(x0,y0,x1,y1,width)width 1~10Draw a line, with color taken from the current brush
draw_rect(x0,y0,x1,y1,fill)fill 1=fill/0=borderRectangle, x0,y0 top left corner, x1,y1 bottom right corner
draw_rect_alpha(x0,y0,x1,y1,alpha)alpha 0~255Semi-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 aboveDraw 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 frameDraw 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=GBKDraw text within the area
load_surface(filename)JPEG/PNG pathLoad external image and return handle (not through image.bin)
draw_surface(surface,dstx,dsty,w,h,srcx,srcy)surface handledraws loaded external images, supports cropping and scaling,must be called in on_draw
destroy_surface(surface)handleto release a single layer resource
destroy_all_surface()-batch release all loaded layers
get_surface_size(surface)handleto get the original pixel width and height of the layer
clear_image_buffer()-release internal image resource cache
screen_shoot(filepath)full path including extensionsave 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
end

3. 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.

ColorRGB(888)RGB565Recommended Lua constants
Red(255,0,0)0xF800COLOR_RED = 0xF800
Green(0,255,0)0x07E0COLOR_GREEN = 0x07E0
Blue(0,0,255)0x001FCOLOR_BLUE = 0x001F
White(255,255,255)0xFFFFCOLOR_WHITE = 0xFFFF
Black(0,0,0)0x0000COLOR_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
end

5. 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")
end

External 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.

Five pitfalls:① draw_xxx must be called in the on_draw callback to take effect, drawing anything in on_update will have no effect;② Control ID ≠ 0, control ID 0 does not trigger self-drawing;③ The fill semantics of draw_circle/draw_ellipse are opposite to that of draw_rect- for circles and ellipses, 0=solid, non-0=hollow, for rectangles, 1=filled/0=bordered, don't confuse them;④ The image_id of draw_image is found in the project's build/image.xml, not the file name;⑤ After using the external image, destroy_surface. The HMI memory is limited, and too many leaks will cause a crash.

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.

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email address will not be published. Required fields are marked *.