2010-07-23 5 views
4

Je travaille sur une application de peinture pour Android. Maintenant, je veux implémenter une gomme pour permettre d'effacer des parties d'un bitmap chargé en utilisant l'entrée tactile et en rendant le bitmap transparent le long du chemin du doigt.Dessiner des lignes transparentes sur bitmap via l'entrée tactile

Un très bon exemple de ce que j'essaye de réaliser est montré dans l'application Steamy Window pour Android. Steamy Window simule une fenêtre embuée, où un utilisateur peut essuyer des parties du brouillard via l'entrée tactile.

Des suggestions comment je pourrais mettre en œuvre la fonctionnalité?

MISE À JOUR: J'ai posté ci-dessous les sections les plus importantes de mon code actuel. Je ne suis pas vraiment heureux avec lui pour les raisons suivantes:

  1. Le dessin est assez léthargique. Que puis-je améliorer ici?

  2. Je cherche un moyen d'utiliser un masque alpha afin de définir la transparence/alpha des pixels que je veux simuler un pinceau. Des suggestions comment cela pourrait-il être réalisé?

 
     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; 
     } 
    } 
} 


+0

Qu'est-ce que l'arrière-plan censé ressembler? Ce que vous pouvez faire est de dessiner l'arrière-plan sur le dessus du premier plan aux endroits nécessaires. – Maz

+0

avez-vous essayé d'ajouter une alpha avec la méthode onDraw? vous obtenez la couleur du pixel, et vous changez son alpha quelque part entre 00 et FF? – Sephy

+0

Je prévois d'utiliser deux bitmaps: un comme premier plan et un comme arrière-plan. Des parties du bitmap de superposition sont supposées être "effacées" tout en dessinant, c'est-à-dire que la valeur alpha des pixels du bitmap de superposition est modifiée. – Philipp

Répondre

Questions connexes