2014-12-17 15 views
14

Quando si implementa la classe flood-fill, il mio intero Bitmap diventa nero. Ovviamente questo non è l'effetto desiderato. Ho guardato i seguenti thread:Android - Tela nera quando si utilizza Flood-Fill

Da quello che posso vedere che sto facendo tutto quello che è venuta in mente a quelle soluzioni, tuttavia non mi ha portato a una soluzione per il mio problema. Quindi, per andare al sodo, ecco il codice con alcune brevi spiegazioni.

XML
sto usando un layout relativa e posizionamento (impilabile) due ImageViews direttamente sopra l'altro. Entrambi hanno la stessa immagine e questo crea l'illusione di essere in grado di disegnare sull'immagine. Tuttavia, stai semplicemente disegnando su una sovrapposizione trasparente.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

    .... 

    <ImageView 
     android:id="@+id/drawContainer2" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_toRightOf="@id/imageMapperSurfaces" 
     android:contentDescription="@string/image" /> 

    <ImageView 
     android:id="@+id/drawContainer" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_toRightOf="@id/imageMapperSurfaces" 
     android:contentDescription="@string/image" /> 

    ... 
</RelativeLayout> 

Tela
Poi Creo il mio Canvas con questo codice e faccio in modo di impostare correttamente i miei tipi di livello.

public void setCanvas() { 
    if(mFile != null && mFile.exists()) { 
     mPictureBitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); 
     mBitmap = Bitmap.createScaledBitmap(mPictureBitmap, mImageView.getWidth(), mImageView.getHeight(), false); 
     mPictureBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true); 
     mBitmap = mPictureBitmap.copy(Bitmap.Config.ARGB_8888, true); 
     mSceneBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true); 
     mBlurBitmap = blurImage(mPictureBitmap); 
     mCanvas = new Canvas(mBitmap); 
     mImageView.setImageBitmap(mBitmap); 
     mImageView2.setImageBitmap(mPictureBitmap); 
     mBlur.setImageBitmap(mBlurBitmap); 

     // failure to set these layer types correctly will result in a black canvas after drawing. 
     mImageView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
     mImageView2.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
     mImageView.bringToFront(); 
     mAllowedToDraw = true; 

     setImageViewOnTouch(); 
    } 
} 

Flood-Fill Attuazione
Afferro il colore, passare i miei params all'oggetto flood-fill, utilizzare il metodo flood-fill, restituire il bitmap, e infine disegnare la nuova bitmap alla mia canvas.

int targetColor = mSceneBitmap.getPixel((int) event.getX(), (int) event.getY()); 
FloodFill fill = new FloodFill(mBitmap, targetColor, Color.argb(100, 255, 0, 0)); 
fill.floodFill((int) event.getX(), (int) event.getY()); 
Bitmap bmp = fill.getImage(); 
mCanvas.drawBitmap(bmp, 0, 0, null); 
mImageView.invalidate(); 

Flood-Fill Classe
La caldaia-piastra Flood-fill algoritmo.

public class FloodFill { 
    protected Bitmap mImage = null; 
    protected int[] mTolerance = new int[] { 0, 0, 0, 0 }; 
    protected int mWidth = 0; 
    protected int mHeight = 0; 
    protected int[] mPixels = null; 
    protected int mFillColor = 0; 
    protected int[] mStartColor = new int[] { 0, 0, 0, 0 }; 
    protected boolean[] mPixelsChecked; 
    protected Queue<FloodFillRange> mRanges; 

    public FloodFill(Bitmap img) { 
     copyImage(img); 
    } 

    public FloodFill(Bitmap img, int targetColor, int newColor) { 
     useImage(img); 

     setFillColor(newColor); 
     setTargetColor(targetColor); 
    } 

    public void setTargetColor(int targetColor) { 
     mStartColor[0] = Color.red(targetColor); 
     Log.v("Red", "" + mStartColor[0]); 
     mStartColor[1] = Color.green(targetColor); 
     Log.v("Green", "" + mStartColor[1]); 
     mStartColor[2] = Color.blue(targetColor); 
     Log.v("Blue", "" + mStartColor[2]); 
     mStartColor[3] = Color.alpha(targetColor); 
     Log.v("Alpha", "" + mStartColor[3]); 
    } 

    public int getFillColor() { 
     return mFillColor; 
    } 

    public void setFillColor(int value) { 
     mFillColor = value; 
    } 

    public int[] getTolerance() { 
     return mTolerance; 
    } 

    public void setTolerance(int[] value) { 
     mTolerance = value; 
    } 

    public void setTolerance(int value) { 
     mTolerance = new int[] { value, value, value, value }; 
    } 

    public Bitmap getImage() { 
     return mImage; 
    } 

    public void copyImage(Bitmap img) { 
     mWidth = img.getWidth(); 
     mHeight = img.getHeight(); 

     mImage = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(mImage); 
     canvas.drawBitmap(img, 0, 0, null); 

     mPixels = new int[mWidth * mHeight]; 

     mImage.getPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight); 
    } 

    public void useImage(Bitmap img) { 
     mWidth = img.getWidth(); 
     mHeight = img.getHeight(); 
     mImage = img; 

     mPixels = new int[mWidth * mHeight]; 

     mImage.getPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight); 
    } 

    protected void prepare() { 
     mPixelsChecked = new boolean[mPixels.length]; 
     mRanges = new LinkedList<FloodFillRange>(); 
    } 

    public void floodFill(int x, int y) { 
     // Setup 
     prepare(); 

     if (mStartColor[0] == 0) { 
      // ***Get starting color. 
      int startPixel = mPixels[(mWidth * y) + x]; 
      mStartColor[0] = (startPixel >> 16) & 0xff; 
      mStartColor[1] = (startPixel >> 8) & 0xff; 
      mStartColor[2] = startPixel & 0xff; 
     } 

     LinearFill(x, y); 
     FloodFillRange range; 

     while (mRanges.size() > 0) { 
      range = mRanges.remove(); 
      int downPxIdx = (mWidth * (range.Y + 1)) + range.startX; 
      int upPxIdx = (mWidth * (range.Y - 1)) + range.startX; 
      int upY = range.Y - 1; 
      int downY = range.Y + 1; 

      for (int i = range.startX; i <= range.endX; i++) { 
       if (range.Y > 0 && (!mPixelsChecked[upPxIdx]) && CheckPixel(upPxIdx)) LinearFill(i, upY); 
       if (range.Y < (mHeight - 1) && (!mPixelsChecked[downPxIdx]) && CheckPixel(downPxIdx)) LinearFill(i, downY); 
       downPxIdx++; 
       upPxIdx++; 
      } 
     } 

     mImage.setPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight); 
    } 

    protected void LinearFill(int x, int y) { 
     int lFillLoc = x; 
     int pxIdx = (mWidth * y) + x; 

     while (true) { 
      mPixels[pxIdx] = mFillColor; 
      mPixelsChecked[pxIdx] = true; 
      lFillLoc--; 
      pxIdx--; 

      if (lFillLoc < 0 || (mPixelsChecked[pxIdx]) || !CheckPixel(pxIdx)) { 
       break; 
      } 
     } 

     lFillLoc++; 
     int rFillLoc = x; 

     pxIdx = (mWidth * y) + x; 

     while (true) { 
      mPixels[pxIdx] = mFillColor; 
      mPixelsChecked[pxIdx] = true; 

      rFillLoc++; 
      pxIdx++; 

      if (rFillLoc >= mWidth || mPixelsChecked[pxIdx] || !CheckPixel(pxIdx)) { 
       break; 
      } 
     } 

     rFillLoc--; 

     FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y); 

     mRanges.offer(r); 
    } 

    protected boolean CheckPixel(int px) { 
     int red = (mPixels[px] >>> 16) & 0xff; 
     int green = (mPixels[px] >>> 8) & 0xff; 
     int blue = mPixels[px] & 0xff; 
     int alpha = (Color.alpha(mPixels[px])); 

     return (red >= (mStartColor[0] - mTolerance[0]) && red <= (mStartColor[0] + mTolerance[0]) 
       && green >= (mStartColor[1] - mTolerance[1]) && green <= (mStartColor[1] + mTolerance[1]) 
       && blue >= (mStartColor[2] - mTolerance[2]) && blue <= (mStartColor[2] + mTolerance[2]) 
       && alpha >= (mStartColor[3] - mTolerance[3]) && alpha <= (mStartColor[3] + mTolerance[3])); 
    } 

    protected class FloodFillRange { 
     public int startX; 
     public int endX; 
     public int Y; 

     public FloodFillRange(int startX, int endX, int y) { 
      this.startX = startX; 
      this.endX = endX; 
      this.Y = y; 
     } 
    } 
} 

Quindi è tutto, dovremmo avere tutti i pezzi del puzzle ma per qualche motivo non stanno funzionando. Sono in perdita e ogni aiuto è apprezzato. Grazie!

risposta

0

Penso che tu sia la linea:

mCanvas.drawBitmap(bmp, 0, 0, null); 

potrebbe aver bisogno di essere più come

mPaint = new Paint();  
mCanvas.drawBitmap(bmp, 0, 0, mPaint); 
0

io non sono sicuro che a tutto, ma per quanto ne posso dire vorrei provare con questi soluzioni:

Prime: invece di utilizzare decodeFile io invece uso decodeInputStream secondo: Come qualcuno ha più problemi È meglio usare un Paint() quando si mostra la vista Terzo: Ho intenzione di chiedere perché hai bisogno di quell'algoritmo di cibo? Penso che sia troppo lento e sembra un po 'disordinato da usare, perché non creare una nuova bitmap in scala o qualcosa di simile a un effetto opengl per farlo? perché questo è il motivo per cui ci sono le schede grafiche;

Problemi correlati