KHCの

KHC( https://twitter.com/we_can_panic )が140字を超えるツイートをするところ

何枚ものスクショからアクティブなウィンドウを切り出す(誇張)

↑これ仲間のタヌキに聞いたので信憑性は高いと思います。

 
 

なんか俺は知らんかったけど、Windowsのスクショって連続で撮れるらしい。
Alt+PrintScreenで「ピクチャ>スクリーンショット」っていうフォルダの中に画像が自動的に溜まっていくらしい。 みんな知ってた?知らんよね(見下し)。
あとWin+PrintScreenでいちばん手前のウィンドウだけスクショできるらしい。 すごe。
でも別にWin+Alt+PrintScreenで、特定のウィンドウだけ連続でパシャる(死語)ってのはできんらしい。フ~ン。。。  
 

↑を作っていきます

2時間くらいかかった。これ書くのは1時間くらい。
Pythonのバージョンは3.7で、ライブラリはconda installで入れた最新のやつです(2020/7/26現在)

作りました

"""
1. Alt+PrintScreenで、撮りたいウィンドウをクリップボードにコピー
2. Win+PrintScreenで画面全体を撮る
3. 1.で撮ったスクショを、「スクリーンショット」下に「master.png」という名前で保存
3. あとはWin+PrintScreenでスクショを保存していく
4. このプログラムを動かす。outputというフォルダができてそこに切り抜かれた保存される
"""

import os, re, time
import cv2
import tqdm
import numpy as np


def main():
  print("Start")
  SS_PATH = "ここにWin+PrintScreenが保存される場所のパスを入れてください。下のように..."
  # SS_PATH = "C:\\Users\\khc\\OneDrive\\画像\\スクリーンショット\\"
  SS_output_PATH = SS_PATH + "outputs\\"
  if not os.path.isdir(SS_output_PATH):
    os.mkdir(SS_output_PATH)

  SS_re = re.compile("スクリーンショット \\([0-9]+\\).png")
  SS_num_re = re.compile("[0-9]+")

  img_path_list = list(filter(lambda x: SS_re.match(x), os.listdir(SS_PATH)))
  img_path_list.sort(key=lambda x: int(SS_num_re.search(x).group()))

  mstr = imread(SS_PATH+"master.png")
  dcpl = imread(SS_PATH+img_path_list[0])

  top, bottom, left, right = find_place(mstr, dcpl)

  for img_name in img_path_list:
    img_in = SS_PATH+img_name
    img_out = SS_output_PATH+img_name
    trim_img = imread(img_in)
    imwrite(img_out, trim_img[top: bottom, left: right])

  print(len(img_path_list), "images has clipped at", SS_output_PATH)

def find_place(mstr, dcpl):
  h, w = mstr.shape[:2]
  first_pixel = mstr[0][0].sum()
  i_cdd, j_cdd = np.where(dcpl.sum(axis=2)==first_pixel)
  for i,j in zip(i_cdd, j_cdd):
    if np.all(mstr==dcpl[i: i+h, j: j+w]):
      print("find!")
      return i, i+h, j, j+w
  print("見つけられませんでした。。。")


def imread(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8):
  try:
    n = np.fromfile(filename, dtype)
    img = cv2.imdecode(n, flags)
    return img
  except Exception as e:
    print(e)
    return None


def imwrite(filename, img, params=None):
  try:
    ext = os.path.splitext(filename)[1]
    result, n = cv2.imencode(ext, img, params)
    if result:
      with open(filename, mode='w+b') as f:
        n.tofile(f)
      return True
    else:
      return False
  except Exception as e:
    print(e)
    return False


if __name__ == '__main__':
  main()

説明

スクリーンショットのフォルダから自動保存された画像を持ってきて、同じフォルダに入ってるmaster.pngと一致してる部分をトリミングして保存してる。
なので一番小さい番号の画像の中にあるウィンドウがmaster.pngと完全に一致しないと見つけられなくて終了する。
↑のコメントで書いてる通りにやればたぶん一緒になるはずだけど。。。
撮りたいウィンドウに動画とか入ってると完全一致は難しいと思うから、そのときはmasterを自分で切り出して作ればいいんじゃないかな。(投げやり)
スクリーンショットのフォルダに保存される画像のナンバリングってフォルダを空にしてもリセットされんっぽい。人生みたいだね。

参考にしたサイト

ありがとうございました!