+ N8 o6 f; @2 ~/ ^) O% o, q/ }. Q4 z
这种做法,可以说是完全没有什么技术水平了。想要画什么内容,还得预先编排字符,太麻烦了。于是便有了升级版。 8 p" U# y1 E" N1 E+ L( k# ^/ ]& j6 B: O* @' L
图片转字符- `9 {6 S4 ~" }3 y2 A' c3 r' o
这种用图片转字符,看似没有什么意义,但其实有时候可以创作出意想不到的作品。比如前一阵子的顶流冰墩墩。9 ?8 u3 m( \6 k& p5 N7 x0 y7 z. z
% [# b7 l) O6 X- @' x7 v& m, a; J% Z% w |+ F5 R7 B& o
0 Z. m8 ^) v: \2 T9 J这种做法的思路总的来说,就是把图片的抽样图片的像素信息,然后将像素信息中关键的亮度信息用特殊的字符串进行打印,效果就是我们最终看到的样子。# P1 w' E; z4 V2 I; T' t& X
' C; y; Q6 t; W
public static void printImage(BufferedImage image) throws IOException {3 J9 I2 i) Q# \9 |
final char[] PIXEL_CHAR_ARRAY = {'W', '@', '#', '8', '&', '*', 'o', ':', '.', ' '}; + l+ ^3 _/ f/ ^& _$ ` int width = image.getWidth();: R6 j: T. {% g/ @+ | `' }
int height = image.getHeight(); 6 `5 B+ u, \; _& M6 H/ [. F2 n for (int i = 0; i < height; i++) {4 S$ G8 v$ h( g% c
for (int j = 0; j < width; j++) {! c1 O* M& W. I/ b
int rgb = image.getRGB(j, i); 0 s5 C2 @6 L) S' b7 T/ }) [ Color color = new Color(rgb);; w' s1 V' |; b# ]+ y
int red = color.getRed();2 \# V5 Y. Q% A' Q5 E
int green = color.getGreen();) |3 q) G( J2 w7 ^" Y/ Y
int blue = color.getBlue(); Q& [% _2 b# P
// 一个用于计算RGB像素点灰度的公式7 ^. O# T0 O- R: e( h4 @- I
Double grayscale = 0.2126 * red + 0.7152 * green + 0.0722 * blue;& Z# u7 p- U5 e& Q
double index = grayscale / (Math.ceil(255 / PIXEL_CHAR_ARRAY.length) + 0.5); ( t" i1 T; N1 I7 j: L System.out.print(PIXEL_CHAR_ARRAY[(int)(Math.floor(index))]);7 I! `" l8 s* r3 ]4 f# u6 f5 v
} 9 q! s" n4 Z2 l% x" V4 ]* f9 K- w System.out.println();- _; q/ e& f# j5 B6 R
}/ h7 O( D5 u2 b" t& o; i
}9 J, c8 ^/ n' t/ j) Z+ B
3 S1 p4 U& Z! W" z
1: b6 b3 W, B% G& P
2 / v# r: Y: Z8 z) S3 9 H3 |& J! ^% S4* G( A; [$ \% M- z
5 / z' W4 H1 b7 J: P3 y% `63 |4 g& R# n: ?0 W
7 ( h+ W) R6 T8 l3 ]3 J8% }! S! Z+ A" B) l- W
9 / Q8 J1 I# w: o5 |9 \& f+ p. l10 5 X! V2 h- }2 X2 ^! ~ e$ p114 P. C$ k- H6 n( i" ?8 H- C# N$ `
12 0 Q$ g) M u% L+ }13) y5 I$ O: |5 a3 }' J
14& J `& b% y* b$ m- v" r/ J
15, i9 Q: B5 s" ^) E+ F. l- p
169 @/ g4 R1 D& ~5 R% d) }
17 7 e8 s9 q. h3 n: O18 $ f1 X6 a1 p9 ~4 z% e; M( G6 O0 N7 i19 ( ?( x8 T+ L$ ]) n- u7 U& R$ r6 n更多具体实现可以参考 字符作画,我用字符画个冰墩墩 。 % E2 X+ x# X/ N. z; M1 t: @ * h. a. i. v4 n0 q$ C- ]5 F8 c# Z使用 Python-turtle 库作图 & F8 R: p7 Z: _; V5 B下面这几幅知乎用户的回答,可以说是非常有水平了。* \+ r( G6 ^ S, T2 w4 v! T
; b m$ }* @( x 2 ^2 W' D q0 v4 J9 J' ]+ ^* L9 h. _* z/ l$ ~( S {% \& [9 P
import random 1 O$ O K- p* Y, P4 Gimport turtle4 l0 k- e6 c9 t7 W# g
from turtle import *7 w9 e+ n$ ]3 f# H, `, ?& g4 R
% k+ i. d- C8 B4 \( Lt = turtle.Turtle(); @7 O/ V! y" |# O7 t3 x' s: m2 e
w = turtle.Screen() 2 U- K5 q# T2 R) w' Y/ P- z) ?2 H3 C( G" t3 W; Z3 a. _ h# R
$ H) y6 V0 t* m" J o& edef tree(branchLen, t):9 E! J) K8 Q7 c7 q4 S
if branchLen > 3:* V8 P' n! r% f7 }/ l2 y+ B
if 8 <= branchLen <= 12: , l4 L7 R. N: Y if random.randint(0, 2) == 0:: v9 W- x4 K! A
t.color('snow') # x" E* e P [ E( T/ x else: f1 Y4 O$ O/ ^4 l j7 j t.color('lightcoral')7 K* c# K' o2 W; f1 T
t.pensize(branchLen / 3) , s( D. e- y( s1 [ o elif branchLen < 8: " q5 s$ p# C4 ?2 G% V5 w9 h) ] if random.randint(0, 1) == 0: & d+ E1 c, T6 L% m/ x7 C t.color('snow')0 x$ O) g. f" H% d
else: " ^" \* z/ ]! H6 ]5 X* y x t.color('lightcoral') ; A& I% H: x& D* p t.pensize(branchLen / 2) 9 q6 \8 ~5 m7 B/ T, n. Z8 c/ { else: M$ n: u `% g t.color('sienna'); z1 u8 {' ?$ A
t.pensize(branchLen / 10) - H; ^6 Q! V2 B I3 _0 v6 Z' [4 ?5 N# x, l: w# Z8 v! T
t.forward(branchLen)* O7 X8 k, ^8 m- d5 i: Q4 Y: n
a = 1.5 * random.random()8 A4 R( L! E; h G0 g% E
t.right(20 * a) 7 e- [% u, i. j: K b = 1.5 * random.random()/ Q* s D j' ^' z; j! T
tree(branchLen - 10 * b, t) . y: M8 f( Q( b" y t.left(40 * a)) v' y# v5 B8 ~
tree(branchLen - 10 * b, t)1 i+ }* W# C: l5 L: d# ]+ w- p! q
t.right(20 * a) . Q/ q# C* h! o& o& Q t.up() 6 s2 U) e g! H t.backward(branchLen)6 z- y, Z% F4 }) w) J) f
t.down()- N/ G5 ~7 q/ k. @9 [; u% O
3 ? k$ V3 v# ~! T$ Z$ `2 a
% s/ Y; I: f' ?1 t- ]3 {* @' \" i3 P" _def petal(m, t): # 树下花瓣 }, O8 u1 j8 w, l4 C) M
for i in range(m): ' t3 H9 U$ J" g4 [ a = 200 - 400 * random.random()' G- O# ^8 O* F9 y; Q; x3 o2 i
b = 10 - 20 * random.random(): F2 m0 `8 V( @" f6 y$ _
t.up() 4 i( M1 p# j b/ S/ @ t.forward(b) ! A% O* |6 v6 C/ A7 I t.left(90) ' [' s# w' V( L& i t.forward(a)4 p3 a( H: h |4 U$ x
t.down() 8 z6 |# z2 R6 i! i/ h7 U( {4 R7 J t.color("lightcoral") 8 D9 |( O" P# R4 W3 b t.circle(1)8 X* B5 p& S, `+ q
t.up(). b4 w Q' T/ K, V9 @' P0 A
t.backward(a) # b+ K8 T d: j! t# r t.right(90) 4 B) e' ~2 P5 Z, b* A t.backward(b)) n, H, i' G+ s7 ]
, l( Z+ f4 {$ y0 o# S! O) j" T( K5 |
! V' e1 |" {& M! V3 ?$ @
def main():! ~& g& ]0 j' @
t = turtle.Turtle() 1 z; R2 J0 [# j V V/ T myWin = turtle.Screen() ; }3 E) g C0 }* E* ?/ c getscreen().tracer(5, 0); I M7 G: L2 w% U
turtle.screensize(bg='wheat') . ]; y7 X+ A( v5 h9 {: g( B t.left(90) " a1 e- c/ J: y t.up() 2 F4 H* B6 C7 E- I0 G- h t.backward(150)) ]+ B( [4 h/ C2 u4 l
t.down() 0 @( s' `( X$ ~6 f t.color('sienna')8 }2 \8 [6 Q! f" g I. E
tree(60, t)0 {; m8 w5 _' |+ n% j
petal(100, t) - b0 ~4 ~7 ?7 \5 d & p' ]# h, a3 r4 M E! o+ U myWin.exitonclick() % }0 W% {# o3 v x; p- I E& E. N6 Q6 ^6 y% s' m5 K
! n. _% N; a3 }) i, ?' I- q; Mif __name__ == '__main__':* g( @0 T$ |8 i" k6 z8 d- C1 n2 j
main()' A( o6 u1 k( h/ f- g0 G
" S$ j7 y( F# `+ V H
7 V) q3 B( G' `+ Z% V9 o
1 % M. e: V9 j" M X: u5 g2, j" c$ u! _1 |
3 ( {/ P/ z' W; `0 C# P- J4+ {0 e+ \* R) m, k
5 6 r! S @" x% m- E4 W7 {/ M1 w6 , e% P$ H; {% N7* P! Y! ^, b! a. k; R
8 6 {4 E- H, {) t$ l9% c4 A4 }7 k: Z- k* y/ [, }
10. G4 F: G4 Y$ G* y2 j8 x2 _
11 . g: y4 g2 V. r! D5 o7 D/ v5 J1 o: V12 $ ?( ]" ^: X2 v2 b/ ~% W/ ?3 K. F13 ! Z" q- u0 Z, E7 G14 " X7 f& i0 z( A5 j: `) o153 t6 @! b9 b$ v, |0 i
16 / C% l8 U# q0 c" \* h/ l170 v( t$ l: H8 Q7 H% p
18 X4 f4 u S; C F2 t- a. f
199 I( c" f% C) {2 ?+ v( e1 _' O/ E
20 ; W1 K+ ?8 _: {4 w5 N% b! i; f21 3 F; W- K; \6 p7 j4 ]22 2 l+ t6 N5 H* U0 Z. v5 Q23 1 z) T Z3 C1 o- B6 a24 ; }" M5 [5 ^$ k9 e! I% }253 d7 z# i) W P0 l9 i( W1 ~( ~
26 1 P v& J- Q: _' X# i2 @: U27# |, u7 D) B) D/ }# `4 V- v! k- G: q
28: s# v2 K/ {: y; g O
29 + S: ]( t, o% T( P30% U2 S5 B. P! H2 M
31: s9 L: x0 [# q0 d/ j5 `
32: ~& i/ O5 _! V5 K9 e$ C
33 1 e2 b ?) A5 b+ u8 @34 # m; R- E# |1 o0 H* x& a5 V' p35& x) s* ~7 h3 [* x2 ~
36& W7 m- C8 l# U: e* z% R! U; [; X
37% o. F$ l4 \0 w; E7 h
38' u# R0 q$ e$ K5 S8 |
39 # L5 }! w; i2 t2 M40 0 B0 f: }7 t" w6 X41 2 U2 K f; t# ?3 K9 M& `42 9 A) {2 \, j* }7 @43/ e4 ] h; n8 _% W; n% g
44 " E& ?+ S) D. A/ V45 ( [. U3 i0 f: s% F46 - N- l- C1 Y y, a/ m3 w4 `# r0 N474 |+ _) Y7 A' g0 h
48 : z ?2 p$ _1 _0 E; E5 J) y- X49 . C3 s0 F: Q: M. q5 {) N506 F' Q* c, V" r1 |* J% V- K
517 [0 Q# \0 z. h$ {- n1 T, E
52 2 M7 K% V/ v6 p R& n9 t2 w+ ?8 t5 h53 4 @' B9 `3 f3 Q( ?7 ?; r9 R# g54 5 _( [1 V3 U& u4 g$ E8 z55+ `& f' q" r- ^6 W* C
56- ?* i+ ]) L# [2 H7 L: O$ p+ Y
57% x+ |# r% L" e( |8 s: v
58 * [# d) U; x3 N* s8 B6 l) X: ]7 E6 ?59 " P3 u5 `$ z! u' b. ~6 h" N60 # i& E1 Y$ J- `4 @7 D4 @- \61 ( }0 `" _4 }/ q; _6 U$ k/ T62 7 C9 B- ]; z0 }/ [( |63 , g' Y2 p% h0 a" j# s- h$ v3 i64 * K' v4 s' L, T& o65# U0 O# ?% H8 C% X: }3 @8 h, X
66" V% j4 D5 y F+ G3 n0 n' D) x. a
67 : I) V$ ]3 e/ M68 8 b& _/ A' N( @ [1 Q9 y69 2 [" x) X0 F, i70 - F/ y' p, K# B* J710 b) K( ~7 q; G7 p
723 M) t- Z8 O1 x5 ^. j
73" s9 G' U7 E" D0 x# V! P. D
74 . B2 ^8 r5 D. g& F75* d- u; N6 I% m! X# e: G
+ L. S* G5 s% C6 t) t* S) G5 N
; d0 `# `8 g! U8 M+ j8 G 2 N t$ K- P4 S0 f, p8 i2 N9 [可以看到,使用 turtle 库加上强大的数学几何知识,可以创作出非常好的看图像。更多内容可以参考 这个问题 3 u8 E9 H; N% C' v 4 o: z* F+ V: a5 o/ H. b7 ]5 t+ G使用 AI 作画8 A6 O1 [; o# x5 u7 I7 w
ERNIE-ViLG文生图 ) |) C- {' J* Z; e! u# D+ H使用以上方案绘制的内容,一般都比较刻板,缺少一些人文气息。少了一些人类才能有的特点。但是随着 AI 算力的提升和大数据的逐步发展,已经有很多可以使用 AI 进行作画的平台了。 比如 百度飞浆文心大模型 ERNIE-ViLG文生图 平台。& t/ _8 G r. C7 W$ }0 d( e
% s. ^& [0 E( zimport wenxin_api$ g$ u, o3 J. [ m n
from wenxin_api.tasks.text_to_image import TextToImage " H; j8 Z9 ^& X8 N( vimport secret + `9 b; G+ l; x4 V& z 7 N0 W. T: n) U/ }! g8 t9 E2 o" h9 y b9 a8 {- C/ w
def draw(t, s): + f5 B. v4 R; M& U wenxin_api.ak = secret.ak 8 o$ i: }2 o% }' R1 ]' C wenxin_api.sk = secret.sk- S2 A! H+ Z0 y, i: ^2 ?
input_dict = { : b( k4 }2 `0 r" Y "text": t,8 w8 T5 L8 m/ l
"style": s& l" t* X& t! g+ f/ T$ d
} 6 v9 w" o1 u. y% V rst = TextToImage.create(**input_dict)& J9 q4 A4 C' [2 W6 d/ [" Q
print(rst) 2 Y9 K8 R, z3 }& T 6 Q2 M0 j0 I* `% L0 {. X/ ]& a 2 C u2 `! Z' S: S; `if __name__ == '__main__': / d, k# O- v* G/ T text = "夏天"8 J% X5 V7 O# |2 g6 X
style = "油画" 7 J8 i* D8 O( h- ?; L4 ~1 `. @ draw(text, style)9 A/ ?: y8 Y0 U. Z6 I$ F n5 E
7 D7 |' h* q3 y# w/ E$ O
10 B- @$ ~# T$ }2 I* @' K
24 y4 i- U+ n+ c
37 h, q. ~, W9 ]# {
4* M$ }7 E2 t0 y: P
59 B) y4 R- }( ]4 U0 n/ b
6 5 x2 u* v8 o+ `7 x. ]7# f6 y& `. L- t1 _& L/ {/ E3 h
86 x$ @5 ~2 v% N4 y
9 8 s8 S; Z0 n! ?; T$ F10 - I1 Z4 ?1 z! x) ~! k11 7 F! b8 E6 ]6 c12 ( f" h f# B% G13. c* ~9 g: b! a
14% ?5 w8 x$ Y r" O- i6 l! B
15 6 V" }0 ^: v% H16 7 u0 v) |; B8 a4 N2 U" ?17# m% D4 N3 t( f9 t/ X3 Z
18 1 p5 t9 ^1 a! A- U$ Z19 ( |. r% H7 C* O1 a! u# K20* i) N; H( s* J& Y3 e8 u
使用上面的代码,就可以创作出 油画 风格的夏天,可以看看 AI 生成结果。1 R$ u4 d* a- g, m
- l! n7 z; V- P7 U9 F' p
2022-08-28 12:20:06,785 - model is painting now!, % {) Z1 K! p8 H+ E% S% a; Y; A( {# K( l4 d- taskId: 1062408, waiting: 30s 9 B1 L) o3 F% t+ ?/ A% Z3 h{'imgUrls': ['https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fex', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fi4', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828f5q', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828f30', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fv9', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fa2']}* O1 ]* Q4 g% d8 _
1 2 L" O5 d; Q0 B' U% s; |9 B2+ h- Y3 L2 d- t0 d
31 L" q0 G/ {6 f$ r T
可以看到速度还是很快的出不多一分钟就搞定了。可以预览一下结果8 I, z3 u4 f* L
. n) {4 L6 G7 O" }( @8 U
k, ]3 u- s- r7 ~4 Z ?' F+ t