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

C#图片转指定格式十六进制数组适配OLED显示异常问题

问题

需要将图片转换为0x00, 0x00,...格式的十六进制数组,用于Arduino OLED显示屏,但现有C#代码输出的是连续的PNG原始十六进制字符串(如89504e47...),调整格式后内容比目标输出长,写入Arduino后无法正常显示图片。

现有代码:

private void btnImg2ByteArray_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();

    dialog.Filter = "Select Valid Image(*.png)|*.png";
    dialog.Multiselect = true;

    if (dialog.ShowDialog() == DialogResult.OK)
    {
        foreach (string fileName in dialog.FileNames)
        {
            using (var ms = new MemoryStream())
            {
                Image imageIn = new Bitmap(fileName);
                imageIn.Save(ms, imageIn.RawFormat); //System.Drawing.Imaging.ImageFormat.Png
                byte[] b = ms.ToArray();
                txtImage2byte.Text += "[" + Path.GetFileName(fileName) + "]" + Environment.NewLine;
                StringBuilder hex = new StringBuilder(b.Length * 2);

                foreach (byte _b in b)
                {
                    hex.AppendFormat("{0:x2}", _b);
                }

                txtImage2byte.Text += hex.ToString();
            }
        }
    }
}
问题分析与解决

核心问题

你当前的代码是直接读取PNG文件的原始字节流(包含PNG文件头、压缩编码等冗余数据),但OLED显示屏需要的是图像的单色点阵压缩数据(比如128x64屏幕需要1024字节,每字节对应8个像素的黑白状态),两者完全不是同一类型的数据,所以长度不符且无法显示。

修改后的代码

下面的代码会将图片转换为OLED所需的点阵字节数组,并格式化为指定的0xXX, 格式:

private void btnImg2ByteArray_Click(object sender, EventArgs e)
{
    // 按你的OLED屏幕尺寸调整,这里以128x64为例
    int oledWidth = 128;
    int oledHeight = 64;

    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = "Image Files(*.png;*.jpg)|*.png;*.jpg";
    dialog.Multiselect = true;

    if (dialog.ShowDialog() == DialogResult.OK)
    {
        foreach (string fileName in dialog.FileNames)
        {
            txtImage2byte.Text += $"[{Path.GetFileName(fileName)}]{Environment.NewLine}";
            
            // 加载图片并缩放到OLED尺寸
            using (Bitmap originalBmp = new Bitmap(fileName))
            using (Bitmap resizedBmp = new Bitmap(originalBmp, oledWidth, oledHeight))
            {
                // 计算需要的字节数:每8个像素占1字节
                int byteCount = oledWidth * oledHeight / 8;
                byte[] oledData = new byte[byteCount];

                // 遍历OLED的每一页(共8页,每页8行像素)
                for (int page = 0; page < oledHeight / 8; page++)
                {
                    // 遍历每一列
                    for (int x = 0; x < oledWidth; x++)
                    {
                        byte currentByte = 0;
                        // 遍历当前页的8行像素
                        for (int bit = 0; bit < 8; bit++)
                        {
                            int y = page * 8 + bit;
                            Color pixelColor = resizedBmp.GetPixel(x, y);
                            
                            // 将像素转为黑白:亮度低于阈值则视为黑色(OLED点亮),否则白色(熄灭)
                            bool isBlack = (pixelColor.R + pixelColor.G + pixelColor.B) / 3 < 128;
                            if (isBlack)
                            {
                                currentByte |= (byte)(1 << bit);
                            }
                        }
                        // 填充到数组对应位置
                        oledData[page * oledWidth + x] = currentByte;
                    }
                }

                // 格式化为0xXX, 形式的字符串
                StringBuilder hexBuilder = new StringBuilder();
                foreach (byte b in oledData)
                {
                    hexBuilder.Append($"0x{b:x2}, ");
                }
                // 移除最后一个多余的逗号和空格
                if (hexBuilder.Length > 0)
                {
                    hexBuilder.Length -= 2;
                }

                txtImage2byte.Text += hexBuilder.ToString() + Environment.NewLine + Environment.NewLine;
            }
        }
    }
}

关键说明

  • 尺寸匹配:必须将图片缩放到和OLED屏幕一致的分辨率(比如128x64),否则点阵数据无法正确映射。
  • 单色转换:通过像素亮度阈值将彩色/灰度图转为黑白,适配OLED的单色显示特性。
  • 点阵存储规则:按照OLED的页存储模式(每页8行,每列8个像素组成一个字节)生成数据,和大多数OLED驱动库的要求一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:33:22