JavaFun | 實現圖片轉字元輸出示例demo
Java實現圖片轉字元輸出示例demo
原圖
字元圖
前面幾篇博文介紹了使用jdk來對圖片做一些有意思的轉換,接下來我們再介 紹一個有意思的玩法,直接根據圖片,輸出一個二維字元陣列,實現用字元來實現繪畫的場景
各位小夥伴可能都有看到過一些有趣的註釋,比如大佛,美女之類的,通關本文,相信你也很可以很簡單的實現類似的場景
關鍵實現,在前面的文章中其實也說到了,下面是超鏈
接下來我們需要做的就是將之前轉成字元圖片輸出的地方稍微改一下,根據當前色顏色,來選擇合適的替換字元儲存下來
所以關鍵的實現在於,如何根據顏色來選擇字元
// 這個字元來自於github搜尋結果,下面將最後一個從原來的點號改成了空格,即白色時,不輸出字元
private static final String DEFAULT_CHAR_SET = "[email protected]%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
---------------------- 結束 ------------------------
雖說上面這個是輸出了字元圖,從結果上看也比價像,但是需要注意的是,若圖片的背景非白色,主角不是那麼突出的場景,通過上面的方式輸出的結果可能就不太友好了,解決辦法當然就是識別背景,識別主體,針對主體元素進行轉換(這個過程後面有機會再介紹)
接下來我們藉助開源專案 http://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或者有更好的建議,歡迎批評指正,不吝感激
• 個人站點:http://blog.hhui.top • 微博地址: 小灰灰Blog [1] • QQ:一灰灰/3302797840 • 微信公眾號: 一灰灰blog
References
[1]
小灰灰Blog: http://weibo.com/p/1005052169825577/home
- 基於MySql,Redis,Mq,ES的高可用方案解析
- 1w5字詳細介紹分散式系統的那些技術方案
- 程式設計師的浪漫:三十行程式碼實現用她的名字作幅畫
- 【WEB系列】內嵌Tomcat配置Accesslog日誌檔案生成位置原始碼探索
- 【搜尋系列】ES查詢常用例項演示
- 【搜尋系列】ES文件基本操作CURD例項演示
- 【搜尋系列】ES基本專案搭建
- Nosql儲存系統-叢集工作原理
- 例項演示,帶你瞭解終端神器ncat
- Redis:你真的會Redis麼,一文告訴你如何學習
- 常用設計模式彙總,告訴你如何學習設計模式
- 微服務閘道器:從對比到選型,由理論到實踐
- 【WEB系列】從0到1實現自定義web引數對映器
- SpringBoot系列Mybatis之批量插入的幾種姿勢
- SpringBoot系列Mybatis之ResultMap、ResultType返回結果使用姿勢
- 【DB系列】Mybatis之批量插入的幾種姿勢
- 【DB系列】Mybatis之ResultMap、ResultType返回結果使用姿勢
- 【中介軟體】Prometheus基於AOP實現埋點採集上報
- JDNI注入:RMI之繞過trustURLCodebase配置的注入例項演示三
- JDNI注入:RMI Reference引起的注入case二