
0. 介绍
如上图这种由文字拼成的图片看起来很有趣,利用变成语言可以非常轻松地绘制出这种图片。基本思路是用原位置像素颜色的文字替代该像素。本文把由文字拼成的图片分为两大类:
- 整图
- 半图
整图为整幅图均由文字组成,包括白色的像素点,一般原图像为彩色图和灰度图。半图则是部分区域填充文字,其余位置留白,如上图是半图。半图的原图一般是二值化图片。
1. 整图
思路是获取图像
I
(
x
,
y
)
I(x,y)
I(x,y),得到各个位置的RGB分量
[
I
R
(
x
,
y
)
,
I
G
(
x
,
y
)
,
I
B
(
x
,
y
)
]
[I_R(x,y), I_G(x,y), I_B(x,y)]
[IR(x,y),IG(x,y),IB(x,y)]。
目标是得到一幅由文字填充的图片
T
(
x
,
y
)
T(x,y)
T(x,y)。
方法是对于未知
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0),图像在该位置的像素是
I
(
x
0
,
y
0
)
I(x_0,y_0)
I(x0,y0)。在
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0)处添加文字
T
(
x
0
,
y
0
)
T(x_0,y_0)
T(x0,y0),文字颜色的RGB为
[
I
R
(
x
0
,
y
0
)
,
I
G
(
x
0
,
y
0
)
,
I
B
(
x
0
,
y
0
)
]
[I_R(x_0,y_0), I_G(x_0,y_0), I_B(x_0,y_0)]
[IR(x0,y0),IG(x0,y0),IB(x0,y0)]。
在Matlab中,添加文字很容易实现,调用text()函数即可。text()函数可以向数据点添加文本,调用格式为
text(x, y, txt, 'color', c, 'fontsize', fs);
x, y指定坐标;txt是在该位置添加的文本;c是该文本的颜色,这里使用RGB;fs是字体大小。下图所示在
(
0
,
0
)
,
(
0
,
1
)
,
(
1
,
0
)
(0,0), (0,1), (1,0)
(0,0),(0,1),(1,0)和
(
1
,
1
)
(1,1)
(1,1)分别添加文本A, B, C和D。
matlab代码实现如下
%matlab
clear;
word = '文字'; % 填充图像的文字,本文选择《出师表》
len = length(word);
img = imread('lena.jpeg');
%img = imresize(img, [100, 100]); % 如果图片太大,适当减小
[r, c, d] = size(img);
figure;
for i = 1 : r
for j = 1 : c
pos = mod((i-1)*c+j, len); % 循环选中文字
if pos == 0
pos = len;
end
t = word(pos);
text(j, -i, t, 'color', [img(i,j,1), img(i,j,2), img(i,j,3)], 'fontsize', 1.5);
end
end
xlim([1,c]);
ylim([-r,1]);
axis off;
print('lena.png', '-dpng', '-r1200');
需要注意的是,图像左上角的坐标为
(
0
,
0
)
(0,0)
(0,0),从上往下,从左往右依次增大,而右手坐标系
(
0
,
0
)
(0,0)
(0,0)在左下角,从下往上,从左往右依次增大,所以图像的坐标和添加文字的坐标需要做一些转换。另外,为了输出的图片能足够清晰,代码使用print()而不是savefig输出图像。图片应适当压缩,200*200分辨率已经很耗时间。
效果如下:
由于图片大小限制在5M,图中文字无法看清。局部放大效果图(眼睛位置)如下:
2. 半图
同样的思路,不同的是原图 I ( x , y ) I(x,y) I(x,y)只能取0或1,当 I ( x 0 , y 0 ) = 0 I(x_0,y_0)=0 I(x0,y0)=0时, ( x 0 , y 0 ) (x_0,y_0) (x0,y0)添加文字,其余留白。代码如下:
%matlab
clear;
word = '';
len = length(word);
img = imread('lena.jpeg');
img = rgb2gray(img);
img = img>128; % 选择恰当的阈值
[r, c] = size(img);
figure;
count = 1;
for i = 1 : r
for j = 1 : c
if img(i, j) == 0
pos = mod(count, len);
if pos == 0
pos = len;
end
t = word(pos);
text(j, -i, t, 'fontsize', 1.5);
count = count + 1;
end
end
end
xlim([1,c]);
ylim([-r,1]);
axis off;
print('lenabw.png', '-dpng', '-r1200');
效果图如下:
局部放大图:
3. 动图 / 视频
原理一样,把视频分解成帧,对每一帧图像输出对应的“文字图像”,最后合并成动图或视频。