LoginSignup
9
7

More than 5 years have passed since last update.

Androidのdrawableの画像リソースから、高速でバイト列を取得する方法

Posted at

Androidのdrawabaleに組み込んだ画像リソースから、検索してよく出てくる方法よりも素早くデータのバイト列を取得する方法です。
私がXamarin使いなのでXamarinのc#コードで例示しますが、XamarinのAPIは基本ラッパなので、JavaでAndroid開発されている方にも基本伝わるかと思います。

drawableの画像リソースをバイト列で取得する方法を検索していて、よく出てくる方法は以下のようなものです。

drawableリソース取得法1
var res_id = context.Resources.GetIdentifier ("res_name", "drawable", context.PackageName);
if (res_id == 0) {
    throw new Java.IO.FileNotFoundException("Resource Not Found");
}

var bitmap = BitmapFactory.DecodeResource(context.Resources, res_id);
byte[] data;
using (var stream = new MemoryStream())
{
    bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
    data = stream.ToArray();
}
return data;

ですが、これ、クソ重いです。
小さなアイコン画像とかだと気にならないのかもしれませんが、全画面サイズくらいのレベルの画像を取得しようと思うと、本当に一息つくというレベルでデータ取得までに時間がかかります。
考えてみれば当たり前で、元々pngでresourceに登録されているデータを、Bitmapに戻してから、またpngに圧縮してバイト化してるので、無駄な解凍/圧縮処理の分負荷と時間がかかってしまいます。

解決方法を探していて、以下のやり方を見つけました。

drawableリソース取得法2
var res_id = context.Resources.GetIdentifier ("res_name", "drawable", context.PackageName);
if (res_id == 0) {
    throw new Java.IO.FileNotFoundException("Resource Not Found");
}

var ins = context.Resources.OpenRawResource(res_id);      

var baos = new ByteArrayOutputStream();
var buff = new byte[10240];
var i = int.MaxValue;
while ((i = ins.Read(buff, 0, buff.Length)) > 0)
{
    baos.Write(buff, 0, i);
}

return baos.ToByteArray();

この方法だと、resourceから直接InputStreamを取得しているので、無駄な解凍/圧縮をしなくてよい分、一瞬でデータ取得できます。

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7