画像ファイルをアプリにドラッグすると、縦横で長い方のサイズを自動で500ピクセルにして別名で保存するアプリが完成しました!

こんばんは。蓬莱梨乃です♡

あ、これは、Python コンテンツとはちょっと毛色が違うので、「なりたい自分チャレンジ」のカテゴリーにしました。

GW 後半、午前中や午後の早い時間はほぼずーっと Python ばかりをやっておりました。

作成に約8時間。その後の修正 + 仕様追加に4時間程度かかりましたが、この時間で、「画像ファイルをアプリにドラッグすると、縦横で長い方のサイズを自動で500ピクセルにして別名で保存するアプリ」が完成しました☆

私には仕事や個人的な作業で何回も使う操作だったから、GW 中に自動化出来て嬉しいです!

Python を学ぶと、このように、自分だけのアプリが簡単に作成できます。

困難なことも沢山あり、原因がわかるまでにかなり時間がかかりましたが、やっぱり考え続けると、必ず答えは見つかるんだなと思いました。

どうやって作るのか。

詳しい作り方の説明はしませんが、考え方だけ残しておきます。

自動化アプリの作り方

自動化アプリを作る際には、まず、普通に操作する場合に何をすれば良いのかを書き出します。

今回のアプリの場合、実際にしなければならない操作は以下になります。

  1. 画像をペイントで開く。
  2. 「画像サイズを傾斜」ダイアログを開く
  3. 横(水平方向)と縦(垂直方向)の長さの情報を取得する。
  4. 単位を「ピクセル」に変更する。
  5. 取得した横と縦の長さを比較する。
  6. 長い方を500ピクセルにする。
  7. 「OK」ボタンを押す。
  8. 「ファイル」-「名前を付けて保存」で別名(元のファイル名の末尾に「-500」を付けた名前にしました)でファイルを保存する。

上記を 1 つ 1 つ実現していくような感じです。

画像ファイルをペイントで開くには・・・

ファイルを開くには
subprocess.Popen っていう関数があるのでそれを使うとか。
1 つ 1 つ調べて書いて動かして・・・というような地味な作業です。

追加仕様

それで一応 8 時間くらいでできた(と思った)のですが、その後、

「保存フォルダを指定した画像ファイルと同じ場所にしたい!

と思いました。

普通にペイントで別名で保存しようとすると、どこのファイルを開いたかにはかかわらず、前回保存した場所が開かれる仕様にペイントがなっているため、何もしないとそこに保存されるようになっています。

私は普段行う操作で考えると、元の画像ファイルがある場所に保存したいため、その場所に保存するにはそこまでパスを移動するか、保存場所を絶対パス(階層のトップから、ファイルの場所までのアドレス)で指定するなどをしなければなりません。

それをするには、

  1. ドラッグしたファイルのパスを取得しておく。
  2. パスをコピーしてクリップボード(コピーした時に一時的に記録される場所。ペーストでこの情報を貼り付けることができる)に貼り付けておく。
  3. 保存時にファイル名の頭にペーストして、絶対パスで保存する。

というプログラムの追加が必要になります。

不具合発生

追加の仕様も問題なく組み込むことができ、動作確認もいくつかのファイルで試してうまくいった!!と思っていたのですが、なんと!不具合がありました!!
画像の縦横の長い方を 500 ピクセルにするアプリなのですが、
一部のファイルで短いほうが 500 ピクセルになってしまいました。

例えば、横 1000 ピクセル、縦 750 ピクセルだった場合、横の 1000 ピクセルを 500 ピクセルにしたいのに、そうなりませんでした。縦 750 ピクセルのほうが 500 ピクセルになってしまいました。

横 900 ピクセル、縦 750 ピクセルのファイルと、横 300 ピクセル、縦 750 ピクセルのファイルで確認してうまくいったので OK だと思っていたのですが、とんでもない罠があったのです!!
(きっとプログラミングが得意な方はこの情報だけでも何となく結末の予想がついたと思いますが。。。)

横と縦の長さですが、画像ファイルをペイントで開いて、「画像サイズを傾斜」ダイアログの水平方向と垂直方向に入力されているサイズをコピーして取得し、その値をどちらが大きいか比較します。

水平方向のほうが大きい場合、水平方向の値を 500 ピクセルに変更する。そうでない場合(水平方向の値と垂直方向の値が同じ場合も含む)、垂直方向を 500 ピクセルに変更するというプログラムを書いていました。

しかし、取得した値は、数値ではなく、文字列として扱われていました!!

少し詳しく説明しますと、
数値として扱われている 1000 と 750 でしたら 1000 が大きいと判断されるのですが、文字列扱いで比較されると、まず先頭の値から五十音順、アルファベット順、数字順などで比較されるため、1000 の先頭の 1 よりも、後に登場する 750 の先頭の 7 のほうが大きいとされていたのです。

最初に確認した 2 つの画像ファイル、横 900 ピクセル、縦 750 ピクセルのファイルの組み合わせと、横 300 ピクセル、縦 750 ピクセルのファイルの組み合わせでは、その誤った比較でも偶然同じ結果が出ていただけだったのです。

まぁ、幸いそれに気づきやすい仕事をしている関係で、Python やプログラミングには詳しくないわりには、早く気付けて良かったです。

これこそが、ソフトウェアのバグを見つけるための「テストパターンが足りていない」という例だなと思いました。

【備忘録】
文字列を数値に変換するには
int(変換したい文字列)
を使用します。

できたアプリを実際に動かした動画を公開します。(最初マウスがうろうろしてますが(笑))

今後の課題

今後のために課題をまとめておきます。

  • 値を取得するのに、クリップボードを多用してしまったが、クリップボードを使う以外の方法はなかったものなのか(出来れば Windows の機能に頼るのではなく、Python の機能で閉じるような作り方をしたいため)

  • pyautogui (キーボード操作ができるモジュール) を使用して Ctrl キーとの組み合わせのショートカット(例:Ctri + w )を自動で動かすと、操作が終わっても Ctrl キーがずっと押された状態になってしまっていた (もう一度 Ctrl を押すまで解消されない)。これは Python の仕様なのか、バグなのか、よくわからなかったので、再度 Ctrl キーを押す操作を組み込むことで回避した。

  • win32gui のインストールがなぜかうまくいかず、別の方法を使用したが、原因がわからないまま。

  • クラス定義が複雑過ぎてよくわからず、どうしてもそこで作った変数に入れた値が他に持っていけなかったので、その中に無理矢理詰めこんだ。理解を待っていたらアプリが GW 中に完成しなさそうだったので、後日理解すれば良いとした。

こんな感じで、時間はかかったけれど、学ぶことは多かったです。

これからも便利アプリを作成していきます。

長文読んでいただきありがとうございました☆

蓬莱梨乃でした♡

Follow me!