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

如何在WPF中将图像转为字节数组用于Adafruit SSD1306 OLED显示屏

WPF环境下将图像转换为SSD1306 OLED适用的字节数组实现方法

首先得明确Adafruit SSD1306单色OLED的显存规则:以128x64分辨率为例,显存被划分为8个"页",每页对应垂直方向的8行像素;每个字节对应垂直方向的8个像素(bit7对应页内最顶部的像素,bit0对应最底部),每页包含128个字节(对应水平128列),总字节数为128×8=1024。我们的目标就是把图像转换成符合这个格式的字节数组。

实现步骤与代码示例

1. 图像预处理(缩放、转灰度、二值化)

先把WPF中的图像调整到OLED的分辨率,转成灰度后再二值化(区分黑白像素):

// 加载图像并转换为适合处理的格式
private BitmapSource PrepareImage(string imagePath, int oledWidth = 128, int oledHeight = 64)
{
    var bitmap = new BitmapImage(new Uri(imagePath));
    
    // 缩放图像到OLED分辨率(保持比例,超出部分裁剪)
    var scaleTransform = new ScaleTransform();
    double scaleX = (double)oledWidth / bitmap.PixelWidth;
    double scaleY = (double)oledHeight / bitmap.PixelHeight;
    double scale = Math.Max(scaleX, scaleY);
    
    scaleTransform.ScaleX = scale;
    scaleTransform.ScaleY = scale;
    
    var scaledBitmap = new TransformedBitmap(bitmap, scaleTransform);
    
    // 裁剪到OLED精确尺寸
    var croppedBitmap = new CroppedBitmap(scaledBitmap, new Int32Rect(
        (scaledBitmap.PixelWidth - oledWidth) / 2,
        (scaledBitmap.PixelHeight - oledHeight) / 2,
        oledWidth,
        oledHeight));
    
    // 转换为8位灰度图
    return new FormatConvertedBitmap(croppedBitmap, PixelFormats.Gray8, null, 0);
}

// 二值化处理:根据阈值将灰度图转为黑白
private bool[,] BinarizeImage(BitmapSource grayImage, byte threshold = 127)
{
    int width = grayImage.PixelWidth;
    int height = grayImage.PixelHeight;
    bool[,] binaryPixels = new bool[width, height];
    
    byte[] pixelData = new byte[width * height];
    grayImage.CopyPixels(pixelData, width, 0);
    
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            // 灰度值大于阈值则为亮像素(true),否则为暗(false)
            binaryPixels[x, y] = pixelData[y * width + x] > threshold;
        }
    }
    
    return binaryPixels;
}

2. 转换为SSD1306格式的字节数组

根据OLED的页存储规则,将二值化后的像素数据拼成字节数组:

private byte[] ConvertToOledBytes(bool[,] binaryPixels, int oledWidth = 128, int oledHeight = 64)
{
    int pageCount = oledHeight / 8;
    byte[] oledBytes = new byte[oledWidth * pageCount];
    
    for (int page = 0; page < pageCount; page++)
    {
        for (int x = 0; x < oledWidth; x++)
        {
            byte b = 0;
            // 遍历当前页内的8个垂直像素
            for (int bit = 0; bit < 8; bit++)
            {
                int y = page * 8 + bit;
                if (binaryPixels[x, y])
                {
                    // 对应位置设为1(bit7是页内第0行,bit0是第7行)
                    b |= (byte)(1 << (7 - bit));
                }
            }
            oledBytes[page * oledWidth + x] = b;
        }
    }
    
    return oledBytes;
}

3. 完整调用示例

把上述方法组合起来,完成从图像到OLED字节数组的转换:

public byte[] ImageToOledByteArray(string imagePath, byte threshold = 127)
{
    var preparedImage = PrepareImage(imagePath);
    var binaryPixels = BinarizeImage(preparedImage, threshold);
    return ConvertToOledBytes(binaryPixels);
}

额外说明

  • 阈值可调:像目标工具一样,允许用户调整二值化阈值,适配不同图像的明暗效果
  • 分辨率适配:如果使用其他分辨率的SSD1306(如128x32),只需修改对应的oledWidth和oledHeight参数,代码会自动调整页数量和字节数
  • 像素反转:如果OLED显示的图像是反色的,可以在二值化时反转判断条件(pixelData[...] <= threshold),或者在生成字节时对每个字节取反(b = (byte)~b)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:35:07