2013-06-25 31 views
0

在我的实现中,我有两个图像,一个放在另一个上面。因为我在顶部图像上移动了一个圆形对象,我想将该区域放在圆形的透明区域内,以便我可以看到底部图像。例如,我有两个图像 - 一个汽车图像和它的框架图像。我将车图覆盖在framweork图像上,当我在车图上拖动一个圆时,它应该显示下面的框架。通过在图像上拖动一个圆形在图像下制作

我试图搜索很多,但没有得到任何指针。在某处我读到我需要使用alpha遮罩或使用porterduff和xfermode进行图像遮罩。但我不明白。

具体来说,

我怎样才能使上面的图像透明单位,我怎么只能打一圈透明单位内的区域?

谢谢

回答

0

我已经从这个问题PorterduffXfermode: Clear a section of a bitmap使用的有帮助的投入。在下面的示例中,触摸区域变为“透明”,并且可以在up_image之下观察down_image部分(这两个图像都只是资源中的jpg drawable)。

基本上有两种可能的实现:

  1. 禁用附图的硬件加速这将使PorterDuff.Mode.CLEAR使视图透明(参照here对于有关硬件加速效果的更多细节):

    活性:

    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; 
        } 
    } 
    
  2. 采用这种solution,不过貌似这取决于Android版本,因为建议的解决方案并没有对我的4.2设备工作在所有。