ブラックボックス化させないくん
プログラムのコードを投げればコメントアウトで分かりやすくしてくれます。 さらなる自動化も提案してくれます。
投稿日時:
- プロンプト実行例
- プロンプトを見る
ブラックボックス化させません。
#coding:utf-8
#画像切り出しスクリプト
#@Ryo Sasaki (zonepotage) #@Seiya Shibata (sorap)
#画像を良しなに切り出すやつ #Usage: py cutImage.py [inputImagePath / ImageDirectoryPath]
#Target Python Env : 3.6 #Rev : 2018/09/14 15:48
#coding:utf-8 from PIL import Image, ImageFilter import sys import os #import math import glob import datetime
Image.MAX_IMAGE_PIXELS = 1000000000
#config (mm)
CUT_SIZE_X = 420 CUT_SIZE_Y = 297 RAP_MARGIN = 30 JPEG_QUALITY = 80
logfileName = "execLog_{0:%Y%m%d_%H%M%S}.txt".format(datetime.datetime.now())
#動作保障外関数↓ def calcCutArea(x,y,dpi):
1#mmからpxを計算 2cutSizeX = round(CUT_SIZE_X/25.4 * dpi) 3cutSizeY = round(CUT_SIZE_Y/25.4 * dpi) 4rapMargin = round(RAP_MARGIN/25.4 * dpi) 5 6if x < y: 7 cutSizeX, cutSizeY = cutSizeY, cutSizeX 8 9 10#床処理(切り上げ) 11pageX = int((x + cutSizeX - 1)/cutSizeX) 12try: 13 if rapMargin > ((pageX * cutSizeX - x) / (pageX - 1)) : 14 pageX += 1 15except: 16 pass 17 18#床処理(切り上げ) 19pageY = int((y + cutSizeY - 1)/cutSizeY) 20try: 21 if rapMargin > ((pageY * cutSizeY - y) / (pageY - 1)) : 22 pageY += 1 23except: 24 pass 25 26 27''' 28#分割ページ数を算出(切り上げ) 29pageX = x//cutSizeX 30pageY = y//cutSizeY 31''' 32#分割ページ数からラップ分を算出 33if pageX == 1: 34 rapX = 0 35else: 36 rapX = (cutSizeX*pageX-x)/(pageX-1) 37 38if pageY == 1: 39 rapY = 0 40else: 41 rapY = (cutSizeY*pageY-y)/(pageY-1) 42 43#切り出し位置(左上座標)を算出 44#結果を [[1枚目x,y],[2枚目x,y].... のように 45leftTopCode = [0,0] 46cropRequest = [] 47 48for ii in range(pageY): 49 if ii==0: 50 leftTopCode[1] = 0 51 else: 52 leftTopCode[1] = round(ii*cutSizeY-rapY*ii) 53 54 for i in range(pageX) : 55 if i==0: 56 leftTopCode[0] = 0 57 else: 58 leftTopCode[0] = round(i*cutSizeX-rapX*i) 59 60 cropRequest.append(leftTopCode.copy()) 61 62#辺長が切り出しサイズより小さい場合は辺長を切り出しサイズに 63if cutSizeX > x: 64 cutSizeX = x 65if cutSizeY > y: 66 cutSizeY = y 67 68 69#出力画像サイズと切り出し位置を返す 70 71return [cutSizeX,cutSizeY],cropRequest
def getImageData(image): result = {} result["height"] = image.size[1] result["width"] = image.size[0] result["format"] = image.format result["colorMode"] = image.mode if image.info["dpi"]: result["dpi"] = image.info["dpi"] return result
def logging(level,message): with open(logfileName, 'a') as fh: print('[{}] {}'.format(level,message),file = fh) return
def cutImage(image,mode,startX,startY,endX,endY): """ 指定サイズで画像を切り出す @param image Imageオブジェクト @param mode 座標指定モード (relatively:相対指定, absolutely:絶対指定) @param startX 切り出し開始X座標 @param startY 切り出し開始Y座標 @param endX 切り出し終了X座標 @param endY 切り出し終了X座標
1@return 切り出し後Image) 2""" 3 4if mode == "relatively": 5 endX += startX 6 endY += startY 7elif mode == "absolutely": 8 endX += 1 9 endY += 1 10else: 11 return None 12if 0<= startX and 0<= startY and endX <= image.size[0]+1 and endY <= image.size[1]+1 and startX < endX and startY < endY: 13 return image.crop((startX, startY, endX, endY)) 14else: 15 return None
if name == 'main':
1arguments = sys.argv 2try: 3 arguments[1] 4except: 5 print('Arguments too short.') 6 7 8#argTest = "Z:\py_cut\A1\A1_001a.jpg" 9 10try: 11 12 fileList = [] 13 14 if os.path.isfile(arguments[1]): 15 16 logfileName = os.path.dirname(arguments[1]) + "/" + logfileName 17 fileList.append(arguments[1]) 18 else: 19 logfileName = arguments[1] + logfileName 20 fileList.extend(glob.glob(arguments[1] + '/*.jpg')) 21 fileList.extend(glob.glob(arguments[1] + '/*.jpeg')) 22 fileList.extend(glob.glob(arguments[1] + '/*.tif')) 23 fileList.extend(glob.glob(arguments[1] + '/*.tiff')) 24 #fileList.extend(list(map(lambda x: arguments[1] + "/" + x, glob.glob(arguments[1] + '/*.jpeg')))) 25 #fileList.extend(list(map(lambda x: arguments[1] + "/" + x, glob.glob(arguments[1] + '/*.tif')))) 26 #fileList.extend(list(map(lambda x: arguments[1] + "/" + x, glob.glob(arguments[1] + '/*.tiff')))) 27 28 29 #fileList.append("Z:\py_cut\master2.jpg") 30 for processFile in fileList: 31 32 image = Image.open(processFile) 33 info = getImageData(image) 34 35 print("Format:" + info["format"],"Width:" + str(info["width"]) ,"Height:" + str(info["height"]),sep=" / ", end = "") 36 37 if image.info['dpi']: 38 print(" / Dpi:" ,info["dpi"]) 39 else: 40 raise Exception("処理対象となる画像ファイルにDPI属性が存在しません。(" + processFile + ")") 41 result = calcCutArea(info["width"],info["height"],info["dpi"][0]) 42 43 count = 0 44 for item in result[1]: 45 count = count + 1 46 print(os.path.splitext(processFile)[0] + "_" +str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1] + "...",end = "") 47 try: 48 if info["format"] == "JPEG": 49 cutImage(image,"relatively",item[0], item[1], result[0][0] , result[0][1]).save(os.path.splitext(processFile)[0] + "_" +str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1] , quality=JPEG_QUALITY, dpi=info["dpi"]) 50 elif info["format"] == "TIFF": 51 cutImage(image,"relatively",item[0], item[1], result[0][0] , result[0][1]).save(os.path.splitext(processFile)[0] + "_" +str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1] , quality="group4", dpi=info["dpi"]) 52 print("OK") 53 except: 54 raise Exception("何かしら問題が発生しました。(" + + processFile + ")") 55except Exception: 56 logging("ERROR",Exception) 57 58print("Fin.") 59 60os.system("pause > nul") 61 62 63
以下に、コードの各部分にコメントアウトを追加しました。また、自動化の提案も行っています。
Python1#coding:utf-8 2 3##### 4# 画像切り出しスクリプト 5# @Ryo Sasaki (zonepotage) 6# @Seiya Shibata (sorap) 7# 画像を良しなに切り出すやつ 8# Usage: py cutImage.py [inputImagePath / ImageDirectoryPath] 9# Target Python Env : 3.6 10# Rev : 2018/09/14 15:48 11 12#coding:utf-8 13from PIL import Image, ImageFilter # 画像処理用ライブラリ 14import sys # システムパラメータ用ライブラリ 15import os # オペレーティングシステムとのインターフェースライブラリ 16import glob # ファイル名のパターンマッチング用ライブラリ 17import datetime # 日時処理用ライブラリ 18 19Image.MAX_IMAGE_PIXELS = 1000000000 # 最大画像ピクセル設定 20 21# 設定(mm単位) 22CUT_SIZE_X = 420 # 切り出し幅 23CUT_SIZE_Y = 297 # 切り出し高さ 24RAP_MARGIN = 30 # ラップ余白 25JPEG_QUALITY = 80 # JPEG品質設定 26 27# ログファイル名作成 28logfileName = "execLog_{0:%Y%m%d_%H%M%S}.txt".format(datetime.datetime.now()) 29 30# 動作保障外関数↓ 31def calcCutArea(x,y,dpi): 32 # mmからpxを計算 33 cutSizeX = round(CUT_SIZE_X/25.4 * dpi) # 切り出し幅 34 cutSizeY = round(CUT_SIZE_Y/25.4 * dpi) # 切り出し高さ 35 rapMargin = round(RAP_MARGIN/25.4 * dpi) # ラップ余白をpxに変換 36 37 # 対象画像のサイズによって縦横を入れ替え 38 if x < y: 39 cutSizeX, cutSizeY = cutSizeY, cutSizeX 40 41 # 切り出しページ数を計算 42 pageX = int((x + cutSizeX - 1)/cutSizeX) # 横方向のページ数 43 try: 44 if rapMargin > ((pageX * cutSizeX - x) / (pageX - 1)) : 45 pageX += 1 # ラップ余白を考慮してページ数+1 46 except: 47 pass 48 49 pageY = int((y + cutSizeY - 1)/cutSizeY) # 縦方向のページ数 50 try: 51 if rapMargin > ((pageY * cutSizeY - y) / (pageY - 1)) : 52 pageY += 1 # ラップ余白を考慮してページ数+1 53 except: 54 pass 55 56 # 分割ページ数からラップ分を算出 57 rapX = (cutSizeX*pageX-x)/(pageX-1) if pageX > 1 else 0 58 rapY = (cutSizeY*pageY-y)/(pageY-1) if pageY > 1 else 0 59 60 # 切り出し位置(左上座標)を算出 61 leftTopCode = [0,0] 62 cropRequest = [] 63 64 # 切り出し占有位置を計算 65 for ii in range(pageY): 66 leftTopCode[1] = round(ii*cutSizeY-rapY*ii) if ii else 0 67 for i in range(pageX): 68 leftTopCode[0] = round(i*cutSizeX-rapX*i) if i else 0 69 cropRequest.append(leftTopCode.copy()) 70 71 # 出力画像サイズと切り出し位置を返す 72 return [cutSizeX if cutSizeX <= x else x, cutSizeY if cutSizeY <= y else y], cropRequest 73 74def getImageData(image): 75 # 画像データを辞書形式で取得 76 result = {} 77 result["height"] = image.size[1] # 画像の高さ 78 result["width"] = image.size[0] # 画像の幅 79 result["format"] = image.format # 画像フォーマット 80 result["colorMode"] = image.mode # カラーモード 81 result["dpi"] = image.info.get("dpi") # DPI情報 82 return result 83 84def logging(level,message): 85 # ログファイルにエラーメッセージを書き込む 86 with open(logfileName, 'a') as fh: 87 print('[{}] {}'.format(level,message), file=fh) 88 89def cutImage(image,mode,startX,startY,endX,endY): 90 """ 91 指定サイズで画像を切り出す 92 @param image: Imageオブジェクト 93 @param mode: 座標指定モード (relatively:相対指定, absolutely:絶対指定) 94 @param startX: 切り出し開始X座標 95 @param startY: 切り出し開始Y座標 96 @param endX: 切り出し終了X座標 97 @param endY: 切り出し終了Y座標 98 @return: 切り出し後のImage 99 """ 100 if mode == "relatively": 101 endX += startX 102 endY += startY 103 elif mode == "absolutely": 104 endX += 1 105 endY += 1 106 else: 107 return None 108 109 # 切り出し範囲が正しいか確認 110 if 0 <= startX < endX <= image.size[0] + 1 and 0 <= startY < endY <= image.size[1] + 1: 111 return image.crop((startX, startY, endX, endY)) 112 else: 113 return None 114 115if __name__ == '__main__': 116 # コマンドライン引数取得 117 arguments = sys.argv 118 try: 119 arguments[1] 120 except IndexError: 121 print('Arguments too short.') 122 123 try: 124 fileList = [] 125 if os.path.isfile(arguments[1]): 126 logfileName = os.path.dirname(arguments[1]) + "/" + logfileName 127 fileList.append(arguments[1]) 128 else: 129 logfileName = arguments[1] + logfileName 130 # 指定ディレクトリ内の画像ファイルを取得 131 fileList.extend(glob.glob(arguments[1] + '/*.jpg')) 132 fileList.extend(glob.glob(arguments[1] + '/*.jpeg')) 133 fileList.extend(glob.glob(arguments[1] + '/*.tif')) 134 fileList.extend(glob.glob(arguments[1] + '/*.tiff')) 135 136 for processFile in fileList: 137 image = Image.open(processFile) # 画像を開く 138 info = getImageData(image) # 画像の情報を取得 139 140 # 画像情報を出力 141 print("Format:" + info["format"], "Width:" + str(info["width"]), "Height:" + str(info["height"]), sep=" / ", end="") 142 if image.info['dpi']: 143 print(" / Dpi:", info["dpi"]) 144 else: 145 raise Exception("処理対象となる画像ファイルにDPI属性が存在しません。(" + processFile + ")") 146 147 # 切り出し範囲を計算 148 result = calcCutArea(info["width"], info["height"], info["dpi"][0]) 149 count = 0 150 for item in result[1]: 151 count += 1 152 print(os.path.splitext(processFile)[0] + "_" + str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1] + "...", end="") 153 try: 154 # 切り出し処理 155 if info["format"] == "JPEG": 156 cutImage(image, "relatively", item[0], item[1], result[0][0], result[0][1]).save( 157 os.path.splitext(processFile)[0] + "_" + str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1], 158 quality=JPEG_QUALITY, 159 dpi=info["dpi"] 160 ) 161 elif info["format"] == "TIFF": 162 cutImage(image, "relatively", item[0], item[1], result[0][0], result[0][1]).save( 163 os.path.splitext(processFile)[0] + "_" + str(count) + "/" + str(len(result[1])) + os.path.splitext(processFile)[1], 164 quality="group4", 165 dpi=info["dpi"] 166 ) 167 print("OK") 168 except Exception as e: 169 raise Exception("何かしら問題が発生しました。(" + processFile + ") " + str(e)) 170 except Exception as e: 171 logging("ERROR", str(e)) 172 173 print("Fin.") 174 175 os.system("pause > nul") 176 177# さらなる自動化の提案: 178# 1. コマンドライン引数をGUI化することで、ユーザビリティを向上させる。 179# 2. 複数形式の画像に対応するための設定を追加し、拡張性を持たせる。 180# 3. 日次・週次で自動実行されるスケジュール機能を追加し、定期的な処理を行えるようにする。 181# 4. エラーログをデータベースに記録し、後で分析できるようにする。
このスクリプトは画像を切り出すためのもので、引数として指定された画像ファイルまたはディレクトリ内の画像を処理します。エラーハンドリングがあり、全ての処理はログとして記録されます。
提案した自動化内容を導入することにより、作業の効率化やトラブルシューティングが容易になるでしょう。
コメント 0
他のプロンプトもチェック
SNS広告
▼最新作はこちら▼ https://oshiete.ai/item_lists/73557973863457792 Xやインスタリール、YouTubeショート、TikTok全てに使えるショート動画作成ツールです。 ショート動画戦国時代をAIとともに乗り越えましょう!! 興味をひける短い動画の自動作成が可能になります。13321.18K4.79KGPTs
計画立案
スマホ用Chat GPTアプリでGPTsを読み込んで、片付けたい場所の写真を撮ってください。画像解析して部屋を綺麗に片付けるステップと効率的な片付けアドバイスをくれます。片付けが苦手なあなたに対応した励まし機能つき。3076351