2014-12-17 2 views
14

का उपयोग करते समय कैनवास ब्लैक जब मैं अपना flood-fill कक्षा लागू करता हूं तो यह मेरा पूरा Bitmap काला बदल देता है। जाहिर है यह वांछित प्रभाव नहीं है। मैं निम्नलिखित धागे देखा है:एंड्रॉइड - फ्लड-फिल

मैं क्या देख सकते हैं मैं सब कुछ वे उन समाधानों में ले कर आए हैं कर रहा हूँ से, हालांकि इसने मुझे मेरी समस्या के समाधान के लिए प्रेरित नहीं किया है। तो पीछा करने के लिए कटौती करने के लिए, यहां कुछ संक्षिप्त स्पष्टीकरण के साथ कोड है।

एक्सएमएल
मैं एक रिश्तेदार लेआउट का उपयोग कर रहा और स्थिति (स्टैकिंग) दो ImageViews सीधे एक दूसरे के शीर्ष पर। दोनों के पास एक ही छवि है और यह आपको छवि पर आकर्षित करने में सक्षम होने का भ्रम पैदा करता है। हालांकि, आप वास्तव में एक पारदर्शी ओवरले पर चित्रित कर रहे हैं।

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

कैनवास
तब मैं बनाने के मेरे इस कोड के साथ Canvas और मैं अपने परत प्रकार सही ढंग से स्थापित करने के लिए सुनिश्चित करें।

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 वस्तु के लिए मेरे पैरामीटर पारित flood-fill विधि का उपयोग करें, लौट bitmap, और अंत में मेरी canvas करने के लिए नए bitmap आकर्षित।

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 एल्गोरिथ्म।

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

तो यह है, हमारे पास पहेली के सभी टुकड़े होना चाहिए लेकिन किसी कारण से वे काम नहीं कर रहे हैं। मुझे नुकसान हुआ है और किसी भी मदद की सराहना की है। धन्यवाद!

उत्तर

0

मुझे लगता है कि आप लाइन कर रहे हैं:

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

होने की

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

अधिक की तरह मैं सब कुछ पर यकीन नहीं है लेकिन जहां तक ​​मैं आपको बता सकता मैं इन के साथ की कोशिश करेगा आवश्यकता हो सकती है समाधान:

पहले: बजाय decodeFile का उपयोग कर के मैं नहीं बल्कि decodeInputStream दूसरा उपयोग करें: किसी रूप में आपने देखा है कि तीसरा: तीसरा: मैं यह पूछने जा रहा हूं कि आपको उस खाद्य-भरने वाले अलौकिकता की आवश्यकता क्यों है? मुझे लगता है कि यह बहुत कमजोर है और यह उपयोग करने के लिए थोड़ा गन्दा लग रहा है, आप ऐसा करने के लिए एक नया स्केल्ड बिटमैप या ओपनग्ल प्रभाव जैसे कुछ क्यों नहीं बनाते? क्योंकि यही कारण है कि ग्राफिक्स कार्ड हैं;

संबंधित मुद्दे