比較検索なら 天秤AI byGMO
ブラックボックス化させないくん

ブラックボックス化させないくん

プログラムのコードを投げればコメントアウトで分かりやすくしてくれます。 さらなる自動化も提案してくれます。

1
0
12
0
user_197214048179726336
がお気に入り登録しました。

投稿日時:

  • プロンプト実行例
  • プロンプトを見る
ブラックボックス化させないくん

ブラックボックス化させません。

#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
ブラックボックス化させないくん

以下に、コードの各部分にコメントアウトを追加しました。また、自動化の提案も行っています。

Python
1#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

他のプロンプトもチェック