Java实现图片转字符输出示例demo

Java实现图片转字符输出示例demo

前面几篇博文介绍了使用jdk来对图片做一些有意思的转换,接下来我们再介绍一个有意思的玩法,直接根据图片,输出一个二维字符数组,实现用字符来实现绘画的场景

各位小伙伴可能都有看到过一些有趣的注释,比如大佛,美女之类的,通关本文,相信你也很可以很简单的实现类似的场景

关键实现,在前面的文章中其实也说到了,下面是超链

接下来我们需要做的就是将之前转成字符图片输出的地方稍微改一下,根据当前色颜色,来选择合适的替换字符保存下来

所以关键的实现在于,如何根据颜色来选择字符

// 这个字符来自于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------");
}

实际输出如下(实际输出结果与皮神还是很像的)

image
---------------------- 开始 ------------------------
                                                                                          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();
image

一灰灰的联系方式

尽信书则不如无书,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容