p-hone p-hone.info

CLIP STUDIO PAINT タイムラプス消し忘れチェック

CLIP STUDIO PAINTで普段お絵かきをしていて、タイムラプス機能をよく使っている。お絵描きの過程を動画にできて自分で見返すだけでも楽しいし、Twitterに上げたりもできる。

しかし、ひとつだけ難点がありタイムラプスをONにするとCLIPファイルが巨大になることだ。ひとつの絵で100MB以上になることも普通で、ディスク容量が圧迫されていく。 なので、イラストが完成してタイムラプスを動画化した後にタイムラプスをOFFにしているのだが、手作業なので忘れることも結構ある。そこで、多くのCLIPファイルに対して一括でタイムラプスがあるかどうかをチェックできるプログラムを(Pythonで)書いた。

import sqlite3
import sys
import tempfile


class Clip:
    def __init__(self, clipfile: str):
        with open(clipfile, "rb") as f:
            data = f.read()
            head = data.find(b"SQLite format 3")
            if head == -1:
                raise Exception(f"invalid clip format: {clipfile}")
        self._tf = tempfile.NamedTemporaryFile()
        self._tf.write(data[head:])
        self._tf.seek(0)
        self._db = sqlite3.connect(self._tf.name)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._db.__exit__(exc_type, exc_val, exc_tb)
        self._tf.__exit__(exc_type, exc_val, exc_tb)

    def has_timelapse(self):
        if self._db.execute("select count(*) from sqlite_master where name = 'TimeLapseRecord'").fetchone()[0] != 1:
            return False
        return self._db.execute("select count(*) from TimeLapseRecord").fetchone()[0] > 0


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: ./check_timelapse.py <CLIP_FILES...>", file=sys.stderr)
        exit(2)
    files = sys.argv[1:]
    for file in files:
        with Clip(file) as clip:
            print(f"{file}: {clip.has_timelapse()}")

引数に任意個数のCLIPファイルをつけて実行すると、タイムラプスの有無が表示される。次の実行例では カラーパレット縛りあおのちゃん.clip だけタイムラプスが残っていたことが判明した。便利!

$ python3 check_timelapse.py *.clip

Stella-rium.clip: False
ちみも×サラサちゃん.clip: False
新年スク水2023.clip: False
新年スク水2023_new.clip: False
はやかわちゃん.clip: False
いわれなき邪竜認定ちゃん.clip: False
カラーパレット縛りあおのちゃん.clip: True

CLIPファイルの中身の仕様は公開されていないが、ネットに落ちている情報によるとファイルの中身にSQLiteデータベースが埋め込まれているらしい。よってそこからタイムラプスっぽい名前のテーブルを引き出している。 有無のチェックだけでなく、タイムラプスの削除までプログラムでできればもっと便利なのだが、CLIPファイルの仕様がわからないのであきらめた。