Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8829

CLIP STUDIO PAINTのファイルからNode.jsでサムネイル画像を出力する

$
0
0

CLIP STUDIO PAINTファイル(.clip)のサムネイル画像をNode.js上で出力してみました。

CLIPSTUDIO PAINTのファイルからサムネイル画像を取得

CLIP STUDIO PAINTで作成した漫画データのサムネール出力の為の調査

こちらの記事のように、Pythonやシェル、Goで実装されたライブラリ等はあったものの、JavaScript(TypeScript)で実装されたものが無かったので調べてみました。

概要

  • clipファイルからSQLite部分のデータを切り出し
  • 切り出したSQLiteファイルからサムネイル画像のデータを抽出

次節から実装になりますが、ファイルの読み書きにfs.readFileSync/writeFileSyncを使用しています。
また、単なる出力テストなので、実装する場合はfs.readFile/writeFileの使用及び適宜例外処理をお願いします。

コード

とりあえず全体像。TypeScriptで記述しています。
外部モジュールとしてsqlite3をインストールしてください。

$ npm i sqlite3
import*asfsfrom"fs"import*assqlite3from"sqlite3"// .clipファイルパスconstpath="../sample_asset/illust1"constclipPath=path+".clip"// Bufferの読み込みconstclipBuffer=fs.readFileSync(clipPath)// SQLiteのデータは「SQLite format 3」から始まるらしいconstsearchText="SQLite format 3"// Uint8Arrayに変換constuint8Array=newUint8Array(Buffer.from(searchText))// clipからSQLiteのデータのスタート位置を取得constfindIndex=clipBuffer.indexOf(uint8Array)// SQLite部分のみ切り出しconstdbBuf=clipBuffer.slice(findIndex,clipBuffer.length)// 一時書き出し用のSQLiteファイルパスconstdbPath=path+".sqlite"// いったんsqliteファイルに書き出しfs.writeFileSync(dbPath,dbBuf)// sqlite3モジュールでSQLiteファイルを展開constdb=newsqlite3.Database(dbPath)db.serialize(()=>{// CanvasPreviewテーブルからImageData(png)を抽出db.get("SELECT ImageData FROM CanvasPreview",(err,row)=>{if(err){console.log(err)return}if(row.length>0){// png出力パスconstbinaryPath=path+".png"// rowのImageDataプロパティからpngを生成fs.writeFileSync(binaryPath,row.ImageData)}})})

解説

clipファイルの読み込み

// .clipファイルパスconstpath="..\\sample_asset\\illust1"constclipPath=path+".clip"// Bufferの読み込みconstclipBuffer=fs.readFileSync(clipPath)

fs.readFileSyncでclipファイルの読み込みを行う。
fs.readFileSyncBufferを返す。

SQLiteのデータの位置を探索

clipファイルは何らかのメタデータ+SQLiteで構成されているらしく、
そのままでは下記のとおりSQLiteとして展開できない。

// PowerShellで確認
$ C:\...> sqlite3 illust1.clip
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.

// テーブルリストを出力
$ sqlite> .table
Error: file is not a database

そこで、SQLiteのデータだけ切り出してやる必要がある。
噂によるとSQLiteのデータは「SQLite format 3」から始まるらしい。

// SQLiteのデータは「SQLite format 3」から始まるらしいconstsearchText="SQLite format 3"// Uint8Arrayに変換constunit8Array=newUint8Array(Buffer.from(searchText))// clipからSQLiteのデータのスタート位置を取得constfindIndex=clipBuffer.indexOf(uint8Array)// SQLite部分のみ切り出しconstdbBuf=clipBuffer.slice(findIndex,clipBuffer.length)// 一時書き出し用のSQLiteファイルパスconstdbPath=path+".sqlite"// いったんsqliteファイルに書き出しfs.writeFileSync(dbPath,dbBuf)

Buffer#indexOfにて、SQLiteのインデックスを取得する。
インデックスが分かったら、そこから終点までsliceしてやる。

取得したバッファをfs.writeFileSyncでSQLiteファイルとして書き出し。

SQLiteの展開とpngの書き出し

SQLiteファイルのテーブルは次のようになっており、
CanvasPreviewテーブルにプレビュー画像のデータが保持されている。

// PowerShellで確認
$ C\...> sqlite3 illust1.sqlite //←上で生成したやつ
$ sqlite3> .table
AnimationCutBank            Layer
Canvas                      LayerThumbnail
CanvasItem                  Mipmap
CanvasItemBank              MipmapInfo
CanvasPreview               Offscreen
ElemScheme                  ParamScheme
ExternalChunk               Project
ExternalTableAndColumnName  RemovedExternal

sqlite3モジュールにより、先ほど生成したSQLiteファイルを展開する。

// sqlite3モジュールでSQLiteファイルを展開constdb=newsqlite3.Database(dbPath)db.serialize(()=>{// CanvasPreviewテーブルからImageData(png)を抽出db.get("select ImageData from CanvasPreview",(err,row)=>{if(err){console.log(err)return}if(row.length>0){// png出力パスconstbinaryPath=path+".png"// row.ImageDataプロパティからpngを生成fs.writeFileSync(binaryPath,row.ImageData)}})})

クエリにてCanvasPreviewからImageDataを取得する。
このとき出力結果のrowには、次の形でデータが格納されている。

{ImageData:<Buffer89504e470d0a...>}

つまり、row.ImageDataで目的のサムネイル画像のデータを取得することが可能。
最後に、fs.writeFileSyncによりillust1.pngrow.ImageDataを書き出してやれば終了である。

参考

CLIP STUDIO PAINTで作成した漫画データのサムネール出力の為の調査

CLIPSTUDIO PAINTのファイルからサムネイル画像を取得

CLIP STUDIO PAINTの.lipファイルをハックして作業動画を書き出すWindowsアプリを作った

Node.js で TextEncoder や SHA512 を作る

MDN - オブジェクトでの作業

Node.js で SQLite を扱う

Writing to Files in Node.js

Get list of tables from SQLite in Node.js

主にPowerShell関係

MS - certutil

Windows10でバイナリ<->HEXテキスト変換

PowerShellからデータを出力するパターンまとめ

cutコマンドについてまとめました 【Linuxコマンド集】

Windows PowerShell : UNIXの cut コマンド相当の作業をする。


Viewing all articles
Browse latest Browse all 8829

Trending Articles