파이썬에서 연예인 사칭 입문(문자예술)

18149 단어 pillowPython입문
개시하다
안녕하세요, 저는 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
    
  • add_text_to_이미지 함수의 호출원입니다.처음 위치부터 각 문자는 오른쪽에 문자를 그리고 한 줄 그리기를 마친 후 좌표 줄을 이동하여 그립니다.스케줄러: 갑자기 만들어서 별로인 것 같은데...
  • 일종의 완성 방식!!!
    이렇게 되면 처음에 전시된 가짜 예술이 완성된다.과제로 한 글자 한 글자 묘사한 결과 한 글자 x축 방향의 설정에 약간의 편차가 있어 원인을 찾고 있습니다(코드에 문제가 있는 부분을 지적해 주시면 기쁩니다!)
    끝맺다
    이 문장에서 나는pytohon으로 문자 예술을 했다.물론 다른 작품의 문자열로 제작할 수 있는 것 외에도 제목의 글자수에 맞게 배치하는 방법도 공들일 수 있으니 꼭 해보세요~

    좋은 웹페이지 즐겨찾기