예제 #1
0
  /** Private method for grabbing a "screenshot" of screen content */
  private void drawOffscreenBitmap() {
    // Grab global visible rect for later use
    // mView.getGlobalVisibleRect(mRectVisibleGlobal);

    // Calculate scaled off-screen bitmap width and height
    int width = Math.round(mView.getWidth() * BITMAP_SCALE_FACTOR);
    int height = Math.round(mView.getHeight() * BITMAP_SCALE_FACTOR);

    // Width and height must be > 0
    width = Math.max(width, 1);
    height = Math.max(height, 1);

    // Allocate new off-screen bitmap only when needed
    if (mBitmap == null || mBitmap.getWidth() != width || mBitmap.getHeight() != height) {
      mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
      mAllocationBitmap = Allocation.createFromBitmap(mRS, mBitmap);
      mAllocationBitmapTmp = Allocation.createFromBitmap(mRS, mBitmap);
      mSizeStruct.width = width;
      mSizeStruct.height = height;
      // Due to adjusting width into multiple of 4 calculate scale matrix
      // only here
      mMatrixScale.setScale((float) width / mView.getWidth(), (float) height / mView.getHeight());
      mMatrixScale.invert(mMatrixScaleInv);
    }

    // Translate values for off-screen drawing
    // int dx = -(Math.min(0, mView.getLeft()) + mRectVisibleGlobal.left);
    // int dy = -(Math.min(0, mView.getTop()) + mRectVisibleGlobal.top);
    //
    // Replaced dx and dy with View.getLocationInWindow() coordinates
    // because translate was bad for using BlurLinearLayout and
    // BlurRelativeLayout as children for other Views than root View.
    mView.getLocationInWindow(mLocationInWindow);
    // Restore canvas to its original state
    mCanvas.restoreToCount(1);
    mCanvas.setBitmap(mBitmap);
    // Using scale matrix will make draw call to match
    // resized off-screen bitmap size
    mCanvas.setMatrix(mMatrixScale);
    // Off-screen bitmap does not cover the whole screen
    // Use canvas translate to match its position on screen
    mCanvas.translate(-mLocationInWindow[0], -mLocationInWindow[1]);
    // Clip rect is the same as we have
    // TODO: Why does this not work on API 18?
    // mCanvas.clipRect(mRectVisibleGlobal);
    // Save current canvas state
    mCanvas.save();
    // Start drawing from the root view
    mView.getRootView().draw(mCanvas);
  }
  private Bitmap BlurImage(Bitmap input, int radius) {
    RenderScript rsScript = RenderScript.create(getActivity());
    Allocation alloc = Allocation.createFromBitmap(rsScript, input);

    ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rsScript, Element.U8_4(rsScript));
    blur.setRadius(radius);
    blur.setInput(alloc);

    Bitmap result = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
    Allocation outAlloc = Allocation.createFromBitmap(rsScript, result);
    blur.forEach(outAlloc);
    outAlloc.copyTo(result);

    rsScript.destroy();
    return result;
  }
예제 #3
0
  protected boolean prepare() {
    final int width = mBlurredView.getWidth();
    final int height = mBlurredView.getHeight();

    if (mBlurringCanvas == null
        || mDownSampleFactorChanged
        || mBlurredViewWidth != width
        || mBlurredViewHeight != height) {
      mDownSampleFactorChanged = false;

      mBlurredViewWidth = width;
      mBlurredViewHeight = height;

      int scaledWidth = width / mDownSampleFactor;
      int scaledHeight = height / mDownSampleFactor;

      // The following manipulation is to avoid some RenderScript artifacts at the edge.
      scaledWidth = scaledWidth - scaledWidth % 4 + 4;
      scaledHeight = scaledHeight - scaledHeight % 4 + 4;

      if (mBlurredBitmap == null
          || mBlurredBitmap.getWidth() != scaledWidth
          || mBlurredBitmap.getHeight() != scaledHeight) {
        mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
        if (mBitmapToBlur == null) {
          return false;
        }

        mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
        if (mBlurredBitmap == null) {
          return false;
        }
      }

      mBlurringCanvas = new Canvas(mBitmapToBlur);
      mBlurringCanvas.scale(1f / mDownSampleFactor, 1f / mDownSampleFactor);
      mBlurInput =
          Allocation.createFromBitmap(
              mRenderScript,
              mBitmapToBlur,
              Allocation.MipmapControl.MIPMAP_NONE,
              Allocation.USAGE_SCRIPT);
      mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType());
    }
    return true;
  }
예제 #4
0
  public static Bitmap blendRenderScript(RenderScript rs, Bitmap bitmap1, Bitmap bitmap2) {
    if (Build.VERSION.SDK_INT >= 17) {
      final Allocation input1 =
          Allocation.createFromBitmap(
              rs, bitmap1, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
      final Allocation input2 =
          Allocation.createFromBitmap(
              rs, bitmap2, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
      final ScriptIntrinsicBlend blendScript = ScriptIntrinsicBlend.create(rs, Element.U8_4(rs));
      blendScript.forEachAdd(input1, input2);
      input2.copyTo(bitmap1);
      return bitmap1;

    } else {
      throw new IllegalStateException("Renderscript needs sdk >= 17");
    }
  }
예제 #5
0
  @Override
  protected void createFilter(
      android.content.res.Resources res, float scaleFactor, int quality, Allocation in) {
    RenderScript rsCtx = getRenderScriptContext();

    Type.Builder tb_float = new Type.Builder(rsCtx, Element.F32_4(rsCtx));
    tb_float.setX(in.getType().getX());
    tb_float.setY(in.getType().getY());
    mScript = new ScriptC_grad(rsCtx, res, R.raw.grad);
  }
예제 #6
0
  private void runSelectiveAdjust(Allocation in, Allocation out) {
    int width = in.getType().getX();
    int height = in.getType().getY();

    LaunchOptions options = new LaunchOptions();
    int ty;
    options.setX(0, width);

    for (ty = 0; ty < height; ty += STRIP_SIZE) {
      int endy = ty + STRIP_SIZE;
      if (endy > height) {
        endy = height;
      }
      options.setY(ty, endy);
      mScript.forEach_selectiveAdjust(in, out, options);
      if (checkStop()) {
        return;
      }
    }
  }
예제 #7
0
  public static Drawable createBlurredImageFromBitmap(
      Bitmap bitmap, Context context, int inSampleSize) {

    RenderScript rs = RenderScript.create(context);
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = inSampleSize;

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
    byte[] imageInByte = stream.toByteArray();
    ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
    Bitmap blurTemplate = BitmapFactory.decodeStream(bis, null, options);

    final android.support.v8.renderscript.Allocation input =
        android.support.v8.renderscript.Allocation.createFromBitmap(rs, blurTemplate);
    final android.support.v8.renderscript.Allocation output =
        android.support.v8.renderscript.Allocation.createTyped(rs, input.getType());
    final android.support.v8.renderscript.ScriptIntrinsicBlur script =
        android.support.v8.renderscript.ScriptIntrinsicBlur.create(
            rs, android.support.v8.renderscript.Element.U8_4(rs));
    script.setRadius(8f);
    script.setInput(input);
    script.forEach(output);
    output.copyTo(blurTemplate);
    Drawable dr = new BitmapDrawable(blurTemplate);

    return dr;
  }
예제 #8
0
  /** Set blur radius in screen pixels. Value is mapped in range [1, 254]. */
  public void setBlurRadius(int radius) {
    // Map radius into scaled down off-screen bitmap size
    radius = Math.round(radius * BITMAP_SCALE_FACTOR);

    // Setup radius struct
    mRadiusStruct.radius = Math.max(1, Math.min(254, radius));
    mRadiusStruct.div = mRadiusStruct.radius + mRadiusStruct.radius + 1;
    mRadiusStruct.divsum = (mRadiusStruct.div + 1) >> 1;
    mRadiusStruct.divsum *= mRadiusStruct.divsum;

    // Prepare dv allocation
    mAllocationDv = Allocation.createSized(mRS, Element.U8(mRS), 256 * mRadiusStruct.divsum);
    mScriptStackBlur.set_initializeDv_divsum(mRadiusStruct.divsum);
    mScriptStackBlur.forEach_initializeDv(mAllocationDv);
  }
예제 #9
0
  /** Applies blur to current off-screen bitmap */
  public void applyBlur() {
    // Copy current bitmap into allocation
    mAllocationBitmap.copyFrom(mBitmap);

    // Set script variables
    mScriptStackBlur.bind_dv(mAllocationDv);
    mScriptStackBlur.set_bitmap(mAllocationBitmap);
    mScriptStackBlur.set_bitmapTmp(mAllocationBitmapTmp);
    mScriptStackBlur.set_sizeStruct(mSizeStruct);
    mScriptStackBlur.set_radiusStruct(mRadiusStruct);

    // On first step iterate over y = [0, mBitmap.getHeight]
    mLaunchOptions.setX(0, 1);
    mLaunchOptions.setY(0, mBitmap.getHeight());
    mScriptStackBlur.forEach_blurHorizontal(mAllocationBitmap, mLaunchOptions);

    // On second step iterate over x = [0, mBitmap.getWidth]
    mLaunchOptions.setX(0, mBitmap.getWidth());
    mLaunchOptions.setY(0, 1);
    mScriptStackBlur.forEach_blurVertical(mAllocationBitmap, mLaunchOptions);

    // Copy bitmap allocation back to off-screen bitmap
    mAllocationBitmap.copyTo(mBitmap);
  }
예제 #10
0
  private static void blurRenderScript(Bitmap bitmap, float radius) {
    Allocation inAllocation =
        Allocation.createFromBitmap(
            renderScript, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
    Allocation outAllocation = Allocation.createTyped(renderScript, inAllocation.getType());

    blurShader.setRadius(radius);
    blurShader.setInput(inAllocation);
    blurShader.forEach(outAllocation);

    outAllocation.copyTo(bitmap);
  }
예제 #11
0
  public static Bitmap blurBitmap(Bitmap bitmapToBlur, Context context) {
    RenderScript rs = RenderScript.create(context);

    // use this constructor for best performance, because it uses USAGE_SHARED mode which reuses
    // memory
    final Allocation input = Allocation.createFromBitmap(rs, bitmapToBlur);
    final Allocation output = Allocation.createTyped(rs, input.getType());
    final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
    script.setRadius(16f);
    script.setInput(input);
    script.forEach(output);
    output.copyTo(bitmapToBlur);
    return bitmapToBlur;
  }
예제 #12
0
  public static Bitmap apply(Context context, Bitmap sentBitmap, int radius) {
    final Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
    final RenderScript rs = RenderScript.create(context);
    final Allocation input =
        Allocation.createFromBitmap(
            rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
    final Allocation output = Allocation.createTyped(rs, input.getType());
    final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

    script.setRadius(radius);
    script.setInput(input);
    script.forEach(output);
    output.copyTo(bitmap);

    sentBitmap.recycle();
    rs.destroy();
    input.destroy();
    output.destroy();
    script.destroy();

    return bitmap;
  }
예제 #13
0
 protected void blur() {
   mBlurInput.copyFrom(mBitmapToBlur);
   mBlurScript.setInput(mBlurInput);
   mBlurScript.forEach(mBlurOutput);
   mBlurOutput.copyTo(mBlurredBitmap);
 }