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/