Original, reproduced please indicate the source!
The first use of graphics to imitate the text for various angles of the inverted and arranged, later switched to text, there are many problems. Summarized as follows:
1, the program in the drawing and drawing text is not the same, the graphic is starting from the origin (0,0), and the text from the baseline beginning (0,baseline)
2, when increasing the angle offset, the text or graphics aspect will change (∠ 45 degrees to achieve maximum), this time in order to make them vertex alignment, need to calculate the offset (with trigonometric functions)
3. When drawing, the "canvas" (the description may not be accurate) is rotated before the text is drawn. Rotate back now, or the next graphic will continue to draw along this angle.
4, in order to keep the shape of the fixed width, for the angle of the text, it is necessary to narrow the average left and right (otherwise different angles, fixed number of words, will make the width of the graph different)
:
Source: (Code can be re-organized and optimized, but limited to the planned time, too lazy to get it)
Package Mainimport ("math" "reflect" "Time" "Math/rand" "Github.com/golang/freetype/truetype" "Github.com/fogleman/gg "//need to install this package" flag "" FMT "" Io/ioutil "" Log ") var wordslib = []interface{}{" Zhao "," Money "," Sun "," Li "," Zhou "," WU "," Zheng "," Feng "," Chen "," Chu "," Wei "," Jiang "," Shen "," Han "," Yang "," Zhu "," Qin "," especially "Xu", "Ho", "LV", "Shi", "Zhang", "Hole", "Cao", "Yan", "Hua", "Jin", "Wei", "Tao", "Ginger", "qi", "Xie", "Zou", "Yu", "Bai" , "Water", "Sinus", "chapter", "Cloud", "su", "Pan", "GE", "Xi", "fan", "Peng", "Lang", "Lu", "Wei", "Chang", "Ma", "Miao", "Feng", "Flower", "Fang", "Yu", "Ren", "Yuan", "Liu", "Feng", "Bao", "History", "Tang", " Fee "," Low "," cen "," Xue "," Lei "," he "," ni "," Soup "," teng "," Yin "," Luo "," bi "," Hao "," WU "," Ann "," Chang "," le "," Yu "," When "," Fu "," PI "," Bian Shenqiu "," Qi "," Kang "," WU "," Yu "," Yuan "," BU " , "gu", "Meng", "ping", "Huang", "and", "Mu", "Shaw", "Yin", "Yao", "Shao", "Zhan", "Wang", "Qi", "Mao", "Yu", "Di", "Rice", "bei", "Ming", "Zang", "Count", "V", "Cheng", "Dai", "Talk", "song", "Mao", " Pang "," Bear "," Ji "," Shu "," Qu "," item "," Wish "," Dong "," Liang "," du "," Ruan "," Blue "," min "," Mat "," season "," hemp "," strong "," Jia "," Lu "," Lou "," Danger "," Jiang "," Tong "," Yan "," Guo "," Mei "," Sheng "," Lin " , "Diao", "Zhong", "Xu", "Qiu", "Luo", "Gao", "Xia", "Cai", "Fan", "Hu", "Ling", "Huo", "Yu", "Million", "branch", "Ke", "Zan", "tube", "Lou", "Mo", "Jing", "Room", "Jo", "Barthelemy", "dry", "solution", "should", " Zong, "Ding", "Xuan", "Ben", "Deng", "Yu", "single", "Hang", "Hong", "Bao", "various", "left", "stone", "Cui", "Ji", "button", "Gong", "Cheng", "Kang", "Xing", "slip", "Pei", "Lu", "Rong", "Weng", "Xun", "sheep",", "Hui", "Zhen", "qu", "Home", "seal", "Rui", "Yi", "Storage", "Jin", "Ji", "Bing", "mi", "Pine", "Well", "Duan", "Fu", "WU", "WU", "Jiao", "ba", "Bow", "pastoral", "Wei", "Mountain", "valley", "car", "Hou", "mi", "Peng", "full", "Astrid", "class", "Yang", "Autumn", "Zhong", "Yi", "palace", "Ning", "Revenge", "Luan", "Violence", "Gan", "inclined", "Li", "Rong", "zu", "WU", "symbol", "Liu", "King", "Zhan", "bundle", "dragon", "leaf "," Fortunately "," division "," Shao "," Gao "," Li "," thistle "," thin "," Indian "," homestay "," white "," bosom "," Pu "," Tai "," from "," e "," Rope "," salty "," nationality "," Lai "," Zhuo "," Lin "," tu "," Meng "," Chi "," Joe "," Yin "," depression ", "Xu", "Can", "Cang", "double", "smell", "xin", "Party", "Zhai", "Tan", "Gong", "Lao", "sacrificed", "Ji", "Fu", "plugging", "ran", "Slaughter", "Li", "Yong", "but", "Quwan", "sang", "GUI", "Pu", "Niu", "Shou", "Tong", "side "," Hu "," Yan "," Ji "," Jia "," Pu "," Shang "," Nong "," Wen "," Don't "," Zhuang "," Yan "," Chai "," qu "," yen "," Charge "," Mu "," Lian "," Ru "," Xi "," Huan "," AI "," Fish "," Rong "," to "," ancient "," easy "," cautious ", "GE", "Liao", "Yu", "End", "Jinan", "Ju", "Heng", "step", "All", "Geng", "full", "Hong", "Marina", "Country", "Wen", "Kou", "Guang", "Lu", "que", "East", "ou", "shu", "Wo", "Li", "Wei", "Yue", "Kui", "long "," Division "," Gong "," she "," nie "," Chao "," tick "," AO "," Rong "," cold "," Zi "," xin "," Kanbao "," that "," Jane "," Rao "," Empty "," Zeng "," No "," Sha "," What "," raise "," Ju "," must "," abundance "," nest "," Guan "," Quine ", "Phase", "check", "after", "Jing", "Red", "Tour", "Aulympic", "right", "Lu", "Gai", "Yi", "Huan", "Gong", "Once", "Shang", "Guan", "Yang", "Man", "Wei", "King", "Fu", "WU", "Late", "Dan", "Taiwan", "Ye", "Government", "Chun "," Too "," Uncle "," Shen "," Xuan "," shafts "," order "," Fox "," Away "," Yu "," Long "," Fresh "," Lu "," Qiu "," acts "," Zhang "," du "," son "," Zhuan "," End "," Wood "," West "," lacquer "," carving "," positive "," soil "," Xiaosi "," good ", "Extension", "PostScript", "clamp"Father", "Jin", "Chu", "Yan", "fa", "Ru", "Yan", "tu", "Chin", "hundred", "Li", "South", "door", "call", "delay", "return", "Sea", "tongue", "micro", "Health", "Yue", "handsome", "bindings", "hypersplenism", "condition", "Hou Yi", "have", "Jean", "Quotient", "Mu", "Di she", "counted", "Bo", "reward", "Mo", "Ha", "Qiao", "Da", "Year", "Love", "Tong", "first", "Five", "Yan", "Fu", "surname"}var (DPI = flag. Float64 ("dpi", "page resolution in Dots Per Inch") Fontfile = flag. String ("Fontfile", "./simyou. TTF "," filename of the TTF font ") size = flag. Float64 ("size", +, "font size in points")) Func main () {x: = "abc" FMT. Println (X[0:3]) Drawimagebygg ()} func Drawimagebygg () {DC: = Gg. When Newcontext (+/-)//W*sin + h*sin (45) 45 degrees, the font reaches the maximum height of DC. Setrgba (1, 1, 1,0)//Set background color: The end is transparency 1-0 (1-Opaque 0-Transparent) DC. Clear () DC. Setrgba (0, 0, 0,1)//Set Font color fontbytes, err: = Ioutil. ReadFile (*fontfile) if err! = Nil {log. PRINTLN (ERR) return} font, err: = TrueType. Parse (fontbytes) if err! = Nil {log. PRINTLN (ERR) return}face: = TrueType. Newface (font, &truetype. Options{size: *size,dpi:*dpi,}) DC. Setfontface (face)//Initialize the variable used to calculate coordinates fm: = face.Metrics () Ascent: = FLOAT64 (FM. Ascent.round ())//The baseline of the font to the top distance decent: = FLOAT64 (FM. Descent.round ())//The distance to the bottom of the font is w: = FLOAT64 (FM. Height.round ())//characters, most of which should be equal width words, i.e., as high as H: = FLOAT64 (FM. Height.round ()) TotalWidth: = 0.0//Current cumulative image width (required to calculate font position)//random take Chinese character, position inverted word words: = getrandommembersfrommemberlibary ( wordslib,8)//Take 8 characters Reversewordsindex: = Getrandommembersfrommemberlibary ([]interface{}{0,1,2,3,4,5,6,7},2)// Random 2 inverted words for i,word: = range Words{degree: = If (Contain (I,reversewordsindex), Float64 (RandInt64 (150,210)), Float64 ( RandInt64 ( -30,30))//random angle, positive angle -30~30, inverted angle 150~210x,y,leftcutsize,rightcs: = Getcoordbyquadrantanddegree (W,h, Ascent,decent,degree,totalwidth) DC. Rotateabout (GG. Radians (degree), 0,0) DC. Drawstringanchored (Word. ( string), X, Y, 0,0) DC. Rotateabout ( -1*gg. Radians (degree), 0,0) TotalWidth = totalWidth + leftcutsize + rightcsfmt.println ("x:", X, "y:", Y, "total:", TotalWidth, " Degree: ", degree)}dc. Stroke () DC. Savepng ("Out.png") fmt. Println ("wrote out.png OK.")} Func Getcoordbyquadrantanddegree (w, H,ascent,descent,degree,befortotalwidth float64) (x,y,leftcutsize,rightcutsize float64) {var totalWidth Float64switch{case degree<=0 && degree >=-40://First Quadrant: counterclockwise-30 degrees ~ 0 <=> 330 ~ 360 (current parameter to pass in negative numbers) RD: =-1 * Degree//converted to positive integer for easy calculation leftcutsize = W*getdegreesin (90-rd) rightcutsize = h*getdegreesin (rd) Offset: = (leftcutsize + ri GHTCUTSIZE-W)/2///horizontal offset (the more angular tilt, the greater the width, the left and right margin allocated to it by the offset to narrow) Leftcutsize,rightcutsize = Leftcutsize-offset,rightcutsize -Offsettotalwidth = befortotalwidth + leftcutsize x = Getdegreesin (90-rd) *totalwidth-w y = ascent + getdegreesin (RD) * TotalWidth Case degree >=0 && degree <= 40://Fourth quadrant: clockwise 0 ~ 30 degrees Leftcutsize = H*getdegreesin (degree) RIGHTCU Tsize = W*getdegreesin (90-degree) Offset: = (leftcutsize + rightcutsize-w)/2leftcutsize,rightcutsize = leftcutsize-of Fset,rightcutsize-offsettotalwidth = befortotalwidth + leftcutsize//Now totalwidth = Front width + own left tangent x = Getdegreesin (90-de Gree) *totalwidthy = Ascent-getdegreesin (deGree) *totalwidth case degree >= && degree <= 220://second quadrant: Clockwise 180 ~ 210 Degrees RD: = Degree-180leftcutsize = H*getdegreesin (rd) rightcutsize = w*getdegreesin (90-rd) Offset: = (leftcutsize + rightcutsize-w)/2 Leftcutsize,rightcut Size = Leftcutsize-offset,rightcutsize-offsettotalwidth = befortotalwidth + leftcutsize x =-1 * (Getdegreesin (90-RD) * TotalWidth + W) y = getdegreesin (rd) *totalwidth-descentcase degree >= && degree <= 180://Third quadrant: Clockwise 15 0 ~ 180 Degrees RD: = 180-degreeleftcutsize = W*getdegreesin (90-rd) rightcutsize = h*getdegreesin (rd) Offset: = (leftcutsize + Right CUTSIZE-W)/2leftcutsize,rightcutsize = Leftcutsize-offset,rightcutsize-offsettotalwidth = BeforTotalWidth + leftCu Tsize x =-1 * (Getdegreesin (90-RD) * totalWidth) y = 1 * (Getdegreesin (RD) * totalWidth + descent) default:panic (FMT. Sprintf ("Illegal parameters:%f", degree))}return}func Getdegreesin (degree float64) Float64{return Math. Sin (Degree*math. pi/180)}//randint64 ... func RandInt64 (min, MAx Int64) Int64 {if min >= max | | min = = 0 | | max = = 0 {return Max}rand. Seed (time. Now (). Unixnano ()) return Rand. Int63n (max-min) + Min}func getrandommembersfrommemberlibary (lib []interface{},size int) []interface{}{source,result: = Make ([]interface{},0], make ([]interface{},0) if size <= 0 | | Len (lib) = = 0{return Result}for _,v: = Range Lib{source = append (source,v)}if size >= Len (lib) {return source}for i:=0;i <size;i++{rand. Seed (time. Now (). Unixnano ()) pos: = Rand. INTN (len (source)) result = Append (Result,source[pos]) Source = append (source[:p os], source[pos+1:] ...)} Return Result}//contain ... func contain (obj interface{}, Target interface{}) bool {targetvalue: = reflect. VALUEOF (target) switch reflect. TypeOf (target). Kind () {case reflect. Slice, reflect. Array:for I: = 0; I < Targetvalue.len (); i++ {if Targetvalue.index (i). Interface () = = obj {return true}} case reflect. Map:if Targetvalue.mapindex (reflect. Valueof (obj)). IsValid () {return true}} return false}//if ... func If (expr bool,trueval float64,falseval float6 4) float64{if Expr {return trueval}return Falseval}
Need a font file here to use the young round (young round free, other free fonts too lazy to find).
Note: Depending on the font, the width and height may need to be adjusted.