2014-09-04 113 views
4

我有一個背景圖像的畫布。我需要知道是否可以清除此畫布上的繪畫以進行重繪而不清除其背景圖像。這是我的例子和迄今爲止的結果。從畫布清除油漆而不清除背景圖像 - Android

JAVA

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

     mImageView.setImageBitmap(mBitmap); 
     mImageView.setOnTouchListener(this); 
    } 
} 

private void draw() { 
    mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); // THIS LINE CLEARS 

    int lastIndex = mCordHashMap.size() - 1; 
    int index = 0; 

    for (LinkedHashMap.Entry<String, ArrayList<Circle>> entry : mCordHashMap.entrySet()) { 
     ArrayList<Circle> coords = new ArrayList<Circle>(); 
     coords = entry.getValue(); 
     Path path = new Path(); 
     String key = entry.getKey(); 
     String surface = getSurfaceFromKey(key); 
     changePaint(surface); 

     if (coords.size() < 3) { 
      for (Circle c : coords) { 
       mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCirclePaint); 
      } 
     } else { 
      for (Circle c : coords) { 
       if (c == coords.get(0)) { 
        path.moveTo(c.getmX(), c.getmY()); 
       } else { 
        path.lineTo(c.getmX(), c.getmY()); 
       } 
      } 

      path.close(); 
      mCanvas.drawPath(path, mPaint); 
      mCanvas.drawPath(path, mStrokePaint); 

     } 

     if (index == lastIndex && !mSpecificPathSelected) { 
      for (Circle c : coords) { 
       mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCirclePaint); 
       mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCircleStrokePaint); 
      } 
     } 
     mImageView.invalidate(); 
     index++; 
    } 
} 

XML

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

    <ExpandableListView 
     android:id="@+id/surfaceList" 
     android:background="@color/light_grey" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight=".20" /> 

    <ImageView 
     android:id="@+id/drawContainer" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight=".80" 
     android:contentDescription="@string/app_name"/> 

</LinearLayout> 

所以上面的代碼將圖像加載到我的Canvas。然後,每次觸摸Canvas時,都會繪製一個圓圈並最終形成圓圈之間的路徑。然而,當我開始添加更多的圈子和路徑時,它正在重繪本身,看起來很糟糕。

現在我可以使用此線清除畫布上的油漆。

mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 

不過,我也失去了我Bitmap設置爲它的背景,現在我的背景是黑色的。那麼,我如何保留我的背景圖像,但清除了我的油漆?這是可能的還是我必須使用諸如兩個Canvas之間的工作?

我已經嘗試了以下,以及相同的幾個變化。

1) mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 

2) mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
    mCanvas.drawBitmap(mBitmap, 0, 0, mPaint); 

3) mBitmap.eraseColor(Color.TRANSPARENT); 
    mCanvas.drawBitmap(mBitmap, 0, 0, mPaint); 

任何幫助表示讚賞

回答

3

據我所知,畫布不包含層。所以你不能刪除一層(油漆),而離開另一層(背景)。我相信你應該使用兩個畫布,甚至是畫布和一個ImageView來保持背景。然後,當您想要導出圖像時,將畫布內容與背景結合在一起。

+0

這很有道理。如果仔細觀察,我實際上使用了'ImageView'並將位圖設置爲其src內容,但顯然這對我沒有任何好處。 ''我相信你應該使用兩個畫布,甚至是畫布和一個ImageView來保存背景,然後當你想導出圖像時,畫布內容和背景結合起來。「」如果你有時間,請發佈這些任何一個的例子。 – Jawascript 2014-09-04 18:37:46

+0

好吧,所以我一直在努力尋找一些東西。你有鏈接成功地使用imageview作爲背景和/或兩個畫布的人? – Jawascript 2014-09-04 20:12:15

+0

對不起,在工作中。在等待服務器部署時,我正在瀏覽它。今晚我會深入研究一下。 – Coeffect 2014-09-04 20:21:41

3

我終於明白了。我能夠使用堆疊在RelativeLayout中的兩個ImageViews。將ImageViews堆疊在一起,然後將ImageViews設置爲相同的圖片,但將Bitmaps分開。現在,頂級人物充當您的前景,您的底部充當您的背景。現在你可以畫出最上面的一張,同時清除背景,而不會影響底部。關鍵是屬性yourImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);,它會關閉硬件加速並允許您的背景實際上呈現透明。如果沒有將此屬性應用於您的視圖,您將會看到黑色或白色背景,它完全覆蓋了您的底部ImageView,這使得它完全無用。

XML

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

    <ExpandableListView 
     android:id="@+id/surfaceList" 
     android:background="@color/light_grey" 
     android:layout_width="250dp" 
     android:layout_height="match_parent" /> 

    <ImageView 
     android:id="@+id/background" 
     android:layout_width="match_parent" 
     android:layout_toRightOf="@+id/surfaceList" 
     android:layout_height="match_parent" 
     android:contentDescription="@string/app_name"/> 

    <ImageView 
     android:id="@+id/foreground" 
     android:layout_width="match_parent" 
     android:layout_toRightOf="@+id/surfaceList" 
     android:layout_height="match_parent" 
     android:contentDescription="@string/app_name"/> 

</RelativeLayout> 

JAVA

public void setCanvas() { 
    if(mFile != null && mFile.exists()) { // check for null 
     mFirstBitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); // get bitmap from directory 
     mSecondBitmap = Bitmap.createScaledBitmap(mPictureBitmap, mImageView.getWidth(), // size bitmap mImageView.getHeight(), false); 
     mSecondBitmap = mSecondBitmap .copy(Bitmap.Config.ARGB_8888, true); // make bitmap mutable so it can be applied to the canvas 
     mFirstBitmap = mSecondBitmap .copy(Bitmap.Config.ARGB_8888, true); // make second bitmap from copy, also mutable 
     mCanvas = new Canvas(mSecondBitmap); //create your canvas from 2nd bitmap 
     mImageView.setImageBitmap(mSecondBitmap); // set this imageview to 2nd bitmap 
     mImageView2.setImageBitmap(mFirstBitmap); //set this imageview to 1st bitmap 

     mImageView.setOnTouchListener(this); // set on touch listener 
     mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); // IMPORTANT set hardware acceleration off with this line. Otherwise your view's background will NOT be transparent 
     mImageView.bringToFront(); // bring this imageview to the front, making it your foreground 
    } 
} 

希望這樣可以節省別人一噸的時間。

1

只是如果你不使用的ImageView還有另外一個,甚至simplier解決方案:

我已經有了自己的新位圖(mBackgroundBitmap);新的Canvas(mBackgorundCanvas),asigned mBackgroundBitmap到mBackgroundCanvas,並且在一切的onDraw方法首先我DAR我的背景位圖:

canvas.drawBitmap(mBackgroundBitmap, offSetX, offSetY, mBitmapPaint); 

就在這時,我開始畫我實際的位圖:

canvas.drawBitmap(mBitmap, offSetX, offSetY, mBitmapPaint); 

我想這是不是內存有效的解決方案(我的意思是說有兩個位圖不是非常酷或愉快的,但是然後我們許多人不使用一個大的圖像,而是(至少我)從一個片段創建我的背景,然後將它平鋪在X和Y

如果我的回答是荒謬的,不要評價我,我只是一個菜鳥。

+0

我喜歡你的答案,但從記憶的角度來看,它的效率可能並不高,但它很好,很簡單。 – Jawascript 2014-12-08 14:48:56