「筆畫」是指漢字書寫時,不間斷地一次連續寫成的一條線條。筆畫是漢字的最小構成單位。
Max 要來挑戰的是判斷某一個交叉點,是二筆畫,還是同一筆畫。同一筆和不同筆,在之後文字效果的處理會不同,同一筆畫會變形,與第二筆畫的交叉不應該變形。
這次寫完的程式,過二天再回來看,就像完全沒看過的程式一樣陌生,完全不知道當初在寫什麼!數學的世界,常常讓人無法理解,太難了。Q_Q;
程式碼的Code Review 參考下面的 YouTube 影片:
https://youtu.be/TXNyNkWpde0
舉例:判斷「丸」的「十」交叉不是同一筆畫,右上角長出來的尾巴是同一筆畫。
在判斷筆畫時還是第二筆。水平線和垂直線的判斷相對容易很多,比較難的是「乂」叉叉系列的判斷,例如:「女」,的轉角是同一筆畫。
產出的副程式:
def join_line_check(self,x0,y0,x1,y1,x2,y2): inside_stroke_flag = False previous_extend_x,previous_extend_y = spline_util.two_point_extend(x0,y0,x1,y1, self.config.STROKE_WIDTH_AVERAGE) previous_extend_x_offset = x1-previous_extend_x previous_extend_y_offset = y1-previous_extend_y previous_left_x,previous_left_y = spline_util.two_point_extend(x0,y0,x1,y1, int(2.0 *self.config.STROKE_WIDTH_AVERAGE)) tmp_next_extend_x,tmp_next_extend_y=spline_util.two_point_extend(x2,y2,x1,y1, self.config.STROKE_WIDTH_AVERAGE) next_extend_x = tmp_next_extend_x - previous_extend_x_offset next_extend_y = tmp_next_extend_y - previous_extend_y_offset next_left_x = next_extend_x - previous_extend_x_offset next_left_y = tmp_next_extend_y - previous_extend_y_offset -previous_extend_y_offset bmp_x1, bmp_y1, bmp_x2, bmp_y2, bmp_x3, bmp_y3, bmp_x4, bmp_y4 = previous_extend_x, previous_extend_y, previous_left_x, previous_left_y, next_left_x, next_left_y, next_extend_x, next_extend_y inside_stroke_flag = self.is_inside_stroke(bmp_x1, bmp_y1, bmp_x2, bmp_y2, bmp_x3, bmp_y3, bmp_x4, bmp_y4) return inside_stroke_flag
前一篇文章:
二點之間內縮後坐標
https://max-everyday.com/2020/04/two-point-extend/
上面的方法,似乎太容易誤判,改良為下面作法:
def join_line_check(self,x0,y0,x1,y1,x2,y2): inside_stroke_flag = False stroke_width = self.get_stroke_width(x0,y0,x1,y1) previous_extend_x,previous_extend_y = spline_util.two_point_extend(x0,y0,x1,y1, int(stroke_width * 1.2)) next_extend_x,next_extend_y=spline_util.two_point_extend(x2,y2,x1,y1, int(stroke_width/2)) next_extend_x_offset = x1-next_extend_x next_extend_y_offset = y1-next_extend_y test_x = previous_extend_x - next_extend_x_offset test_y = previous_extend_y - next_extend_y_offset bmp_x = self.ff_x_to_bmp_x(test_x) bmp_y = self.ff_y_to_bmp_y(test_y) data=self.bmp_image.getpixel((bmp_x, bmp_y)) if data <=128: inside_stroke_flag = True return inside_stroke_flag
上面共用筆寬的作做,還是踩到雷了,在下面的情況會誤判,應該不做事情,實際結果卻是加了圓角:
解法很簡單,先取得上方的筆寬(實際值是41單位),再取得左邊筆寬(實際值是74單位,跨過左邊紫色區塊後,檢查左上角有無黑線。
輪出的除錯訊息如下:
test coordinate: 731 456 - 535 456 - 535 408 stroke_width_lower: 74 stroke_width_upper: 41 test_x,y: 461 480 test_x,y: 460 480 test_x,y: 459 480 test_x,y: 458 480 test_x,y: 457 480 test_x,y: 456 480 test_x,y: 455 480 test_x,y: 454 480 test_x,y: 453 480 test_x,y: 452 480 test_x,y: 451 480 test_x,y: 450 480 test_x,y: 449 480 test_x,y: 448 480
說明:要檢查 [731,456] , [535,456] , [535,408] 這個角,是交叉線還是角落。依序取得線條寬度後,在左上角做測試。測試結果:是交叉線。