2014-12-17 25 views
14

flood-fill sınıfımı uygularken, tüm Bitmap siyahım döner. Açıkçası bu istenen etki değildir. Aşağıdaki parçacığı baktım:Android - Tuval Flood Doldur kullanırken

, Ancak sorunumu çözmem için bana bir çözüm getirmedi. Bu yüzden kovalamayı kesmek için, bazı kısa açıklamaları içeren kod. Doğrudan birbirinin üstüne

bir göreli düzen kullanılarak ve konumlandırma (istifleme) am
XML iki ImageViews. İkisi de aynı görüntüye sahipler ve bu, görüntü üzerinde çizebilmenizin yanılsamasını yaratıyor. Bununla birlikte, aslında sadece şeffaf bir kaplama üzerinde çizim yapıyorsunuz.

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

Tuval Sonra oluşturmak benim bu kodla Canvas ve eğer doğru benim katman türlerini ayarlamak için emin olun.

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

Sel-Dolgu Uygulaması
benim canvas yeni bitmap çizmek nihayet bitmap dönmek flood-fill yöntemi kullanmak, flood-fill nesneye benim params geçmesi ve renk kapmak.

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(); 

Sel-Dolgu Sınıf
kazan plaka Flood-fill algoritması.

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

İşte bu, bulmacanın tüm parçalarına sahip olmalıyız, ancak bazı nedenlerle çalışmıyorlar. Kaybettim ve herhangi bir yardım takdir edilir. Teşekkürler!

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

fazla gibi

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

cevap

0

Sana çizgi olduğunu düşünüyorum çözümleri:

İlk: birisi olarak : yerine decodeFile kullanmanın doğrusu İkinci decodeInputStream kullanmak anonim gördünüz Görünüm Üçüncü: gösteriliyorken bir Paint() kullanmanız daha iyi olur. Neden bu gıda dolgu algoritmasına ihtiyacınız var diye soracağım? Bence bu çok laggy ve kullanmak için biraz dağınık görünüyor, neden yeni ölçekli bir bitmap veya yapmak için bir opengl etkisi gibi bir şey yaratmıyorsun? çünkü grafik kartlarının olmasının nedeni budur;

0

Ben her şeye emin değilim ama bildiğim kadarıyla söyleyebilirim olarak Bunlarla çalışacaktı olması gerekebilir: