質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

642閲覧

Pythonで画像のリサイズとテキストの挿入を行うプログラム

Yuichiro_Honda

総合スコア6

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/07/26 04:41

前提・実現したいこと

Pythonで
『指定した画像に対し、リサイズとテキストの挿入を行う』
プログラムを作成しようとおります。

そのプログラムの実行中に以下のエラーが発生してしまい、画像が作成されません。

発生している問題・エラーメッセージ

C:\Users\OI\Desktop\Python>python prog.py Traceback (most recent call last): File "prog.py", line 125, in <module> main() File "prog.py", line 109, in main for row in reader: File "C:\Users\OI\AppData\Local\Programs\Python\Python37\lib\csv.py", line 111, in __next__ self.fieldnames File "C:\Users\OI\AppData\Local\Programs\Python\Python37\lib\csv.py", line 98, in fieldnames self._fieldnames = next(self.reader) UnicodeDecodeError: 'shift_jis' codec can't decode byte 0xef in position 0: illegal multibyte sequence

該当のソースコード

import csv import matplotlib.pyplot as plt import numpy as np import os from PIL import Image, ImageDraw, ImageFont SETTING_CSV = "setting.csv" INPUT_DATA_DIR = "./input" OUTPUT_DATA_DIR = "./output" IMG_Q = 90 IMG_SIZE = (780, 428) TEXT_SIXE = (750, 200) TEXT_MARGIN = 30 MAX_FONT_SIZE = 100 FONT_PATH = "./fonts/migmix-1p-bold.ttf" TEXT_COLORS = (('black', '#000000', (255, 255, 255, 192)), ('white', '#FFFFFF', (0, 0, 0, 192))) def make_eye_catch(img_path, text): # 画像のファイル名を取得 file_name, ext = os.path.splitext(img_path) # \n(改行指定)でテキストを分割 text = text.split(r"\n") # 先に文字の描画領域決定。合わせて下記を計算しておく # フォントサイズfont_size, 描画幅area_width, 描画高さarea_height, lines_size for font_size in range(MAX_FONT_SIZE, 9, -1): # フォント font = ImageFont.truetype(FONT_PATH, font_size) # 各行の[幅、高さ]を計算 lines_size = [list(font.getsize(t)) for t in text] # 幅の最大と高さの合計 area_x = np.max(lines_size, 0)[0] area_y = np.sum(lines_size, 0)[1] if(area_x <= TEXT_SIXE[0] and area_y <= TEXT_SIXE[1]): break # 画像読み込み、サイズ取得 img = Image.open(os.path.join(INPUT_DATA_DIR, img_path)) original_img_size = img.size # 縮小 if (original_img_size[0] / original_img_size[1]) \ >= (IMG_SIZE[0] / IMG_SIZE[1]): # 目標より横長なら、縦横比を維持して、縦を目標まで縮める img.thumbnail((original_img_size[0], IMG_SIZE[1])) thumbnail_size = img.size # 横幅を切り取るための計算をする crop_left = int((thumbnail_size[0] - IMG_SIZE[0]) / 2) crop_upper = 0 crop_right = crop_left + IMG_SIZE[0] crop_lower = IMG_SIZE[1] else: # 目標より縦長なら、縦横比を維持して、横を目標まで縮める img.thumbnail((IMG_SIZE[0], original_img_size[1])) thumbnail_size = img.size # 縦幅を切り取るための計算をする crop_left = 0 crop_upper = int((thumbnail_size[1] - IMG_SIZE[1]) / 2) crop_right = IMG_SIZE[0] crop_lower = crop_upper + IMG_SIZE[1] # 計算した縦横で切り取る img = img.crop((crop_left, crop_upper, crop_right, crop_lower)) # 背景の塗りつぶしと文字書き込み準備 rectangle_y = area_y + TEXT_MARGIN rectangle_top = int((IMG_SIZE[1]-rectangle_y)/2) # 白黒2色分画像を作成 for (label, fg_color, bg_color) in TEXT_COLORS: # 塗りつぶし領域作成 rectangle_img = Image.new('RGBA', img.size) draw = ImageDraw.Draw(rectangle_img) draw.rectangle((0, rectangle_top, IMG_SIZE[0], rectangle_top+rectangle_y), bg_color) # 塗りつぶし org_img = img.convert('RGBA') new_img = Image.alpha_composite(org_img, rectangle_img) draw = ImageDraw.Draw(new_img) _y = int((IMG_SIZE[1]-area_y)/2) for (t, line) in zip(text, lines_size): _x = int((IMG_SIZE[0]-line[0])/2) draw.text((_x, _y), t, font=font, fill=fg_color) _y += line[1] new_img = new_img.convert("RGB") res_file_name = file_name + "_" + label + ".jpg" new_img.save(os.path.join(OUTPUT_DATA_DIR, res_file_name), quality=IMG_Q) plt.figure() plt.imshow(new_img) def main(): input_data_list = [] # csvファイルの文字コードがSJISの時はencoding="shift_jis"を指定する with open(SETTING_CSV, "r", encoding="shift-jis") as csv_file: reader = csv.DictReader(csv_file) for row in reader: input_data_list.append([row["path"], row["sentence"]]) # もしoutputフォルダが無かったら作る if not os.path.exists(OUTPUT_DATA_DIR): os.makedirs(OUTPUT_DATA_DIR) # アイキャッチ画像の生成 for img_path, text in input_data_list: make_eye_catch(img_path, text) info_msg = "[INFO] {0}の処理が完了しました" print(info_msg.format(os.path.join(INPUT_DATA_DIR, img_path))) print("[INFO] Finish!!") if __name__ == "__main__": main()

※画像の名前・挿入したい文字列を指定したsetting.csvというファイルを利用しておりますが、そちらには問題はないと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

エラーが発生しているのはソースのこの場所で、ここは setting.csv を読み込んでいる場所です。

File "prog.py", line 125, in <module> main() File "prog.py", line 109, in main for row in reader:

shift-jis とは思えない値が入っていたよ。

UnicodeDecodeError: 'shift_jis' codec can't decode byte 0xef in position 0: illegal multibyte sequence

というエラーが出ています。
0バイト目が 0xEF であることが原因とありますが、ファイルの先頭が0xEFになっているということは、BOM付きのUTF-8の可能性が高いです。

ということで、問題無いとおっしゃっていますが、setting.csvのエンコーディングがshift-jisでないことが問題だろうと思います。

  1. setting.csvのエンコーディングをshift-jisに変更する。
  2. 読み込むときのエンコーディングの指定を shift-jis でなく、utf-8-sig に変更する。

あたりで解決するのではないかと思います。

投稿2019/07/26 06:05

TakaiY

総合スコア12745

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問