はじめに
先駆者の記事を参考にC#でCLIP STUDIO PAINTのファイルのサムネイルを取得します。
サムネイルの取得方法
.clipファイル内にSQLiteの情報があり、その中からサムネイルの情報を取得します。
おおまかな流れ
- .clipファイルをバイト配列で取得
- "SQLite format 3"のインデックスを検索
- それ以降のデータをデータベースファイルとして書き出し
- 書き出したデータベースファイルをC#のSQLiteで取得
- CanvasPreviewテーブルのImageDataカラムのデータをバイト配列で取得
- 必要に応じてデータを変換する(今回はBitmapに変換し、PictureBoxに表示)
ファイルを開いてSQLiteの情報を取得
ファイルをバイト配列で取得し、その中からSQLiteのデータを抜き出し、データベースファイルとして書き出します。
ファイルデータの "SQLite format 3" 以降がSQLiteのデータになっています。
C#では配列から配列を検索するメソッドがないため、実装する必要があります。この処理の質によってサムネイル取得の速度が大きく変わります。今回はこちらの検索メソッドを利用しました。
LINQ文によって検索結果のインデックス以降のデータをデータベースファイルとして書き出します。
string searchStr = "SQLite format 3"; //検索文字列
byte[] searchData = Encoding.UTF8.GetBytes(searchStr); //検索データ(バイト配列)
string filePath = "~.clip"; //読み込む.clipファイル
string dbName = "temp.db"; //書き出すデータベースファイル
//ファイルを開く
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
//読み込んだデータを格納するバイト配列生成
byte[] byteData = new byte[fs.Length];
//ファイルからデータを読み込む
fs.Read(byteData, 0, byteData.Length);
//SQLiteのデータが始まるインデックスを取得する
//IEnumerableExtensions - 配列検索メソッド
int findIndex = IEnumerableExtensions.SearchBytes(byteData, searchData);
//SQLiteのデータを取得
byte[] byteDB = byteData.Skip(findIndex).ToArray();
//データベースファイルに書き出す
File.WriteAllBytes(dbName, byteDB);
}
SQLiteのデータからサムネイルを取得
SQLiteを使うためにNuGetでSystem.Data.SQLite
をインストールします。今回は最小限の利用になるため、System.Data.SQLite.Core
をインストールしました。
DataSourceに書き出したファイルを指定してデータベースに接続します。
CanvasPreview
テーブルのImageData
カラムのデータがサムネイルのデータになっているため取得します。
バイト配列に代入して、サムネイルの取得は完了です。
今回はBitmapに変換してPictureBoxに表示しています。
using System.Data.SQLite; //NuGet - System.Data.SQLite.Core
//データベースからデータを抜き出す
using (SQLiteConnection connection = new SQLiteConnection())
{
//ConnectionStringを指定
connection.ConnectionString = "Data Source=" + dbName;
//データベースを開く
connection.Open();
if (connection.State != System.Data.ConnectionState.Open)
Console.WriteLine("Database Open Failed"); //失敗
else
{
//サムネイルを取得する
using (SQLiteCommand command = connection.CreateCommand())
{
/*
SQL文
CanvasPreviewテーブルのImageDataカラムがサムネイルのデータになっている
*/
string sql = " select ImageData from CanvasPreview ";
//SQL文を指定
command.CommandText = sql;
//SQL実行
using (SQLiteDataReader reader = command.ExecuteReader())
{
//読む
reader.Read();
//読み込んだImageDataをバイト配列に取得
byte[] byteThumb = (byte[])reader["ImageData"];
//バイト配列をBitmapにしてPictureBoxに表示
using (MemoryStream ms = new MemoryStream(byteThumb))
{
//Bitmapに変換
Bitmap bmp = new Bitmap(ms);
//PictureBoxに表示
pictureBox.Image = bmp;
}
}
}
}
}
おわりに
先駆者の情報を参考にC#で.clipファイルのサムネイルを取得しました。
データベース上に様々なデータがあったので他のデータについても応用できそうです。
C#の配列の探索はメソッド等が用意されていないのでまだまだ最適化できる部分なのかもしれません。
参考
Pythonでのサムネイル取得
検索アルゴリズム