はじめに
AdobeのASEファイルをUnity上で読み込ませたいなぁと思ったので、ASEファイルから色を取り出すものを作ってみました。
環境
Unity 5.6.1f1
Windows 10
ASEファイルとは
Adobe製品(PhotoshopやIllustratorなど)では、色のセットを共有できる仕組みが用意されています。
そこで使うのがASEファイルです。
ASEファイルには複数のRGBカラーが格納されています。
今回はUnity上でASEファイルからRGBデータを取り出していきたいと思います。
ASEファイルのバイナリを覗いてみる
今回はASEファイルの バイナリ を読んで、RGB値がどこに保存されているかを解読して行きたいと思います。
今回使用するASEファイル
今回はバイナリ上で色がどこに並んでいるかを見つけやすくするため、RGB=(255, 255, 255)が3つ登録されている.aseファイルを使用します。
ASEファイルのバイナリを覗いてみる
バイナリツール( http://qiita.com/r-ngtm/items/8abca767afbb5a6df3cc )を使ってUnity上でASEファイルのバイナリを表示させてみます。
ASEファイルを開くと以下のような感じになります。 数字がたくさん並んでいます。
このバイナリをよく観察すると、バイト列 3F8000 が複数回表れていることが読み取れます。
この 3F8000 がRGB値ではないかと私は予想しました。
ASEファイルの構造
さらに調べていったところ、バイナリの構造は以下のようになっているということが分かりました。
3F8000 の正体
この 3F8000 ですが、floatの1.0を16進数で表したものになっています。
どうやら、ASEファイルにはRGBの各チャンネルの数値が0.0 ~ 1.0の範囲で保存されているようです。
RGBを抽出するコードを書いてみる
RGB個数とRGB値の格納場所が把握できたので、ASEファイルからRGBを抽出するコードを書いていきます。
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// .aseファイルから情報を抽出するクラス
/// </summary>
public static class AseExtractor
{
/// <summary>
/// .aseファイルの色を取り出す
/// </summary>
public static IEnumerable<Color> GetColors(Object ase)
{
// .aseのバイナリを取得
byte[] bin = ToBinary(ase);
// RGBの個数の取得
int colorCount = bin[11];
// RGB値を取り出していく
int pos = 40;
for (int i = 0; i < colorCount; i++)
{
float r = ReadFloatBE(bin, pos, 4);
float g = ReadFloatBE(bin, pos + 4, 4);
float b = ReadFloatBE(bin, pos + 8, 4);
yield return new Color(r, g, b, 1f);
pos += 42;
}
}
static float ReadFloatBE(byte[] bytes, int pos, int length)
{
byte[] b = new byte[length];
int src = pos + length - 1;
for (int i = 0; i < length; i++)
{
b[i] = bytes[src--];
}
return System.BitConverter.ToSingle(b, 0);
}
/// <summary>
/// Assetをバイト列にする
/// </summary>
static byte[] ToBinary(Object asset)
{
var split = AssetDatabase.GetAssetPath(asset).Split('/');
var path = Application.dataPath + "/";
for (int i = 1; i < split.Length - 1; i++)
{
path += split[i] + "/";
}
path += split[split.Length - 1];
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader bin = new BinaryReader(fileStream);
return bin.ReadBytes((int)bin.BaseStream.Length);
}
}
上記クラスの GetColors メソッドへASEファイルを指定するとRGB一覧が取得できます。(完)
ASEファイルフォーマット
今回はASEファイルのバイナリを読んで強引にインポートツールを作ってしまいましたが、
ASEのファイルフォーマットやC#での読み込み方法についてまとめたWebページが既にあったようです。 (この記事を書き終えた後に見つけてしまいました。)
Reading Adobe Swatch Exchange (ase) files using C#
https://www.cyotek.com/blog/reading-adobe-swatch-exchange-ase-files-using-csharp
こちらを参考にインポートツールを作ったほうが良いかもしれません。
参考URL
アプリケーション間でのスウォッチの共有(交換用スウォッチ)
http://www.dtp-transit.jp/adobe/illustrator/post_1963.html
Photoshopスウォッチの管理方法
http://www.syumpei.com/blog/2014/04/swatch.html