在下面的代码中,我试图绘制一个随时间放大的椭圆。
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();
}
现在,如您所见,编写注释“Config Paint Case1”或“Config Paint Case2”,case1表示每次调用方法时创建绘图实例的情况,而情况2表示我定义成员的位置类中的对象所以我可以在需要的时候使用它,当我使用第一种情况时,一切都工作得很完美和准确,而当我使用第二种情况时没有发生任何事情的问题,在我看来主要的事情我不需要每次都创建一个绘图对象,所以我需要越来越多地优化我的代码,但为什么会发生这种情况......
答案 0 :(得分:0)
最后我得到了这个问题的答案,这篇文章Transparency with JPEGs done right提供了很好的帮助,描述了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模式,最后,我回到原来的模式。一切都很完美。