2014-12-30 90 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模式,最后回到原始模式。并且一切都很完美。