2014-12-30 89 views
0

在下面的代碼中,我試圖繪製一個隨時間放大的橢圓。在Android中使用PAINT對象在畫布上繪製橢圓

Bitmap currBitmap = null; 
Canvas currCanvas = null; 

//Config Paint Case2 
final Paint currPaint = new Paint(); 
List BlocksList = null; 
boolean bSet = false; 

public void DrawOval(Bitmap src, int nRadiusprct) 
{ 
    // image size 
    int width = src.getWidth(); 
    int height = src.getHeight(); 

    //create bitmap output 
    if(currBitmap == null) 
     currBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

    // set canvas for painting 
    if(currCanvas == null) 
    { 
     currCanvas = new Canvas(currBitmap); 
     currCanvas.drawARGB(0, 0, 0, 0); 
     MainActivity.imgMain.setImageBitmap(currBitmap); 
    } 

    // config paint Case1 
    /*final Paint currPaint = new Paint(); 
    currPaint.setAntiAlias(true); 
    currPaint.setColor(Color.BLACK);*/ 

    // config paint Case2 
    if(!bSet) 
    { 
     currPaint.setAntiAlias(true); 
     currPaint.setColor(Color.BLACK); 
     // create Xfer mode 
     currPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
     bSet = true; 
    } 

    // config rectangle for embedding 
    int nMidWidth = width/2; 
    int nMidHeight = height/2; 
    float fPercent = (nRadiusprct/100.0f); 

    float fLeft = nMidWidth * (1 - fPercent); 
    float fRight = nMidWidth * (1 + fPercent); 
    float fTop = nMidHeight * (1 - fPercent); 
    float fBottom = nMidHeight * (1 + fPercent); 

    final Rect rect = new Rect(0, 0, width, height); 
    final RectF rectF = new RectF(fLeft, fTop, fRight, fBottom); 

    currCanvas.drawOval(rectF, currPaint); 

    // create Xfer mode, Config Paint Case1 
    //currPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 

    currCanvas.drawBitmap(src, rect, rect, currPaint); 

    MainActivity.imgMain.invalidate(); 
} 

現在,正如你可以看到寫評論「配置畫圖案例1」或「配置塗料案例2」,Case1的代表,我每個方法被調用時創建一個油漆實例的情況下,而情況2表示其中我在類中定義了一個成員對象,這樣我就可以在需要時使用它,當我使用第一個事件時,所有事情都是完美而準確的,而當我使用第二種事件時什麼也沒有發生,主要的事情在我看來,我不需要每次都創建一個繪畫對象,所以我需要優化我的代碼越來越多,但爲什麼發生在這裏......

回答

0

最後我得到了這個問題的答案,本文幫助很大描述了PorterDuff模式是如何工作的,在那篇文章中,我發現了這個Xfermodes Example,它給了我錯誤的地方,這裏是描述。

其實,我並不需要創建一個噴漆的對象每次,我需要的是對付以正確的方式xfermodes,完美的代碼是:

Bitmap currBitmap = null; 
Canvas currCanvas = null; 

//Config Paint Case2 
final Paint currPaint = new Paint(); 
List BlocksList = null; 
boolean bSet = false; 

public void DrawOval(Bitmap src, int nRadiusprct) 
{ 
    // image size 
    int width = src.getWidth(); 
    int height = src.getHeight(); 

    //create bitmap output 
    if(currBitmap == null) 
     currBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

    // set canvas for painting 
    if(currCanvas == null) 
    { 
     currCanvas = new Canvas(currBitmap); 
     MainActivity.imgMain.setImageBitmap(currBitmap); 
    } 

    // config paint Case2 
    if(!bSet) 
    { 
     currPaint.setAntiAlias(true); 
     currPaint.setColor(Color.BLACK); 
     bSet = true; 
    } 

    // config rectangle for embedding 
    int nMidWidth = width/2; 
    int nMidHeight = height/2; 
    float fPercent = (nRadiusprct/100.0f); 

    float fLeft = nMidWidth * (1 - fPercent); 
    float fRight = nMidWidth * (1 + fPercent); 
    float fTop = nMidHeight * (1 - fPercent); 
    float fBottom = nMidHeight * (1 + fPercent); 

    final Rect rect = new Rect(0, 0, width, height); 
    final RectF rectF = new RectF(fLeft, fTop, fRight, fBottom); 

    Xfermode BeforEPaintXferMode = currPaint.getXfermode(); 

    currCanvas.drawOval(rectF, currPaint); 

    // create Xfer mode 
    currPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 

    // draw source image to canvas 
    currCanvas.drawBitmap(src, rect, rect, currPaint); 

    currPaint.setXfermode(BeforEPaintXferMode); 

    MainActivity.imgMain.invalidate(); 
} 

現在,你可以看到我只是在繪製之前存儲當前的xfermode,然後將其設置爲SRC_IN模式,最後回到原始模式。並且一切都很完美。