首页 文章

通过触摸输入在位图上绘制透明线[复制]

提问于
浏览
4

这个问题在这里已有答案:

我正在开发Android的绘图应用程序 . 现在我想实现一个橡皮擦,允许通过使用触摸输入擦除加载的位图的部分,并使位图沿手指的路径透明 .

Android应用程序Steamy Window中显示了我尝试实现的一个非常好的示例 . Steamy Window模拟雾化窗口,用户可以通过触摸输入擦除部分雾 .

有关我如何实现该功能的任何建议?

更新:我已经在下面发布了我当前代码中最重要的部分 . 由于以下原因,我对它并不满意:

  • 绘画相当迟钝 . 我可以在这里改进什么?

  • 我正在寻找一种方法来使用alpha蒙版来设置像素的像素透明度/ alpha,因为我想模拟画笔 . 有任何建议如何实现这一目标?

public DrawView(Context context, String imageName) {

        super(context);

        // Get the overlay image and its dimensions
        Bitmap overlayImageOriginal = BitmapFactory.decodeResource(
                getResources(), R.drawable.overlay);
        width = overlayImageOriginal.getWidth();
        height = overlayImageOriginal.getHeight();

        // Get a copy of the overlay image and recycle the original
        overlayImage = overlayImageOriginal.copy(Config.ARGB_8888, true);
        overlayImageOriginal.recycle();

        // Get background image of this level
        int resId = getResources().getIdentifier(imageName, "drawable",
                "com.xxx");
        backgroundImage = BitmapFactory.decodeResource(getResources(), resId);

        // Copy pixels
        overlayImagePixels = new int[width * height];
        overlayImage.getPixels(overlayImagePixels, 0, width, 0, 0, width,
                height);

        getHolder().addCallback(this);
        _thread = new DrawThread(getHolder(), this);
        setFocusable(true);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        synchronized (_thread.getSurfaceHolder()) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchStart(event.getX(), event.getY());
                return true;
            case MotionEvent.ACTION_MOVE:
                touchMove(event.getX(), event.getY());
                return true;
            case MotionEvent.ACTION_UP:
                touchStop();
                return true;
            }
            return false;
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
       // draw the image to guess
       canvas.drawBitmap(backgroundImage, 0, 0, null);
       // apply user input to the overlay-image
       setRegionTransparency((int) mTouchX, (int) mTouchY, 20, 0);
       // draw the overlay-image (hiding the image to guess)
       canvas.drawBitmap(overlayImage, 0, 0, null);
    }


    /**
     * 
     * @param posX
     * @param posY
     * @param radius
     * @param alpha - 0: full transparent, 255: full opaque
     */
    private void setRegionTransparency(int posX, int posY, int radius, int alpha) {
        int left = posX - radius;
        int right = posX + radius;
        int top = posY - radius;
        int bottom = posY + radius;
        int color = 0;

        // onDraw() is called before any user input
        // -> assume 0/0 as invalid arguments
        if (posX == 0 && posY == 0) {
              return;
        }

        // TODO currently only rectangular area is supported
        // but we need circular
        // we should use a pre-made alpha mask with smoothed edges
        // we should take into account: pressure and/or duration of touch

        for (int y = top; y = 0 && y = 0 && x = TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mTouchX, mTouchY, (x + mTouchX) / 2, (y + mTouchY) / 2);
            mTouchX = x;
            mTouchY = y;
        }
    }
}

1 回答

相关问题