2014年5月3日 星期六

Android 開發(四十一) Spotlight

這是由 Romain Guy 提供的作法
下面是他的網址
http://www.curious-creature.org/2012/12/13/android-recipe-2-fun-with-shaders/

他的做法其實是利用 canvas  draw bitmap 以及 paint來完成,
首先他將背景設置到 paint,
接著將mask 轉成 alpha 接著在canvas上繪製就完成了。

知道大概要怎麼做之後,我們來看code

  • 將背景設置到 paint

 private void createShader() {
  View target = getRootView().findViewById(mTargetId);
  mTargetBitmap = createBitmap(target);
  Shader targetShader = createShader(mTargetBitmap);
  mPaint.setShader(targetShader);
 }

 private static Shader createShader(Bitmap b) {
  return new BitmapShader(b, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
 }

 private static Bitmap createBitmap(View target) {
  Bitmap b = Bitmap.createBitmap(target.getWidth(), target.getHeight(), Bitmap.Config.ARGB_8888);
  Canvas c = new Canvas(b);
  target.draw(c);
  return b;
 }


  • 接著將mask圖轉成alpha


        mMask = convertToAlphaMask(BitmapFactory.decodeResource(getResources(), maskId));
 
        private static Bitmap convertToAlphaMask(Bitmap b) {
  Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
  Canvas c = new Canvas(a);
  c.drawBitmap(b, 0.0f, 0.0f, null);
  return a;
 }


  • 接著在canvas上繪製

canvas.drawBitmap(mMask, 0.0f, 0.0f, mPaint);

基本的功能這樣就完成了,如下圖



接著該如何讓spotlight移動以及放大是另一個問題,
假設我們希望將剛剛的spotlight放大3倍,並且移至較中間的位置 100,100 我們應該怎麼做呢?

  mShaderMatrix.setScale(1.0f / 3, 1.0f / 3);
  mShaderMatrix.preTranslate(-100, -100);

  mPaint.getShader().setLocalMatrix(mShaderMatrix);
  
  canvas.translate(100, 100);
  canvas.scale(3, 3);
  canvas.drawBitmap(mMask, 0.0f, 0.0f, mPaint);

可以發現,作者的做法是

  1. 先將背景先縮小並反向位移
  2. 接著再將整個畫布放大並位移


也就是原先看到的mask 被放大的並位移到較中間的位置,而背景的縮放以及位移被抵銷掉
結果的圖如下


由於作者的範例包含太多動畫,所以我寫了一個更簡單的sample,由兩個按鈕來控制
postion以及 scale  ,讓大家比較容易trace,附上 sample code

沒有留言:

張貼留言