问题描述
在我的实现,我有两个图像,一是奠定了对方。正如,我动了一圈对象,可在最上面的图片,我想打圆圈transperent内的区域,这样我就可以看到下面的图像。比如我有两个图像 - 一辆汽车的图像和框架的形象。我覆盖汽车形象在framweork形象,为我拖累了一圈过车的形象,应该显示下框架。
In my implementation, I have two images, one layed over the other. As, I move a circle object over the top image, I want to make that area inside circle transperent, so that I can see the beneath image. For example I have two images - a car image and its framework image. I overlay car image over framweork image and as i drag a circle over car image, it should show the beneath framework.
我试着搜索了很多,但没有得到任何指针。某处我读,我需要使用porterduff和xfermode使用阿尔法蒙或图像屏蔽。但我不明白。
I tried to search a lot but not getting any pointers. Somewhere I read that I need to use alpha masking or image masking using porterduff and xfermode. but I did not understand.
具体而言,
我怎样才能让上面的图片transperent,我怎么只能打圆圈transperent内的区域?
How can I make the above image transperent and how can I only make the area inside circle transperent?
感谢您
推荐答案
我已经用有用的投入问题PorterduffXfermode:清除位图的一个部分。在下面的例子中,接触面积变透明,它是可以观察到 down_image
下 up_image
部分(包括图像在资源只是JPG可绘制)。
I've used helpful inputs from the question PorterduffXfermode: Clear a section of a bitmap. In the example below, touch area becomes 'transparent' and it's possible to observe down_image
part beneath up_image
(both images are just jpg drawables in resources).
基本上有两种可能的实现方式:
Basically there's two possible implementations:
-
禁用绘图硬件加速这将使
PorterDuff.Mode.CLEAR
使视图透明的(指的了解更多详细的硬件加速效果):
Disabling hardware acceleration of drawing which would make
PorterDuff.Mode.CLEAR
to make view transparent (refer to here for more details about hardware acceleration effects):
活动:
public class MyActivity extends Activity {
/** Overlay image */
private DrawingView mDrawingView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
// Create the view for the xfermode test
mDrawingView = new DrawingView(this);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
mDrawingView.setLayoutParams(params);
final RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.setBackgroundResource(R.drawable.down_image);
relativeLayout.addView(mDrawingView);
// Main part of the implementation - make layer drawing software
if (android.os.Build.VERSION.SDK_INT >= 11) {
mDrawingView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
// Show the layout with the test view
setContentView(relativeLayout);
}
}
DrawingView:
/**
* View which makes touch area transparent
*/
public class DrawingView extends View {
/** Paint to clear touch area */
private Paint mClearPaint = null;
/** Main bitmap */
private Bitmap mBitmap = null;
/** X coordinate of touch circle */
private int mXTouch = -1;
/** Y coordinate of touch circle */
private int mYTouch = -1;
/** Radius of touch circle */
private int mRadius = 0;
/**
* Default constructor
*
* @param ct {@link Context}
*/
public DrawingView(final Context ct) {
super(ct);
// Generate bitmap used for background
mBitmap = BitmapFactory.decodeResource(ct.getResources(), R.drawable.up_image);
// Generate array of paints
mClearPaint = new Paint();
mClearPaint.setARGB(255, 255, 255, 0);
mClearPaint.setStrokeWidth(20);
mClearPaint.setStyle(Paint.Style.FILL);
// Set all transfer modes
mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mRadius = getResources().getDimensionPixelSize(R.dimen.radius);
}
@Override
public void onDraw(final Canvas canv) {
// Background colour for canvas
canv.drawColor(Color.argb(255, 0, 0, 0));
// Draw the bitmap leaving small outside border to see background
canv.drawBitmap(mBitmap, null, new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()), null);
// Loop, draws 4 circles per row, in 4 rows on top of bitmap
// Drawn in the order of mClearPaint (alphabetical)
if (mXTouch > 0 && mYTouch > 0) {
canv.drawCircle(mXTouch, mYTouch, mRadius, mClearPaint);
}
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
boolean handled = false;
// get touch event coordinates and make transparent circle from it
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
mXTouch = (int) event.getX();
mYTouch = (int) event.getY();
// TODO: Note, in case of large scene it's better not to use invalidate without rectangle specified
invalidate();
handled = true;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
mXTouch = -1;
mYTouch = -1;
// TODO: Note, in case of large scene it's better not to use invalidate without rectangle specified
invalidate();
handled = true;
break;
default:
// do nothing
break;
}
return super.onTouchEvent(event) || handled;
}
}
采用这种solution,不过貌似这取决于Android版本,因为建议的解决方案还没有工作的我的4.2设备都没有。
Adopt this solution, but looks like it depends on Android version, because suggested solution hasn't worked on mine 4.2 device at all.
这篇关于在Android的拖动一个圆圈在它使图像的下方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!