Java Android绘图应用程序绘制贝塞尔曲线非常慢
我一直在开发一个Android绘图应用程序,该应用程序旨在基于用户交互绘制贝塞尔曲线。用户在屏幕上画线,它与他们画的完全一样Java Android绘图应用程序绘制贝塞尔曲线非常慢,java,android,canvas,bitmap,bezier,Java,Android,Canvas,Bitmap,Bezier,我一直在开发一个Android绘图应用程序,该应用程序旨在基于用户交互绘制贝塞尔曲线。用户在屏幕上画线,它与他们画的完全一样 @Override public boolean onTouchEvent(MotionEvent event) { touchX = event.getX(); touchY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN:
@Override
public boolean onTouchEvent(MotionEvent event) {
touchX = event.getX();
touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawingElement = new DrawingElement(gridType, canvasWidth, canvasHeight);
drawingElement.addPoint(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawingElement.addPoint(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawingElement.addPoint(touchX, touchY);
actualDrawingElement = new DrawPath(gridType, canvasWidth, canvasHeight, drawPaint, paintColor, brushSize);
actualDrawingElement.setDrawingElementType(DrawingElementType.PATH);
actualDrawingElement.setPoints(drawingElement.getPoints());
drawingElement = actualDrawingElement;
actualDrawingElement = null;
finishedElement = true;
break;
default:
return false;
}
//draw the view - will be called after touch event
@Override
protected void onDraw(Canvas canvas) {
if(bgPaint == null) {
bgPaint = new Paint();
bgPaint.setColor(Color.WHITE);
}
canvas.drawRect(0, 0, getWidth(), getHeight(), bgPaint);
Bitmap dbBMP = null;
BitmapSave bitmapSave = getDatabaseHandler().getLastSave();
if(bitmapSave != null) {
dbBMP = bitmapSave.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
} else {
dbBMP = Bitmap.createBitmap((int) getActualWidth(), (int) getActualHeight(), Bitmap.Config.ARGB_8888);
}
Canvas dbCanvas = new Canvas(dbBMP);
DrawPath p;
if(drawingElement != null && drawingElement.getPointCount() > 0) {
actualDrawingElement = new DrawPath(gridType, canvasWidth, canvasHeight, drawPaint, paintColor, brushSize);
actualDrawingElement.setDrawingElementType(DrawingElementType.PATH);
actualDrawingElement.setPoints(drawingElement.getPoints());
p = (DrawPath)actualDrawingElement;
p.draw(dbCanvas);
p = null;
}
if(finishedElement) {
db.addSave(new BitmapSave(dbBMP));
}
canvas.drawBitmap(dbBMP, 0, 0, drawPaint);
if(displayGrid) {
DrawGrid drawGrid = new DrawGrid(gridType, canvasWidth, canvasHeight, bgPaint);
drawGrid.draw(canvas);
}
updateUndoRedoButtons();
}
上面的代码显示了我的onDraw和onTouchEvent方法。我开始使用数据库来存储位图,因为我开始遇到很多内存过载错误,它会崩溃。以前,我在内存中有多个位图,用于在ArrayList中进行撤消/重做(崩溃前最多3或4个)。我想在应用程序中至少有20个撤消/重做(总共) 最后,它意味着要同时绘制多条线,但即使是一条线也很慢 我试图抽象出一些正在发生的事情,如线条画。。。 它确实将点存储在一个单独的类中,稍后再抓取它们进行绘制 本文介绍了一种抽象线绘制方法
public void draw(Canvas canvas) {
boolean firstRun = true;
Point2D prevPoints = null;
Point2D points = null;
for(Point2D pointGrp : getPoints()) {
points = getCalculatedPoints(pointGrp);
if (firstRun) {
paths.add(new Path());
paths.get(0).moveTo(points.getPosX(), points.getPosY());
} else {
paths.get(0).quadTo(prevPoints.getPosX(), prevPoints.getPosY(), points.getPosX(), points.getPosY());
}
firstRun = false;
prevPoints = points;
}
canvas.drawPath(paths.get(0), getPaint());
}
在这个阶段,“points=getCalculatedPoints(pointGrp);”字面上返回它给出的相同点。Point2D对象只包含pointx,pointy不包含其他内容。除了getter和setter之外,没有其他方法
你知道为什么这会运行得很慢吗?它在一条巨大的直线上只能拾取4个点,这使得它非常参差不齐和笔直。“我希望应用程序中至少有20个撤消/重做(总共)――不要使用位图进行撤消/重做。跟踪有关行的关键数据并重新绘制。除此之外,还可以使用Traceview确定您在哪里花费时间,而不是在位图复制中。此外,看起来您可能正在
onDraw()
中执行数据库I/O,如果为true,则会非常糟糕,并会解释您的问题。您在每次onDraw调用时都从数据库重建位图,而不是将最后一个位图保存在内存中,然后只向其中绘制新数据,只有在必须回滚的情况下才能从数据库中恢复。我以前保留了行的关键数据,没有使用位图。它导致应用程序正常运行了大约3行(如果它们很短的话!),然后速度变得非常慢,没有在行中获得足够的分数。我将尝试在需要时限制对数据库的访问,但以前没有使用数据库,只使用位图。这是缓慢的基本上从字去与该设置太。有没有更好的方法来存储数据?或者我遇到内存不足的问题是不对的?为什么不专门存储用于绘制曲线的输入事件坐标,然后在用户绘制曲线时使用这些坐标来重新绘制曲线?这里似乎不需要位图。