FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Unity »【Unity】【C#】BMP をランタイムで読み込む

【Unity】【C#】BMP をランタイムで読み込む  


 実は VRM Live Viewer には既に導入されているのだが、BMP を画像素材(テクスチャ)として利用したいこともあるだろう。実装当時、ググっても英語サイトしか出てこなかったので、需要は少ないのかも知れないが、探すのに苦労しないように備忘録として残しておく。

 今回紹介する方法は、オープンソースの BMPLoader を使う方法だ。

 以前「ランタイム時にファイルをドラッグ&ドロップして取得する」で紹介した「UnityWindowsFileDrag-Drop」の作者の Bunny83 さんの配布ライブラリで、とても簡単に扱えたので、その方法を書いておこう。


(※) Unity 2018.4.8f1 / Windows10(x64) で確認



■BMPLoader を導入する

 導入方法は簡単だ。以下の公開サイトへ行き、コピペで C# ファイルを作って欲しい。ページの一番下の方に「Raw Paste Data」という欄があるので、ここからコピーするのが簡単だろう。

BMPLoader.cs





■簡単なサンプルを作ってみる(基本的なコード)

 ググってみるといくつか出てくるので、以下などを参考にするのも良いだろう。

How to load a BMP file in binary?
How can I use a .bmp file and create a Texture in Unity at runtime?

 実際には BMPLoader.LoadBMP() はいくつかオーバーロードがあるので、利用方法によって使い分けるのも良いかも知れない。ここでは後述する「非同期ロードに対応してみる」に合わせた書き方となっている。定義をみて自分なりに書き換えるのも良いだろう。

●BMPLoadTest.cs(※名前は任意)
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using B83.Image.BMP;

public class BMPLoadTest : MonoBehaviour
{
public RawImage image; //読み込み先(※インスペクタで UI を設定)
public string filePath = "c:/test/image/sample.bmp"; //※ファイルは任意

// Use this for initialization
private void Start()
{
var bytes = File.ReadAllBytes(filePath);
var loader = new BMPLoader();
//loader.ForceAlphaReadWhenPossible = true; // can be uncomment to read alpha
var bmpImage = loader.LoadBMP(bytes);
image.texture = bmpImage.ToTexture2D();
}

private void OnDestroy()
{
if (image.texture != null)
{
Destroy(image.texture);
image.texture = null;
}
}
}
#endif

 このサンプルではエラーのチェック等は省略しているので、あくまで全て必要なもの(ファイルとか)が揃っている場合であることを留意しておいて欲しい。

 とりあえず、BMP をロードして表示できたなら成功だ。





■非同期ロードに対応してみる

 とりあえず前述の基本的なコードでも十分なのだが、動作確認が取れたなら、ちょっと手を加えて非同期読み込みすると良いかも知れない。ただし、以下のコードは .NET 4.x 以降である必要がある。

●BMPLoadTest.cs(※名前は任意)
using System.IO;
using System.Threading.Tasks; //※追加
using UnityEngine;
using UnityEngine.UI;
using B83.Image.BMP;

public class BMPLoadTest : MonoBehaviour
{
public RawImage image; //読み込み先(※インスペクタで UI を設定)
public string filePath = "c:/test/image/sample.bmp"; //※ファイルは任意

// Use this for initialization
private async void Start() //※async を追加
{
var bytes = await Task.Run(() => File.ReadAllBytes(filePath)); //※Task で別スレッドで読み込み
var loader = new BMPLoader();
//loader.ForceAlphaReadWhenPossible = true; // can be uncomment to read alpha
var bmpImage = await Task.Run(() => loader.LoadBMP(bytes)); //※Task で別スレッドでロード
image.texture = bmpImage.ToTexture2D();
}

private void OnDestroy()
{
if (image.texture != null)
{
Destroy(image.texture);
image.texture = null;
}
}
}
#endif

 ファイルの大きさにもよるが、私が計測したところ、非同期にすれば約1.5倍くらいの速度で読み込める。もし、UniRx を使っているのなら、Task は UniTask にした方が良いだろう。

 ちなみに私が提供しているプラグインを使えば、Android でも BMP を読み込めた。実際にスマホで全天球ビューワを作ることも可能だ(これが VRM Live Viewer で実装されている)。

 ここでは簡単なサンプルなので Start() でやってしまったが、static なメソッドにしてしまえば、使い回しもできて非常に便利だ。その場合にはファイル名やファイル自体の存在チェック、非同期キャンセルのための CancellationToken など入れた方が良いだろう。Task.Run() は2回に分けてあるが、ファイル読み込み/テクスチャとしてロードするのに時間がかかることを考慮して、それぞれにキャンセルチェックをした方が良いと思う(きちんと実装すると結構長くなるため、今回は要点だけにした)。その辺りはご自由に(笑)。






(関連記事)
【Unity】【C#】ランタイム時にファイルをドラッグ&ドロップして取得する(Windows のみ)
【Unity】スマホで簡易360度(パノラマ, 全天球)ビューワを作る
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】AssetStore版 FantomPlugin のセットアップ


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityオープンソースライブラリ  画像ファイル読み込み 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/337-1836a4d9
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR