public Bitmap getBitmap() {
    if (mTileLayer == null) return null;

    // Begin a tile transaction, otherwise the buffer can be destroyed while
    // we're reading from it.
    beginTransaction(mTileLayer);
    try {
      if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0) return null;
      try {
        Bitmap b = null;

        if (mTileLayer instanceof MultiTileLayer) {
          b =
              Bitmap.createBitmap(
                  mBufferSize.width,
                  mBufferSize.height,
                  CairoUtils.cairoFormatTobitmapConfig(mFormat));
          copyPixelsFromMultiTileLayer(b);
        } else {
          Log.w(
              LOGTAG,
              "getBitmap() called on a layer ("
                  + mTileLayer
                  + ") we don't know how to get a bitmap from");
        }

        return b;
      } catch (OutOfMemoryError oom) {
        Log.w(LOGTAG, "Unable to create bitmap", oom);
        return null;
      }
    } finally {
      endTransaction(mTileLayer);
    }
  }
  public void copyPixelsFromMultiTileLayer(Bitmap target) {
    Canvas c = new Canvas(target);
    ByteBuffer tileBuffer = mBuffer.slice();
    int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;

    for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) {
      for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) {
        // Calculate tile size
        IntSize tileSize =
            new IntSize(
                Math.min(mBufferSize.width - x, TILE_SIZE.width),
                Math.min(mBufferSize.height - y, TILE_SIZE.height));

        // Create a Bitmap from this tile
        Bitmap tile =
            Bitmap.createBitmap(
                tileSize.width, tileSize.height, CairoUtils.cairoFormatTobitmapConfig(mFormat));
        tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer());

        // Copy the tile to the master Bitmap and recycle it
        c.drawBitmap(tile, x, y, null);
        tile.recycle();

        // Progress the buffer to the next tile
        tileBuffer.position(tileSize.getArea() * bpp);
        tileBuffer = tileBuffer.slice();
      }
    }
  }