Canvas with PorterDuffXfermode DST_IN not working

0

I am trying to develop Instagram tilt shift function for my apps.

I have two Bitmaps and one Paint. The first one is the empty bitmap. The second one is blurred image bitmap. The third one is an image with white background with transparent circle.

I created an empty bitmap with Canvas and drawn blurred image on the Canvas, then I drawn the third paint on that Canvas with DST_IN. What I expect is the transparent area be replaced by clear image and white background will be replaced by blur image.

Thanks for your help. My code is shown below

Bitmap emptyBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(emptyBmp);

//Convert original bmp to blurBmp
Bitmap blurBmp = fastblur(mContext, bmp, 8);
canvas.drawBitmap(blurBmp, 0, 0, null);

//Draw white background with transparent circle
Paint p = drawPaint(fTiltX, fTiltY, fTiltRadius, emptyBmp);
canvas.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), p);

emptyBmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
emptyBmp.recycle();
blurBmp.recycle();
bmp.recycle();
OutputStream outputStream = null;

FastBlur

public Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {
      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);
      return bitmap;
}

DrawPaint

public Paint drawPaint(float tiltX, float tiltY, float tiltRadius, Bitmap bmp) {
        Paint paint = new Paint();
        float tiltGradientRadius = tiltRadius / 2.0f;
        double bitmapResizedRatio = 1;

        int colors[] = new int[4];
        colors[0] = 0x00ffffff;
        colors[1] = 0x00ffffff;
        colors[2] = 0xffffffff;
        colors[3] = 0xffffffff;

        float tiltRadius1;
        tiltRadius1 = tiltRadius - tiltGradientRadius;
        tiltRadius1 = Math.min(tiltRadius1, bmp.getWidth());
        tiltRadius1 = Math.max(tiltRadius1, 0.0f);
        float tiltRadius2 = tiltRadius;
        tiltRadius2 = Math.min(tiltRadius2, bmp.getWidth());
        tiltRadius2 = Math.max(tiltRadius2, 0.0f);

        float positions[] = new float[4];
        positions[0] = 0.0f;
        positions[1] = tiltRadius1 / tiltRadius;
        positions[2] = tiltRadius2 / tiltRadius;
        positions[3] = 1.0f;

        float shaderTiltX = (float) (tiltX / bitmapResizedRatio);
        float shaderTiltY = (float) (tiltY / bitmapResizedRatio);
        float shaderTiltRadius = (float) (tiltRadius / bitmapResizedRatio);

        RadialGradient shader = new RadialGradient(shaderTiltX, shaderTiltY, shaderTiltRadius, colors, positions, TileMode.CLAMP);
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        //shiftCanvas.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paint);
        return paint;
    }

This is what I expected. The image is blur around the transparent circle: This is what I expected. The image is blur around the transparent circle.

This is my apps. The image is blur around the black circle. The circle should be transparent (Please ignore the blue circle): This is my apps. The image is blur around the black circle. The circle should be transparent

java
android
porter-duff
asked on Stack Overflow Apr 4, 2020 by Dennis • edited Apr 5, 2020 by Dennis

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0