N2-Works
WEB企画・制作/システム開発 大阪拠点

AndroidのBitmap画像プログラミング(2) 透過処理

AndroidのAndroidのBitmap画像プログラミング第二回です。

今回は画像の透過処理です。

Androidでは画像バッファの1pixel情報であるintがARGBを表しています。

ARGBのAはalpha値で上位1byte、つまり0~255の値で表現されます。

alpha値が0の場合下位3byteにどんな値が入っていても描画されません。

つまり透過色をあらかじめ決めておいて、透過対象のpixelのalpha値を0にすれば透過処理の完成です。

透過処理

以下のような関数で実現できます。

public void InvalidBufferFromColor(int color)
{
  int buf_color = 0;
  for (int y = 0; y < mHeight; y++) {
    for (int x = 0; x < mWidth; x++) {
      buf_color = mBuffer[x + y * mWidth];
      if (((buf_color >>> 24) & 0xff) > 0) {
        if ((buf_color & 0xffffff) == (color & 0xffffff)) {
          mBuffer[x + y * mWidth] = (buf_color & 0xffffff);
        }
      }
    }
  }
}

サンプルとして、赤色を透過してみました。

サンプル

package net.n2works.BitmapTest;

// SYSTEM PACKAGE
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class BitmapTest extends Activity
{
  // Bitmap
  private Bitmap mBitmap;
  private Bitmap mBitmap2;

  /**
   * Component
   */
  // SurfaceView
  private SurfaceView mView;

  /**
   * クラス定数
   */
  private final int BG_COLOR = 0xff000000;
  private final int BITMAP_W = 200;
  private final int BITMAP_H = 200;

  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    // BITMAPの作成
    ImageBuffer buf = new ImageBuffer(BITMAP_W, BITMAP_H);
    buf.FillClip(
      buf.new ClipFillInfo(
        0,
        0,
        BITMAP_W,
        BITMAP_H,
        0xffff0000
      )
    );
    buf.FillClip(
      buf.new ClipFillInfo(
        BITMAP_W / 4,
        BITMAP_H / 4,
        BITMAP_W / 2,
        BITMAP_H / 2,
        0xff0000ff
      )
    );

    mBitmap = Bitmap.createBitmap(BITMAP_W, BITMAP_H, Bitmap.Config.ARGB_8888);
    mBitmap.setPixels(buf.GetBuffer(), 0, BITMAP_W, 0, 0, BITMAP_W, BITMAP_H);

    // コピー
    ImageBuffer buf2 = new ImageBuffer(BITMAP_W, BITMAP_H);
    buf2.BltClip(
      buf,
      buf2.new ClipBltInfo(
        0,
        0,
        0,
        0,
        BITMAP_W,
        BITMAP_H
      )
    );

    // 赤成分を無効
    buf2.InvalidBufferFromColor(0xffff0000);

    mBitmap2 = Bitmap.createBitmap(BITMAP_W, BITMAP_H, Bitmap.Config.ARGB_8888);
    mBitmap2.setPixels(buf2.GetBuffer(), 0, BITMAP_W, 0, 0, BITMAP_W, BITMAP_H);

    // Viewの設定
    mView = new SurfaceViewEx(this);
    setContentView(mView);
  }

  private class SurfaceViewEx extends SurfaceView
  implements SurfaceHolder.Callback
  {
    /**
     *  Component
     */
    private ScheduledExecutorService executor;

    /**
     * クラス定数
     */
    private static final int FPS = 60;

    public SurfaceViewEx(Context context)
    {
      super(context);

      getHolder().addCallback(this);
      getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
    }

    public void surfaceCreated(SurfaceHolder holder)
    {
      executor = Executors.newSingleThreadScheduledExecutor();
      executor.scheduleAtFixedRate(
        new Runnable()
        {
          public void run()
          {
            Canvas c = getHolder().lockCanvas();
            Draw(c);
            getHolder().unlockCanvasAndPost(c);
          }
        },
        1000 / FPS, 1000 / FPS,
        TimeUnit.MILLISECONDS
      );
    }

    public void surfaceDestroyed(SurfaceHolder holder)
    {
      mBitmap.recycle();
      mBitmap2.recycle();
      executor.shutdown();
    }

    protected void Draw(Canvas c)
    {
      // 背景色クリア
      c.drawColor(BG_COLOR, Mode.SCREEN);

      // Bitmap描画
      c.drawBitmap(mBitmap, 0, 0, null);
      c.drawBitmap(mBitmap2, 0.0f, 200.0f, null);
    }
  }
}

 

[Android]2011年02月22日 19時58分50秒

※1000文字以内で入力してください

captcha
TOP