2011-03-20 19 views
20

Mi idea es superponer 2 imágenes una encima de la otra y, al tocar, la imagen superior debe hacerse transparente en ese radio tocado, exponiendo así la imagen inferior.Asegúrese de que cierto área del mapa de bits sea transparente al tacto

Así es como superponer las 2 imágenes:

 Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig()); 
     Canvas canvas = new Canvas(bmOverlay); 
     canvas.drawBitmap(bmp1, new Matrix(), null); 
     canvas.drawBitmap(bmp2, new Matrix(), null); 

He mirado en this post y tienen una pintura, como a continuación para hacerlo transparente:

 mPaint = new Paint(); 
     mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); 
     mPaint.setColor(Color.TRANSPARENT); 
     mPaint.setAntiAlias(true); 

public void onDraw(Canvas canvas) { 
      canvas.drawCircle(40, 40, 30, mPaint); //hardcode to test 
} 

El problema es que creo que el círculo enseguida haga que las 2 imágenes sean transparentes en el radio definido, ¿cómo puedo hacer que solo el mapa de bits superior sea transparente?

+0

Algo está mal con mi pintura supongo. – SteD

+0

La solución funciona perfectamente en Android 4.x pero en 2.x los círculos son negros en lugar de mostrar la imagen. ¿Alguna idea? – Ixx

Respuesta

36
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.BlurMaskFilter.Blur; 
import android.graphics.BitmapFactory; 
import android.graphics.BlurMaskFilter; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.PorterDuffXfermode; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.View; 

public class StartActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(new TouchView(this)); 


    } 

    class TouchView extends View{ 
     Bitmap bgr; 
     Bitmap overlayDefault; 
     Bitmap overlay; 
     Paint pTouch; 
     int X = -100; 
     int Y = -100; 
     Canvas c2; 

     public TouchView(Context context) { 
      super(context); 

      bgr = BitmapFactory.decodeResource(getResources(),R.drawable.bgr); 
      overlayDefault = BitmapFactory.decodeResource(getResources(),R.drawable.over); 
      overlay = BitmapFactory.decodeResource(getResources(),R.drawable.over).copy(Config.ARGB_8888, true); 
      c2 = new Canvas(overlay); 

      pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);   
      pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); 
      pTouch.setColor(Color.TRANSPARENT); 
      pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL)); 


     } 

     @Override 
     public boolean onTouchEvent(MotionEvent ev) { 

      switch (ev.getAction()) { 

       case MotionEvent.ACTION_DOWN: { 

        X = (int) ev.getX(); 
        Y = (int) ev.getY(); 
        invalidate(); 

        break; 
       } 

       case MotionEvent.ACTION_MOVE: { 

         X = (int) ev.getX(); 
         Y = (int) ev.getY(); 
         invalidate(); 
         break; 

       }   

       case MotionEvent.ACTION_UP: 

        break; 

      } 
      return true; 
     } 


     @Override 
     public void onDraw(Canvas canvas){ 
      super.onDraw(canvas); 

      //draw background 
      canvas.drawBitmap(bgr, 0, 0, null); 
      //copy the default overlay into temporary overlay and punch a hole in it       
      c2.drawBitmap(overlayDefault, 0, 0, null); //exclude this line to show all as you draw 
      c2.drawCircle(X, Y, 80, pTouch); 
      //draw the overlay over the background 
      canvas.drawBitmap(overlay, 0, 0, null); 

     } 


    } 


} 
+0

Intenté hacerlo sin usar un segundo lienzo pero no pude hacer funcionar el modo xfer. Tenga en cuenta que "superposición" es un mapa de bits mutable. – Lumis

+1

¡Gracias por la respuesta, funciona perfectamente! – SteD

+1

De nada. Fue un problema interesante y me sorprendió que no fuera tan fácil como inicialmente pensé. Parece que los modos xfer funcionan como se espera con un lienzo derivado de un mapa de bits, pero no con el lienzo que pertenece a una Vista. Es por eso que utilicé c2 – Lumis

0

¡Heh, tienes la respuesta justo dentro de tu publicación!

tratar Básicamente algo como:

public void onDraw(Canvas canvas) {  
    if (myPaintFlag) { 
     canvas.drawBitmap(bmp1, new Matrix(), null); 
     canvas.drawBitmap(bmp2, new Matrix(), mPaint); 
    } 
    else { 
     canvas.drawBitmap(bmp1, new Matrix(), mPaint); 
     canvas.drawBitmap(bmp2, new Matrix(), null); 
    } 
} 
+0

Intenté usar mPaint para dibujar el mapa de bits, pero hará que toda la pantalla se convierta en color negro. ¿Supongo que está haciendo que todo el mapa de bits sea transparente de esta manera? – SteD

+0

Eso podría ser. Intenta cambiar el orden de dibujo. – user432209

Cuestiones relacionadas