为了展示库的功能,空梦决定使用这个库编写一个应用程序——在控制台播放“Bad Apple”。
空梦很快就写好了最基本的代码,但是非常遗憾的是,由于 JNI 存在一些性能损失,空梦逐帧绘制时出现了明显的卡顿,这段程序很显然是需要进行优化的。
空梦想出了两种优化方式:
多线程优化
画布重用
多线程优化顾名思义就是多个线程同时绘制一帧或多帧,以此更加充分的利用 CPU 的各个核心的性能;画布重用就是绘制当前帧时不重置画布,而是在上一帧(如果使用了多级缓存则需要在前 N - 1 帧)的基础上进行绘制,仅重绘两帧之间不同的像素。
这两种优化方法的思路都是可行的,前者尝试通过多线程技术优化程序性能,后者则尝试通过改变程序逻辑来优化性能。
经过一番抉择,空梦决定使用“画布重用”来进行优化,但是由于空梦太笨,没有搞定如何计算两帧之间的不同的区域,并推导出一个最优的重绘方案,现在他来寻求参加天梯赛的各位佬的帮助,希望佬们能够帮助他解决这个问题。
空梦已经为控制台建好了坐标系,坐标系原点位于控制台的左上角,X 轴向右为正,Y 轴向下为正,原点的坐标为 (0, 0);同时他也已经对图像进行了预处理,将“Bad Apple”的每一帧都转换为了灰度图像(RGB 图像具有三个通道,灰度图像仅有一个通道),并规定了区分亮色与暗色像素的分界线,大于等于 128 的像素认为是亮色,小于 128 的像素认为是暗色。
需要注意的是,控制台在绘制颜色时只能横向绘制,不能纵向绘制(即每次填充的矩形的高度只能为 1),绘制区域超过当前行的范围时会自动换行。
假设我们现在有一个背景为亮色、长宽为 3 × 3 的画布:
222, 255, 160 128, 200, 255 233, 255, 151
现在我们要在 (0, 1) 的位置填充一个宽 4 的暗色矩形,填充后的结果为:
222, 255, 160 000, 000, 000 000, 255, 151
接下来 m 行每行 n 个非负整数,表示要绘制的这一帧的当前行的各个像素的灰度值 Bi,j,两两之间使用逗号间隔(行末没有逗号)。
x, y, color, width
其中 "x, y" 表示这个绘制操作起始的坐标点,"color" 表示要绘制的颜色("BLACK" 或 "WHITE",其中 "BLACK" 代表暗色,"WHITE" 代表亮色),"width" 表示绘制的宽度。
注意:逗号后包含一个空格,行末没有逗号。
3 3
222,255,160
128,200,255
233,255,151
222,255,160
000,000,000
000,255,151
1
0, 1, BLACK, 4
5 5 001,002,003,004,005 201,202,203,204,205 125,126,127,128,129 128,127,126,125,124 000,111,222,233,255 255,233,222,111,000 128,127,126,125,124 129,128,127,126,125 201,202,203,204,205 005,004,003,002,001
6 0, 0, WHITE, 3 1, 1, BLACK, 4 0, 2, WHITE, 2 3, 2, BLACK, 2 1, 3, WHITE, 4 2, 4, BLACK, 3