파이썬에서 연예인 사칭 입문(문자예술)
안녕하세요, 저는 estie 기계 학습 엔지니어로 일하는 피만입니다.요즘 좀 떨어져서 체력이 완전히 떨어졌어요.이번 기고문은 본업과 상관없이 최근 취미로 제작된'가짜 예술'에 대해 보도한다.막힌 부분도 있으니 자세한 분들은 꼭 댓글을 달아주세요.
이번에 만든 거.
from PIL import Image, ImageDraw, ImageFont
import math
import numpy as np
미리 정의된 상수
만들고 싶은 그림의 크기와 사용할 글꼴을 자유롭게 설정하십시오.
CANVAS_HEIGHT = 2000
CANVAS_WIDTH = 2000
TTFONTNAME = "ヒラギノ明朝 ProN.ttc"
BACKGROUND_RGB = (255, 255, 255)
TEXT_RGB = (0, 0, 0)
TITLE_TEXT_RGB = (255, 0, 0)
제목과 본문의 문자열을 저장할 변수를 따로 준비하십시오.(이 글의 제목: title
, 본문: draw_str
의 변수로 저장합니다.)주 함수의 흐름
# 準備パート
## 1行あたりに描画する文字数を計算する
one_line_text_len = calculate_one_line_text_len(draw_str)
## 文字のフォントサイズを決定する
font_size = calculate_font_size(one_line_text_len)
# 描画パート
## 描画の初期位置の計算
position = calculate_text_position(font_size, one_line_text_len)
## 色を変える文字の位置を記録したarrayを用意する
color_array = prepare_color_array(title, one_line_text_len, position, font_size)
## 描画するImageオブジェクトを生成する
img = Image.new('RGB', (CANVAS_HEIGHT, CANVAS_WIDTH), BACKGROUND_RGB)
## 描画する
img = insert_texts(img, draw_str, font_size, position, one_line_text_len, color_array)
## 描画したものの保存
img.save("image.png")
함수별 설명def calculate_one_line_text_len(draw_str):
return math.ceil(math.sqrt(len(draw_str)))
def calculate_font_size(one_line_text_len):
return CANVAS_WIDTH // one_line_text_len
def calculate_text_position(font_size, one_line_text_len):
return (CANVAS_HEIGHT % (font_size * one_line_text_len)) / 2
def prepare_color_array(title, one_line_text_len, position, font_size):
# タイトルによって自分でサイズと位置を決める
title_str_size = int(font_size * one_line_text_len / 2)
position_1 = [position, position]
position_2 = [position + title_str_size , position + title_str_size]
positions = [position_1, position_2]
img = Image.new('RGB', (CANVAS_HEIGHT, CANVAS_WIDTH), BACKGROUND_RGB)
for s, p in zip(title, positions):
font = ImageFont.truetype(TTFONTNAME, title_str_size)
draw = ImageDraw.Draw(img)
draw.text(p, s, (0, 0, 0), font=font)
# 空のarrayを用意
color_array = np.full([one_line_text_len,one_line_text_len], False)
for row in range(one_line_text_len):
for col in range(one_line_text_len):
pos_x_start = int(position + font_size * row - 1)
pos_y_start = int(position + font_size * col)
obj_pixel = np.array(img)[pos_x_start:pos_x_start+font_size, pos_y_start:pos_y_start+font_size]
if obj_pixel.mean() <= 255/2:
color_array[row][col] = True
return color_array
좀 귀찮아요.
제목의 문자열 이미지를 생성하고 색 부분이 있는 좌표를 계산하여 표시된 aray로 되돌려줍니다.
겸사겸사 말씀드리겠습니다.
if obj_pixel.mean() <= 255/2:
color_array[row][col] = True
의 부분에서 본문 1개의 문자를 판정하는pixel의 집합의 RGB 값은 평균 255/2 이하, 즉'검은색'인지 아닌지를 판정한다.def add_text_to_image(img, text, font_size, width, height, color_flg):
position = (width, height)
font = ImageFont.truetype(TTFONTNAME, font_size)
draw = ImageDraw.Draw(img)
if color_flg:
draw.text(position, text, TITLE_TEXT_RGB, font=font)
else:
draw.text(position, text, TEXT_RGB, font=font)
return img
def insert_texts(image, text, font_size, position, one_line_text_len, color_array):
width = height = float(position)
row = 0
col = 0
charactor_count = 0
for character in text:
charactor_count += 1
# 1行に配置する文字数に達したら、widthを初期化、heightをfont_size分ずらす
if charactor_count % one_line_text_len == 0:
col = 0
width = position
row += 1
height += font_size
charactor_count = 0
img = add_text_to_image(image, character, font_size, width, height, color_array[row][col])
col += 1
width += (font_size)
return img
이렇게 되면 처음에 전시된 가짜 예술이 완성된다.과제로 한 글자 한 글자 묘사한 결과 한 글자 x축 방향의 설정에 약간의 편차가 있어 원인을 찾고 있습니다(코드에 문제가 있는 부분을 지적해 주시면 기쁩니다!)
끝맺다
이 문장에서 나는pytohon으로 문자 예술을 했다.물론 다른 작품의 문자열로 제작할 수 있는 것 외에도 제목의 글자수에 맞게 배치하는 방법도 공들일 수 있으니 꼭 해보세요~
Reference
이 문제에 관하여(파이썬에서 연예인 사칭 입문(문자예술)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pndnism/items/d9b7c09348377a598090텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)