android Bitmap回転と処理時間

androidでBitmapを回転するには、Bitmap.createBitmapを使います。Bitmap.createBitmapについて、回転角度、filter引数、処理時間について、説明します。

Bitmap.createBitmap

androidでBitmapを回転するには、Bitmap.createBitmapを使います。

public static Bitmap createBitmap (Bitmap source, 
                int x, 
                int y, 
                int width, 
                int height, 
                Matrix m, 
                boolean filter)Code language: Java (java)

Bitmap | Android デベロッパー

回転は、Matrix mで指定します。

回転角が90度、180度、270度の場合は、最後の引数filterをfalseにします。

その他の回転角の場合は、状況によって、引数filterをtrue/falseを使い分けます。

多くの状況で、回転の処理時間は、ARGB_8888のほうが速いです。

拡大縮小や平行移動の処理時間は測定していません。

回転角が90度、180度、270度

引数filterがtrueでもfalseでも、回転後の画像は同じです。ところが、filterをtrueにすると、処理時間が1.5〜3倍長くなるので、filterはfalseにしたほうがいいです。

Bitmap rotate90(final Bitmap beforeBmp, final int degrees) {
    final int w = beforeBmp.getWidth();
    final int h = beforeBmp.getHeight();
	
    final Matrix m = new Matrix();
    m.setRotate(degrees);
	
    final Bitmap afterBmp = Bitmap.createBitmap(beforeBmp, 0, 0, w, h, m, false);
    return afterBmp;
}Code language: Java (java)

その他の回転角

引数filterをtrueで回転した画像と、falseで回転した画像は違います。

また、filterをtrueにすると、処理時間が1.5〜3倍長くなります。画像が小さくて、回転後の輪郭や境界のギザギザがあまり目立たないなら、filterをfalseにしたほうがいいかもしれません。

Bitmap rotate(final Bitmap beforeBmp, final float degrees) {
    final int w = beforeBmp.getWidth();
    final int h = beforeBmp.getHeight();
	
    final Matrix m = new Matrix();
    m.setRotate(degrees);
	
    final Bitmap afterBmp = Bitmap.createBitmap(beforeBmp, 0, 0, w, h, m, true);
    return afterBmp;
}Code language: Java (java)

filter=trueとfalseの違い

10x10、左半分を赤、右半分を白にした画像を用意しました。表示のために、100x100に拡大してあります。

元画像

回転角=30度、filter=trueで回転した画像です。回転後は14x14ですが、144x144に拡大してあります。(android studioのdebugのview bitmapのスクショです)

回転角=30度、filter=true

回転角=30度、filter=falseで回転した画像です。

回転角=30度、filter=false

filter=trueと比べると、中央の赤と白の境界がギザギザになっています。

元画像がARGB_8888か、RGB_565かで、処理時間が違う

5120x3840の画像を用意しました。

  • 回転角=90、30
  • filter=true、false
  • Bitmap.Config=ARGB_8888、RGB_565
  • AVD=29、28、27、26

について、処理時間を測定しました。

ARGB_8888が遅いときは、せいぜい1.6倍遅い程度に対して、RGB_565が遅いときは、2〜3倍遅いことが多かったです。

メモリ使用量のことは考えず、処理時間だけを考えるなら、
90度、filter=false
30度、filter=true
30度、filter=false
どの場合も、ARGB_8888にしたほうがよいようです。

90度、filter=false

RGB_565のほうが速いと予想しましたが、ARGB_8888のほうが優勢でした。

  • AVD=29、28は、RGB_565のほうが、1.4〜1.6倍速い。
  • AVD=27、26の、ARGB_8888のほうが、2.3〜3倍速い。
機種
ARGB_8888
(ms)
RGB_565
(ms)
遅いほう何倍遅いか
SH-M1221552653RGB_5651.2
AVD=29693438ARGB_88881.6
AVD=28833592ARGB_88881.4
AVD=273821143RGB_5653.0
AVD=265021167RGB_5652.3

30度、filter=true

アンチエイリアスは、ピクセルのR、G、Bごとに計算します。ARGB_8888のRGBアクセスはバイトアクセスです。RGB_565のRGBアクセスはビット分解合成が必要です。ARGB_8888よりRGB_565が遅いのは、バイトアクセスよりビット分解合成のほうが遅いからと推測します。

  • 全体的に、ARGB_8888のほうが、1.6〜3.6倍速いです。
  • AVD=26は、ほぼ同じ。
機種
ARGB_8888
(ms)
RGB_565
(ms)
遅いほう何倍遅いか
SH-M1212832808RGB_5652.2
AVD=29369835RGB_5652.3
AVD=28424671RGB_5651.6
AVD=273931398RGB_5653.6
AVD=26318293ARGB_88881.1

30度、filter=false

RGB_565のほうが速いと予想しましたが、ARGB_8888のほうが優勢でした。

  • AVD=29、28は、ほぼ同じ。
  • AVD=26、27は、ARGB_8888のほうが、約2倍速い。
機種
ARGB_8888
(ms)
RGB_565
(ms)
遅いほう何倍遅いか
SH-M12692616ARGB_88881.1
AVD=29223227RGB_5651.0
AVD=28266231ARGB_88881.2
AVD=27245467RGB_5651.9
AVD=26131237RGB_5651.8

測定データ

SH-M12

回転角度
filterARGB_8888
(ms)
RGB_565
(ms)
90true45014095
90false21552653
30true12832808
30false692616

AVD=29

回転角度
filterARGB_8888
(ms)
RGB_565
(ms)
90true9311248
90false693438
30true369835
30false223227

AVD=28

回転角度
filterARGB_8888
(ms)
RGB_565
(ms)
90true12121003
90false833592
30true424671
30false266231

AVD=27

回転角度
filterARGB_8888
(ms)
RGB_565
(ms)
90true5231462
90false3821143
30true3931398
30false245467

AVD=26

回転角度
filterARGB_8888
(ms)
RGB_565
(ms)
90true5612911
90false5021167
30true318293
30false131237
タイトルとURLをコピーしました