You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在wxLua面板中如何获取指定点的RGB颜色?

在ZeroBrane Studio中用wxLua实现左键点击获取面板像素颜色

问题背景

环境:Windows 10 + ZeroBrane Studio 2.01(MobDebug 0.805)
需求:左键点击wxPanel面板时,获取点击位置的像素颜色。尝试调用wxClientDC:GetPixel()方法时触发错误,提示attempt to call method 'GetPixel' (a nil value)。

最小复现代码:

package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")

frame = wx.wxFrame(wx.NULL, wx.wxID_ANY,  "How to use GetPixel?", wx.wxDefaultPosition, wx.wxSize(450, 450), wx.wxDEFAULT_FRAME_STYLE)

panel = wx.wxPanel(frame, wx.wxID_ANY)

function OnLeftUp(event)
local point = { x = event:GetX(), y = event:GetY() }
local pdc = wx.wxClientDC(panel)
-- local colour = pdc:GetPixel(point.x, point.y) -- 该行触发错误
  pdc:DrawText("Left mouse button UP at x = " .. tostring(point.x) .. " y = " .. tostring(point.y), point.x, point.y)
--  pdc:DrawText("Left mouse button UP at x = " .. tostring(point.x) .. " y = " .. tostring(point.y) .. " Red = " .. tostring(colour:GetRed()), point.x, point.y) -- 该行触发错误
  pdc:delete()
end

panel:Connect(wx.wxEVT_LEFT_UP, OnLeftUp)

local sizer = wx.wxBoxSizer(wx.wxVERTICAL)
sizer:Add(panel, 1, wx.wxEXPAND)
frame:SetSizer(sizer)

frame:SetAutoLayout(true)
wx.wxGetApp():MainLoop()

解决方法

wxLua中的wxClientDC没有直接提供GetPixel方法,需要通过内存DC和Bitmap来捕获面板画面,再读取像素颜色。修改后的代码如下:

package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")

frame = wx.wxFrame(wx.NULL, wx.wxID_ANY,  "Get Pixel Color Demo", wx.wxDefaultPosition, wx.wxSize(450, 450), wx.wxDEFAULT_FRAME_STYLE)

panel = wx.wxPanel(frame, wx.wxID_ANY)

function OnLeftUp(event)
    local point = { x = event:GetX(), y = event:GetY() }
    -- 创建与面板尺寸匹配的Bitmap
    local size = panel:GetClientSize()
    local bitmap = wx.wxBitmap(size:GetWidth(), size:GetHeight())
    local memdc = wx.wxMemoryDC(bitmap)
    
    -- 刷新面板并将内容绘制到内存DC
    panel:Refresh(false)
    panel:Update()
    memdc:Blit(0, 0, size:GetWidth(), size:GetHeight(), wx.wxClientDC(panel), 0, 0)
    
    -- 读取指定坐标的像素颜色
    local pixelData = wx.wxPixelData(bitmap)
    if pixelData:Ok() then
        local pixel = pixelData:GetPixel(point.x, point.y)
        local rgbText = string.format("点击位置: x=%d, y=%d | RGB=(%d,%d,%d)", 
            point.x, point.y, pixel.Red, pixel.Green, pixel.Blue)
        
        local dc = wx.wxClientDC(panel)
        dc:DrawText(rgbText, point.x, point.y)
        dc:delete()
    end
    
    -- 释放资源
    memdc:delete()
    bitmap:delete()
end

panel:Connect(wx.wxEVT_LEFT_UP, OnLeftUp)

local sizer = wx.wxBoxSizer(wx.wxVERTICAL)
sizer:Add(panel, 1, wx.wxEXPAND)
frame:SetSizer(sizer)

frame:SetAutoLayout(true)
wx.wxGetApp():MainLoop()

核心说明

  • 用wxMemoryDC和wxBitmap捕获面板当前的渲染内容,这是因为wxClientDC仅用于绘制,不支持直接读取像素
  • wxPixelData是wxLua中访问Bitmap像素的专用类,通过GetPixel方法可获取指定坐标的RGB分量
  • 操作完成后务必释放DC和Bitmap对象,避免内存泄漏

内容的提问来源于stack exchange,提问作者Youra_P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:54:53