Рисование растрового изображения по кругу и заливка за пределами цветного холста не работает - PullRequest
0 голосов
/ 23 мая 2018

Я хочу нарисовать изображение внутри круга с растровым изображением и залить цвет снаружи.

Я расширил AppCompatImageView и переопределил метод onDraw, но он отображает белый круг внутри холста.

мой класс:

class ImageMagnifier2 extends AppCompatImageView {

public ImageMagnifier2(final Context context) {
    super(context);
    init();
}

@Override
public boolean dispatchTouchEvent(MotionEvent me) {
    // Call onTouchEvent of SimpleGestureFilterLongPress class
    return super.dispatchTouchEvent(me);
}

private void init() {
    setWillNotDraw(false);
    setLayerType(LAYER_TYPE_HARDWARE, null);

    zoomPos = new PointF(0, 0);
    matrix = new Matrix();
    paint = new Paint();
    paintBackground = new Paint();
    paint.setColor(getResources().getColor(android.R.color.transparent));
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (!zooming) {
        buildDrawingCache();
    } else {
        bitmap = getDrawingCache();
        shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        matrix.reset();
        matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
        paint.getShader().setLocalMatrix(matrix);

        paintBackground.setColor(Color.parseColor("#F227aae0"));//F227aae0
        paintBackground.setStyle(Paint.Style.FILL);
        paintBackground.setAntiAlias(true);

        Rect rectangle = new Rect( 0, 0, canvas.getWidth(), canvas.getHeight()   );
        canvas.drawRect(rectangle,paintBackground);
        canvas.drawCircle(zoomPos.x, zoomPos.y, sizeOfMagnifier - 5, paint);
    }
   }

Хорошо работает, когда рисует растровое изображение без внешнего прямоугольника или цвета заливки холста.но мне нужно заполнить внешний цвет растровым изображением.

Спасибо за помощь заранее.

1 Ответ

0 голосов
/ 29 мая 2018

Ниже приведен код, который я написал ранее, когда у меня были те же проблемы. Вы можете использовать следующий класс:

public class CircleImageView extends AppCompatImageView {
    private RectF drawableRect = new RectF();
    private Matrix shaderMatrix = new Matrix();
    private Paint bmpPaint = new Paint();
    private Paint backgroundPaint = new Paint();
    private Bitmap bmp;
    private int bmpWidth, bmpHeight;
    private BitmapShader bmpShader;
    private float radius;


    public CircleImageView(Context context) {
        super(context);
        setScaleType(ScaleType.CENTER_CROP);
        backgroundPaint.setStyle(Paint.Style.FILL);
        backgroundPaint.setColor(Color.TRANSPARENT);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (bmp == null) return;
        canvas.drawPaint(backgroundPaint);
        canvas.drawCircle(drawableRect.centerX(), drawableRect.centerY(), radius, bmpPaint);
    }



    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) return null;
        if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
        try {
            Bitmap bitmap;
            if (drawable instanceof ColorDrawable) bitmap = Bitmap.createBitmap(5, 5, Bitmap.Config.ARGB_8888);
                         else bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private void initImage() {
        bmp = getBitmapFromDrawable(getDrawable());
        init();
    }

    private void init() {
        if (getWidth() == 0 && getHeight() == 0) return;
        if (bmp == null) {invalidate();return;}

        bmpShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        bmpPaint.setAntiAlias(true);
        bmpPaint.setShader(bmpShader);
        bmpHeight = bmp.getHeight();
        bmpWidth = bmp.getWidth();
        drawableRect.set(new RectF(0,0,getWidth(),getHeight()));
        radius = Math.min(drawableRect.height() / 2.0f, drawableRect.width() / 2.0f);
        updateMatrix();
        invalidate();
    }


    private void updateMatrix() {
        float scale;
        float dx = 0;
        float dy = 0;
        shaderMatrix.set(null);
        if (bmpWidth * drawableRect.height() > drawableRect.width() * bmpHeight) {
            scale = drawableRect.height() / (float) bmpHeight;
            dx = (drawableRect.width() - bmpWidth * scale) * 0.5f;
        } else {
            scale = drawableRect.width() / (float) bmpWidth;
            dy = (drawableRect.height() - bmpHeight * scale) * 0.5f;
        }

        shaderMatrix.setScale(scale, scale);
        shaderMatrix.postTranslate((int) (dx + 0.5f) + drawableRect.left, (int) (dy + 0.5f) + drawableRect.top);
        bmpShader.setLocalMatrix(shaderMatrix);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        init();
    }

    public void setBackgroundColor(@ColorInt int backgroundColor) {
        backgroundPaint.setColor(backgroundColor);
        invalidate();
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        initImage();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        initImage();
    }

    @Override
    public void setImageResource(@DrawableRes int resId) {
        super.setImageResource(resId);
        initImage();
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        initImage();
    }

    /* if this answer solved your problem please mark it as accepted by clicking the check mark next to the answer. Thank you */
}
...