在android中的imageview画布上绘制透明线

时间:2015-02-02 10:33:12

标签: android canvas android-canvas android-drawable android-bitmap

问题是,我尝试将不透明度更改为100,这应该是透明的,但是当我尝试绘制线条时,它在线条上有一些圆圈。 (参见截图)非常感谢如果提供一些示例代码。非常感谢您的帮助。

MainActivity的代码

// set image
bitmap = downScale(view.getTag().toString(),1280,1024);
altered_bitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), bitmap.getConfig());
draw_view.setNewImage(altered_bitmap,bitmap);

  pen.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View arg0) {
                    draw_view.setAlpha(100);
                }
            }
        });

来自自定义imageView的代码

public ScaleImageView(Context context) {
        super(context);
        sharedConstructing(context);
    }

public void sharedConstructing(Context context) {
        super.setClickable(true);
        this.context = context;

        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
        matrix = new Matrix();
        m = new float[9];
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);

        paint = new Paint();

        paint.setAntiAlias(true);
        paint.setStrokeWidth(width);
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setAlpha(alpha);


        drawListener = new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (getDrawable() != null) {
                    int action = event.getAction();
                    switch (action) {
                        case MotionEvent.ACTION_DOWN:
                            downx = getPointerCoords(event)[0];// event.getX();
                            downy = getPointerCoords(event)[1];// event.getY();
                            break;
                        case MotionEvent.ACTION_MOVE:
                            upx = getPointerCoords(event)[0];// event.getX();
                            upy = getPointerCoords(event)[1];// event.getY();
                            canvas.drawLine(downx, downy, upx, upy, paint);
                            mPath = new Path();
                            paths.add(mPath);
                            invalidate();
                            downx = upx;
                            downy = upy;
                            break;
                        case MotionEvent.ACTION_UP:
                            upx = getPointerCoords(event)[0];// event.getX();
                            upy = getPointerCoords(event)[1];// event.getY();
                            canvas.drawLine(downx, downy, upx, upy, paint);
                            mPath = new Path();
                            paths.add(mPath);
                            invalidate();
                            break;
                        case MotionEvent.ACTION_CANCEL:
                            break;
                        default:
                            break;
                    }
                }
                return true;
            }
        };

        setOnTouchListener(drawListener);
    }

    //draw view start
    public void setNewImage(Bitmap alteredBitmap, Bitmap bmp) {
        canvas = new Canvas(alteredBitmap);
        matrix_draw = new Matrix();
        canvas.drawBitmap(bmp, matrix_draw, paint);
        setImageBitmap(alteredBitmap);  
        mPath = new Path();
        paths.add(mPath);
    }

    public void setBrushColor(int color) {
        this.color = color;
        paint.setColor(color);
        paint.setAlpha(alpha);
    }

    public void setAlpha(int alpha) {
        this.alpha = alpha;
        paint.setAlpha(alpha);
    }

    public void setWidth(float width) {
        this.width = width;
        paint.setStrokeWidth(width);
    }

    final float[] getPointerCoords(MotionEvent e) {
        final int index = e.getActionIndex();
        final float[] coords = new float[] { e.getX(index), e.getY(index) };
        Matrix matrix = new Matrix();
        getImageMatrix().invert(matrix);
        matrix.postTranslate(getScrollX(), getScrollY());
        matrix.mapPoints(coords);
        return coords;
    }

    public void setIsScale() {
        isScale = !isScale;
        setOnTouchListener(isScale ? zoomListener : drawListener);
    }

截图

enter image description here

更新:项目代码

由于通过代码提取很难找出问题所以我已经将项目(< 1 mb)与使用过的库一起上传:

如果你有空闲时间,欢迎你来看看 它是一个小型绘图工具,首先将带有一些图像的文件夹复制到设备中的“HistoryTool”文件夹

路径,例如:

sd card root/ HistoryTool/ folder1 / a.jpg 

,然后你可以在上面绘制,但绘制透明线上有圆圈。多数民众赞成

https://drive.google.com/file/d/0B9mELZtUJp0LZncwQVM4alExalE/view?usp=sharing

4 个答案:

答案 0 :(得分:1)

所以,你的问题就是圈子。这来自链条的每个新段,它们被单独绘制,每个端点与先前绘制的链段重叠。您希望在调用stroke();之前绘制线条的路径。这将绘制整个线段链而不是单独绘制,并防止这些圆形重叠。

你可以做的是这样的:创建一个一次性绘制线条的线链类:

/* Feed the line chain an array of points to draw when you construct it. */
/* points_=[{"x":0,"y":0},{"x":10,"y":10}]; */
function LineChain(points_){
    this.points=points_;
}

LineChain.prototype={
    constructor:LineChain,
    /* Draws this line chain to the specified context. */
    drawTo:function(context_){
        /* Get the first point in the chain. */
        var point=this.points[0];
        /* Start the path by moving to the first position on the chain. */
        context_.beginPath();
        context_.moveTo(point.x,point.y);
        /* Loop through the remaining points in the chain and draw the rest of the path. */
        for (var index=1;index<this.points.length-1;index++){
            point=this.points[index];
            context_.lineTo(point.x,point.y);
        }
    }
}

现在,当您真正想要将链条绘制到画布时,只需执行以下操作:

/* Define a line chain. */
var line_chain=new LineChain([{"x":0,"y":0},{"x":10,"y":20},{"x":30,"y":40}]);

/* Wherever you're drawing at... */
context.strokeStyle="rgba(255,0,0,0.5)";
context.lineWidth=20;
line_chain.drawTo(context);
context.stroke();

基本上,如何实现此技术并不重要,您唯一需要做的就是确保在调用stroke函数之前绘制整个路径。

答案 1 :(得分:0)

来自文档Paint.setAlpha(int)

  

设置颜色的alpha组件[0..255]。

表示0是透明的,255是完全不透明的。 100你只是设置在中间的东西。

答案 2 :(得分:0)

我使用On-draw和Path

完成了任务
        drawListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (getDrawable() != null) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        downx = getPointerCoords(event)[0];// event.getX();
                        downy = getPointerCoords(event)[1];// event.getY();
                        holderList.add(new Holder(color, width, alpha));
                        holderList.get(holderList.size() - 1).path.moveTo(downx, downy);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        upx = getPointerCoords(event)[0];// event.getX();
                        upy = getPointerCoords(event)[1];// event.getY();
                        holderList.get(holderList.size() - 1).path.lineTo(upx, upy);
                        invalidate();
                        downx = upx;
                        downy = upy;
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        break;
                    default:
                        break;
                }
            }
            return true;
        }
    };

    setOnTouchListener(drawListener);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (img != null) {
        tmp_canvas.drawBitmap(img, 0, 0, null);
    }
    for (Holder holder : holderList) {
        tmp_canvas.drawPath(holder.path, holder.paint);
    }
}

//draw view start
public void setNewImage(Bitmap alteredBitmap, Bitmap bmp) {
    tmp_canvas = new Canvas(alteredBitmap);
    img = bmp;
    tmp_canvas.drawBitmap(bmp, 0, 0, null);
    setImageBitmap(alteredBitmap);
}

答案 3 :(得分:0)

请参考可帮助您解决此问题的 BlendMode。 期望:如果我们甚至在其自身上绘制相同的笔划,则不应过度绘制并降低透明度。

请参考以下链接。

https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/BlendMode

https://medium.com/mobile-app-development-publication/practical-image-porterduff-mode-usage-in-android-3b4b5d2e8f5f