通过触摸输入在位图上绘制透明线
我正在开发 Android 的绘图应用程序。现在我想实现一个橡皮擦,以允许通过使用触摸输入来擦除加载的位图的一部分,并使位图沿着手指的路径透明。
应用程序 Steamy 窗口(适用于 Android)。 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; } } }
I am working on a paint application for Android. Now I want to implement an eraser to allow erasing parts of a loaded bitmap by using touch input and making the bitmap transparent along the finger's path.
A very good example of what I try to achieve is shown in the application Steamy Window for Android. Steamy Window simulates a fogged window, where a user can wipe parts of the fog via touch input.
Any suggestions how I could implement the feature?
UPDATE: I have posted the most important sections of my current code below. I am not really happy with it for the following reasons:
Drawing is quite sluggish. What can I improve here?
I am looking for a way to use an alpha mask in order to set the pixel transparency/alpha of the pixels as I want to simulate a paint brush. Any suggestions how this could be achieved?
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; } } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
查看
在 Android 中使重叠图像在触摸时透明?
Take a look at
Making Overlaid image transparent on touch in Android?