共计 5199 个字符,预计需要花费 13 分钟才能阅读完成。
Java 实现图片转字符输入示例 demo
后面几篇博文介绍了应用 jdk 来对图片做一些有意思的转换,接下来咱们再介绍一个有意思的玩法,间接依据图片,输入一个二维字符数组,实现用字符来实现绘画的场景
<!– more –>
各位小伙伴可能都有看到过一些乏味的正文,比方大佛,美女之类的,通关本文,置信你也很能够很简略的实现相似的场景
要害实现,在后面的文章中其实也说到了,上面是超链
- Java 也能够非常简单的实现图片灰度化 原创
- JavaFun | 实现图片转字符图片示例 demo 原创
- JavaFun | 基于 Java 实现 Gif 图转字符动图 原创
接下来咱们须要做的就是将之前转成字符图片输入的中央略微改一下,依据以后色色彩,来抉择适合的替换字符保留下来
所以要害的实现在于,如何依据色彩来抉择字符
// 这个字符来自于 github 搜寻后果,上面将最初一个从原来的点号改成了空格,即红色时,不输入字符
private static final String DEFAULT_CHAR_SET = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`' ";
/**
* 基于色彩的灰度值,获取对应的字符
* @param g
* @return
*/
public static char toChar(Color g) {double gray = 0.299 * g.getRed() + 0.578 * g.getGreen() + 0.114 * g.getBlue();
return DEFAULT_CHAR_SET.charAt((int) (gray / 255 * DEFAULT_CHAR_SET.length()));
}
接下来咱们针对之前的办法,略微革新一下
Color getAverage(BufferedImage image, int x, int y, int w, int h) {
int red = 0;
int green = 0;
int blue = 0;
int size = 0;
for (int i = y; (i < h + y) && (i < image.getHeight()); i++) {for (int j = x; (j < w + x) && (j < image.getWidth()); j++) {int color = image.getRGB(j, i);
red += ((color & 0xff0000) >> 16);
green += ((color & 0xff00) >> 8);
blue += (color & 0x0000ff);
++size;
}
}
red = Math.round(red / (float) size);
green = Math.round(green / (float) size);
blue = Math.round(blue / (float) size);
return new Color(red, green, blue);
}
private void parseChars(BufferedImage img) {int w = img.getWidth(), h = img.getHeight();
// 这个 size 可用来控制精度,越小则越像原图
int size = 4;
List<List<String>> list = new ArrayList<>();
for (int y = 0; y < h; y += size) {List<String> line = new ArrayList<>();
for (int x = 0; x < w; x += size) {Color avgColor = getAverage(img, x, y, size, size);
line.add(String.valueOf(toChar(avgColor)));
}
list.add(line);
}
System.out.println("---------------------- 开始 ------------------------");
for (List<String> line: list) {for (String s: line) {System.out.print(s + " ");
}
System.out.println();}
System.out.println("---------------------- 完结 ------------------------");
}
留神下面的实现,须要重点留神的是原图的遍历形式,一层一层的遍历,即内部是 y 轴,外部循环是 x 轴
接下来看一下测试 case
@Test
public void testChars() throws Exception{
String file = "http://pic.dphydh.com/pic/newspic/2017-12-13/505831-1.png";
BufferedImage img = ImageLoadUtil.getImageByPath(file);
// 缩放一下图片为 300x300,不便对输入字符截图
img = GraphicUtil.scaleImg(300,300, img);
parseChars(img);
System.out.println("---over------");
}
理论输入如下 (理论输入后果与皮神还是很像的)
---------------------- 开始 ------------------------
l m
' b $ I
f $ $ [
\ 8 $ $ f
i ~ , x $ $ $ u
_ $ $ a X } ^ ' W $ $ $ c
c $ $ $ $ B L ] ' } q $ $ $ z
` d $ $ $ $ $ 0 r ( " t < U $ $ c
, * $ $ $ $ z < + j | ` \ t < < O $ n
l W $ $ $ U < < < ~ t [ { + < < _ W f
> & $ $ 0 < < < < < - j ~ \ < < < < n (! # $ k < < < < < < < ( t ` j < < < <] ?
: k B 1 + < < < < < < + n ! > } < < < < \ i
^ C z ([ ~ < < < < < < f] 1 < < < < < u `
1 v ( ) ? < < < < < < | { ( < < < < < u
I v / (1 + < < < < < 1} 'l > i" \ < < < < ~ x
1 v (( [ ~ < < < < z r z t | \ n z f ( + 't < < < < ? /" / v |) ? < < < < < < < < < < < < < ] f ) ^ "\ < < < < | ?" ) n v / ~ < < < < < < < < < < < < < ~ j [ l 1 < < < + z ^
- | < < < < < < < < < < < < < < < < ] j ~ { < < < [ u
' f < < < < < < < < < < < < < < < < < < ~ z | < < ~ (/] + < < < < < < < < < < < < < < < < < < < < n - < ? n i
' | < < < < < < < < < < < < < < < < < < < < < < {~) v
) + < ] 0 w f < < < < < < < < < < < < < < < < < < ? / 1
x < ~ * @ "| [< < < < < < < < < < < < < < < < <} c'
i (<} $ $ x w \ < < < < < < < < < < < < < < < < < / -
/ < < + % $ $ 8 _ < < < < < < < < < < < < < < < < < { >
_ q f < < (q m} < < < < < < < < < < < < {\ ~ < < <} <
"O U Z < < < < < < < < < < n f < < < < < n r [ h + < < \"
j U U 0 } < < < < _ < < < < ~ ~ < < < < < M u ( $ r < < t
U U U Q (< < < < { Y v Y 0 Z} < < < < < * $ $ $ x < < |
J U U O [< < < < < # * # # o a t < < < < j $ $ # _ < <)
Y U U O < < < < < < W b q q k # # O r \ < < [/ + < <} <
x U L r < < < < < < d U c c C w * o L < < < < < < < < f '
} Q n < < < < < < < J x x x x z w W [ < < < < < < < < f : + [ { ,
^ f < < < < < < < < L x x x x x J Y < < < < < < _ Y O Y ] \ j \ [_} -
/ < < < < < < < < L x x x x x C _ < < < < < - Z U U Z j ? < < < < < \ v >
l | < < < < < < < Y x x x x X | < < < < < < J U U U z < < < < < < < + ) (i) t / L | + < < < < < c x x x c x < < < < < < ) L U U C t < < < < < < < < f !
? x ( < < < < ? f x j ~ < < 1 J x Y x < < < < < < < u U U U 0 < < < < < < < < + r
1 { < < < < < < < < < _ x \ < < t v 1 < < < < < < < < n U U Z [ < < < < < < < v x _
< ) < < < < < < < < < < < < {u] < < < < < < < < < < < - 0 m {< < < < < < <} n | / n r (/ \ 1} i '
/ < < < < < < < < < < < < < < ~ U < < < < < < < < < < < | c _ < < < < < < < - n < < < < < < < < < < {f / (] ^
| < < < < < < < < < < < < < < < ) n ] _ ~ < < < < < / n 1 < < < < < < < ~ [ L + < < < < < < < < < < < < < < _ t / 1 l
t < < < < < < < < < < < < < < < v j (() - < < ~ } + < < < < < < < < _ 1 Q j < < < < < < < < < < < < < < < < < < < ) f (:) + < < < < < < < < < < < < < < c [] ? ~ < < < < < < < < < < < < ~} ( c t [ < < < < < < < < < < < < < < < < < < < < < ~ / t <
^ x {}] ] - _ ~ < < < ~ _ ~ r c < < < < < < < < < < < < < < < - ) (u < \ < < 1 - < < < < < < < < < < < < < < < < < < < < < \)
< c (( ( ( ( ( () ) / Y n n < < < < < < < < < < < < < < ~ {( ( v i f < _ ( ( 1 _ < < < < < < < < < < < < < < < < < < + j '! v n ( ( ( ( r X c f ~ < < < < < < < < < < < < < < < ~ 1 ( ( c ; r <] (( ( (} + < < < < < < < < < < < < < < < + f'
] X x u u | + < < < < < < < < < < < < < < < < < < { ( t n ^ \ f < { ( ( ( ( ( ( [ ~ < < < < < < < < < < < < + / '
t ~ < < < < < < < < < < < < < < < < < < < < < < - (v { ?] < ) (( ( ( ( ( () ? < < < < < < < < < < + \
u < < < < < < < < < < < < < < < < < < < < < < < { w : \ < + ( ( ( | ( ( ( ( ( ( { ~ < < < < < < < ~ (i \ < < < < < < < < < < < < < < < < < < < < < < < ~ n j < - ( ( / x t c n ( ( ( () - < < < < < ~ (t < < < < < < < < < < < < < < < < < < < < < < < < < n +] : x < [ ( ( v ' ! | n X \ ( ( [ < < < ~ /
u < < < < < < < < < < < < < < < < < < < < < < < < < x ( 1 | r t ( < { ( x + "{ j z r { ~ ~ f'
~ 1 < < < < < < < < < < < < < < < < < < < < < < < < < t ] t 1 + < < < ( ( x ' ~ / n u ^
t < < < < < < < < < < < < < < < < < < < < < < < < < < \ i n ( ( ? < + ( v :
'r < < < < < < < < < < < < < < < < < < < < < < < < < < /" z (( (} ] | \
_ [ < < < < < < < < < < < < < < < < < < < < < < < < < < t L t \ Y u z z `
/ < < < < < < < < < < < < < < < < < < < < < < < < < < < / ; Z Q Q \ , I
' f < < < < < < < < < < < < < < < < < < < < < < < < < < < + # 0 d d d }
] ? < < < < < < < < < < < < < < < < < < < < < < < < < < < < Z d d d b ?
\ < < < < < < < < < < < < < < < < < < < < < < < < < < < < < u o b d k ~
j < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ] | ? u d :
j < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < j
r < ~ < < < < < < < < < < < < < < < < < < < < < < < < < < < < /
/ + (( { ? + < < < < < < < < < _ ?] ] ] ] ] - + < < < < < < f
i f (( ( ( ( 1 {} [[ [} 1 (( ( ( ( ( ( ( ( () } _ < < < /
] X (( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (} < < |
: (f) v u ( ( \ j u c c u x J d m C J | ( ( ( ( ( ( ( ( ( [ r \
` \ J t ] ~ {( ( n X r , ' ` < ( j c C z r ( ( ( ( ( | n z}
u X z r } / u c f \ 1 l ] j z J Y Y n ) } } v _
+ r () ( - I I n c \ + < <] L Z u ^
' i ] } | ( - x O w
; 1 \ z J
---------------------- 完结 ------------------------
虽说下面这个是输入了字符图,从后果上看也比价像,然而须要留神的是,若图片的背景非红色,配角不是那么突出的场景,通过下面的形式输入的后果可能就不太敌对了,解决办法当然就是辨认背景,辨认主体,针对主体元素进行转换(这个过程前面有机会再介绍)
接下来咱们借助开源我的项目 https://github.com/liuyueyi/quick-media 来迅速的实现字符图输入
以一个冰雪女王的转换图来验证下成果
String file = "http://5b0988e595225.cdn.sohucs.com/images/20200410/76499041d3b144b58d6ed83f307df8a3.jpeg";
BufferedImage res = ImgPixelWrapper.build().setSourceImg(file).setBlockSize(4).setPixelType(PixelStyleEnum.CHAR_BLACK).build().asBufferedImg();
一灰灰的联系方式
尽信书则不如无书,以上内容,纯属一家之言,因集体能力无限,不免有疏漏和谬误之处,如发现 bug 或者有更好的倡议,欢送批评指正,不吝感谢
- 集体站点:https://blog.hhui.top
- 微博地址: 小灰灰 Blog
- QQ:一灰灰 /3302797840
- 微信公众号: 一灰灰 blog
正文完