title: How to create emboss around a Bitmap?
body: <p>The popular game <a href="https://play.google.com/store/apps/details?id=com.zynga.words" rel="nofollow noreferrer">Words with Friends</a> draws letter tiles at the game board <em>as a single entity</em> -</p>
  
  <p>You can see a yellow linear gradient <em>applied to all letter tiles</em> in the following screenshot and also an emboss effect on the edge:</p>
  
  <p><img src="https://i.stack.imgur.com/CgyyT.jpg" alt="app screenshot"></p>
  
  <p>In <a href="https://github.com/afarber/android-newbie/tree/master/MyTiles2" rel="nofollow noreferrer">my word game</a> I would like to have similar effects:</p>
  
  <p><img src="https://i.stack.imgur.com/MjML5.png" alt="emboss example"></p>
  
  <p>So I create a game board sized <code>mBitmap</code>, then draw all tiles into it and finally draw the bitmap into <a href="https://github.com/afarber/android-newbie/blob/q27/MyTiles2/src/de/afarber/mytiles2/MyView.java" rel="nofollow noreferrer">my custom view</a> - </p>
  
  <p><strong>Setup:</strong></p>
  
  <pre><code>setLayerType(View.LAYER_TYPE_SOFTWARE, null);
  
  // create yellow linear gradient
  mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
  mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
  LinearGradient gradient = new LinearGradient(
          mGradStart.x,
          mGradStart.y,
          mGradEnd.x,
          mGradEnd.y,
          new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
          null,
          TileMode.CLAMP);
  
  // create the big bitmap holding all tiles
  mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
  mCanvas = new Canvas(mBitmap);
  
  mPaintGrad = new Paint();
  mPaintGrad.setShader(gradient);
  
  mPaintEmboss = new Paint();
  mPaintEmboss.setShader(gradient);
  
  EmbossMaskFilter filter = new EmbossMaskFilter(
      new float[] { 0f, 1f, 0.5f }, 0.8f, 3f, 3f);
  mPaintEmboss.setMaskFilter(filter);
  </code></pre>
  
  <p><strong>Drawing:</strong></p>
  
  <pre><code>@Override
  protected void onDraw(Canvas canvas) {
      mGameBoard.draw(canvas);
  
      // draw all tiles as rectangles into big bitmap 
      // (this code will move to onTouchEvent later)
      mBitmap.eraseColor(Color.TRANSPARENT);
      for (SmallTile tile: mTiles) {
          mCanvas.drawRect(
                  tile.left, 
                  tile.top, 
                  tile.left + tile.width, 
                  tile.top + tile.height, 
                  mPaintGrad);
          tile.draw(mCanvas);
      }
      canvas.drawBitmap(mBitmap, 0, 0, mPaintEmboss); // emboss NOT displayed
      canvas.drawText("TEXT WORKS OK", 400, 400, mPaintEmboss); // ebmoss OK
      canvas.drawRect(300, 600, 800, 1200, mPaintEmboss); // emboss OK
  }
  </code></pre>
  
  <p>The <code>EmbossMaskFilter</code> effect works OK with <code>drawText()</code> and <code>drawRect()</code> calls, but it does NOT work for the <code>drawBitmap()</code>:</p>
  
  <p><img src="https://i.stack.imgur.com/3BKYI.png" alt="app screenshot"></p>
  
  <p><strong>My question:</strong> is it possible to use some combinations of <a href="http://ssp.impulsetrain.com/porterduff.html" rel="nofollow noreferrer">PorterDuff.Mode</a> (and <code>extractAlpha</code>?) to draw an emboss around my big bitmap?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>By looking at <a href="https://android.googlesource.com/platform/packages/apps/Launcher2/+/master/src/com/android/launcher2/HolographicOutlineHelper.java" rel="nofollow noreferrer">HolographicOutlineHelper.java</a> I have been able to add an outer shadow:</p>
  
  <p><img src="https://i.stack.imgur.com/thCTx.png" alt="app screenshot"></p>
  
  <p>with the following code in <a href="https://github.com/afarber/android-newbie/blob/q28/MyTiles2/src/de/afarber/mytiles2/MyView.java" rel="nofollow noreferrer">MyView.java</a> -</p>
  
  <p><strong>Setup:</strong></p>
  
  <pre><code>public MyView(Context context, AttributeSet attrs) {
      super(context, attrs);
  
      mScale = getResources().getDisplayMetrics().density;
      mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
      mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
      LinearGradient gradient = new LinearGradient(
              mGradStart.x,
              mGradStart.y,
              mGradEnd.x,
              mGradEnd.y,
              new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
              null,
              TileMode.CLAMP);
  
      mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
      mCanvas = new Canvas(mBitmap);
  
      mPaintGrad = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
      mPaintGrad.setShader(gradient);
  
      mPaintBlur = new Paint();
      mPaintBlur.setColor(Color.BLACK);
      BlurMaskFilter blurFilter = new BlurMaskFilter(mScale * 1, Blur.OUTER);
      mPaintBlur.setMaskFilter(blurFilter);
  }
  </code></pre>
  
  <p><strong>Drawing:</strong></p>
  
  <pre><code>private void prepareBitmaps() {
      mBitmap.eraseColor(Color.TRANSPARENT);
      for (SmallTile tile: mTiles) {
          mCanvas.drawRect(
                  tile.left, 
                  tile.top, 
                  tile.left + tile.width, 
                  tile.top + tile.height, 
                  mPaintGrad);
          tile.draw(mCanvas);
      }
  
      mAlphaBitmap = mBitmap.extractAlpha(mPaintBlur, mOffset);
  }
  
  @Override
  protected void onDraw(Canvas canvas) {
      mGameBoard.draw(canvas);
      canvas.drawBitmap(mAlphaBitmap, mOffset[0], mOffset[1], mPaintBlur);
      canvas.drawBitmap(mBitmap, 0, 0, mPaintGrad);
  }
  </code></pre>
  
  <p>but unfortunately the app is acting slow now - and I still don't know how to add an emboss effect around the bitmap.</p>