如何在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
相关产品推荐
相关产品推荐

