1:准备工作
显示图片,自然就要准备一张图片啦!墨水屏的像素点是128*296,所以先准备一张128X296的图片。虽然编程很枯燥,但是图片还是要选好看的,给自己点乐趣。通过剪切、拉伸、裁剪,得到了以下的图片。

2:mpy显示图片
将准备好的图片放到images目录下边,然后参考例程,写个图片显示的代码

import os
import badger2040
from badger2040 import HEIGHT, WIDTH
import badger_os
import jpegdec
import pngdec
# Turn the act LED on as soon as possible
display = badger2040.Badger2040()
display.led(128)
display.set_update_speed(badger2040.UPDATE_NORMAL)
jpeg = jpegdec.JPEG(display.display)
file = "meizi.jpg"
name, ext = file.split(".")
jpeg.open_file("/images/{}".format(file))
jpeg.decode()
print(jpeg.get_height(),jpeg.get_width())
display.update()
很简单就显示出了图片。mpy完成功能超级简单,可以所有的操作都隐藏起来了,看不到是怎么实现的。从效果图上看,图片明显是使用了某种抖动算法,但是具体怎么实现的却未知。
3:重新显示图片
为了更好地理解图片的显示和抖动算法,又重新使用keil来编程。在C程序中,有写单个像素的操作。那么简单地理解,就是将图片每个像素绘制到屏幕上,即可展示图片内容了。但是墨水屏每个像素只能有两色,黑或白。二图片是一个RGB彩色图片,即使是将彩色图片转换为灰度图,那么每个像素也是0~255的灰度图,所以这里采取设定阈值方式,设定一个阈值,当灰度大于阈值时,就认为是黑色,小于阈值时判断为白色。依照这个思路重新编程。
第一步,将图片转换为灰度图矩阵。C下边读取文件、解码jpg图片,这些我都不会,所以简单粗暴地将图片直接读出来,做成一个128X296字节的变量。
import cv2
image = cv2.imread("meizi.jpg",cv2.IMREAD_GRAYSCALE)
# print(image)
# cv2.imwrite("meizi_gray.jpg",image)
(x,y)=image.shape
print(x,y)
for i in range(x):
for j in range(y):
print('0X%02X, ' % image[i,j],end='')
print()
第二步,将图片数据矩阵写到一个头文件中,作为全局变量,供代码使用。

第三步,利用循环,遍历屏幕上每一个点,找到对应图片的数据,通过阈值判断是否该涂黑改点(因为初始化墨水屏时,已经将墨水屏绘制为白色,所以只需要涂黑即可)。这里简单地使用了中位数128作为阈值,二值化算法也挺多,但基本原理都一致。
//显示美女图片 图片为 128*298格式图片
void EPD_ShowPicture()
{
uint16_t x, y;
for (y = 0; y < 128; y++)
{
for (x = 0; x < 296; x++)
{
if (MEINV[y * 296 + x] < 128)
draw_fb_point(x, y);
// else
// clear_fb_point(y, x);
// draw_fb_point(x, y);
}
}
}
可以看出,图片的边缘被很好地展现了,但是细节都丢失了。都看不出美女是否穿了衣服了。
4:抖动显示图片
图案法(patterning)是指灰度可以用一定比例的黑白点组成的区域表示,从而达到整体图象的灰度感。黑白点的位置选择称为图案化。说直白点,本来每个点只能显示黑白两色,现在用多个点来展示一个点信息,那么展示的颜色就会变多了。

现在我就是用这种方法,用4个像素点,显示一个点的信息。灰度,就能展示0~4 五种灰度值了。这里也是使用简单的算法,累加4个像素点的灰度值,然后5等分,用5个颜色表达出来。
//抖动方式显示 图片 4个像素合并进行抖动
void EPD_ShowDetailPicture()
{
uint16_t x, y;
uint16_t sumval;
for (y = 0; y < 128; y += 2)
{
for (x = 0; x < 296; x += 2)
{
sumval = MEINV[y * 296 + x] + MEINV[y * 296 + x + 1] + MEINV[y * 296 + 1 + x] + MEINV[y * 296 + 1 + x + 1];
// 最大值为255*4=1020 灰度分为5个等级,所以将1020/5=204
if (sumval < 204){
draw_fb_point(x, y);
draw_fb_point(x+1, y);
draw_fb_point(x, y+1);
draw_fb_point(x+1, y+1);
}
else if (sumval >= 204 && sumval < 408)
{
draw_fb_point(x, y);
draw_fb_point(x, y+1);
draw_fb_point(x+1, y+1);
}
else if (sumval >= 408 && sumval < 612)
{
draw_fb_point(x, y);
draw_fb_point(x+1, y+1);
}
else if (sumval >= 612 && sumval < 816)
{
draw_fb_point(x, y);
}
else
{
}
}
}
}
从效果上可以看出,细节多了很多,但是边缘信息有所丢失,嗯,至少看得出妹子穿衣服了。
视频地址:https://www.bilibili.com/video/BV1d2Y5eCEut/
我要赚赏金
