您好我正在使用SurfaceView繪製輸入信號的實時圖。 採樣率爲128Hz,目標圖形刷新率爲50Zh。如何在清除SurfaceView畫布後避免鬼圖繪製
事情辦得相當順利,該點被正確繪製實時的。
我使用Path() 爲每個段調用path.computeBounds()得到一個矩形,我將用它來調用holder.lockCanvas(rect)並繪製路徑。使用矩形防止閃爍,減少CPU的使用
當圖形達到予鎖定整個畫布和清除背景,繪製圖形幀,然後繼續繪製結束。
的問題是,在每一個新的「頁面」年初我從最後一頁鬼形象:
我相信這是由雙緩衝/使用髒區造成的繪圖時。
我已經看過了這個問題,但沒有解決方案,似乎足以滿足這種類型的應用。任何幫助是最受歡迎的。
感謝 讓 - 皮埃爾·
代碼如下:
private void draw() {
Point point = null;
Canvas canvas = null;
Path path = new Path();
ArrayList<Point> pointArray;
float oldX = -1;
boolean setToClear = false;
boolean isNewSegment = false;
if (samplesInQueue == 0) {
return;
}
pointArray = new ArrayList<Point>((int) samplesInQueue);
for (int i = 0; i < samplesInQueue; i++) {
// take a peek at the point without retrieving it from the point
// queue
point = Points.peek();
// check if first point of segment is the start of a page
if (i == 0) {
if (lastSegmentEndPoint != null) {
if (point.x < lastSegmentEndPoint.x) {
// yes then we will need to clear the screen now
isNewSegment = true;
}
} else {
// yes then we will need to clear the screen now
isNewSegment = true;
}
}
if (point != null) {
if (point.x > oldX) {
// put consecutive points in the path point array
point = Points.poll();
samplesInQueue--;
pointArray.add(point);
oldX = point.x;
} else {
// we have a wrap around, stop and indicate we need to clear
// the screen on the next pass
if (!isNewSegment) {
setToClear = true;
}
break;
}
}
}
// no points, return
if (pointArray.size() == 0) {
return;
}
// fill the path
for (int i = 0; i < pointArray.size(); i++) {
Point p = pointArray.get(i);
if (i == 0) {
if (lastSegmentEndPoint != null) {
if (p.x >= lastSegmentEndPoint.x) {
// if we have the end of the last segment, move to it
// and line to the new point
path.moveTo(lastSegmentEndPoint.x, lastSegmentEndPoint.y);
path.lineTo(p.x, p.y);
} else {
// otherwise just line to the new point
path.moveTo(p.x, p.y);
}
} else {
path.moveTo(p.x, p.y);
}
} else {
path.lineTo(p.x, p.y);
}
}
if (clear || isNewSegment) {
if (clear) {
clear = false;
}
// we need to clear, lock the whole canvas
canvas = holder.lockCanvas();
// draw the graph frame/scales
drawGraphFrame = true;
drawGraphFrame(canvas);
} else {
// just draw the path
RectF bounds = new RectF();
Rect dirty = new Rect();
// calculate path bounds
path.computeBounds(bounds, true);
int extra = 0;
dirty.left = (int) java.lang.Math.floor(bounds.left - extra);
dirty.top = (int) java.lang.Math.floor(bounds.top - extra);
dirty.right = (int) java.lang.Math.round(bounds.right + 0.5);
dirty.bottom = (int) java.lang.Math.round(bounds.bottom + 0.5);
// just lock what is needed to plot the path
canvas = holder.lockCanvas(dirty);
}
// draw the path
canvas.drawPath(path, linePaint);
// unlock the canvas
holder.unlockCanvasAndPost(canvas);
// remember last segment end point
lastSegmentEndPoint = pointArray.get(pointArray.size() - 1);
// set clear flag for next pass
if (setToClear) {
clear = true;
}
}
繪製幀/清除圖形代碼
private void drawGraphFrame(Canvas canvas) {
if (!drawGraphFrame) {
return;
}
if (canvas == null) {
Log.e(TAG, "trying to draw on a null canvas");
return;
}
drawGraphFrame = false;
// clear the graph
canvas.drawColor(Color.BLACK, Mode.CLEAR);
// draw the graph frame
canvas.drawLine(leftMargin, topMargin, leftMargin, mCanvasHeight - bottomMargin, framePaint);
canvas.drawLine(leftMargin, mCanvasHeight - bottomMargin, mCanvasWidth - rightMargin, mCanvasHeight
- bottomMargin, framePaint);
// more drawing
}
謝謝西蒙。這在這種情況下不起作用。 rewind()會導致路徑自保留舊點以來增長。這會導致性能在幾百點之後快速下降。這就是爲什麼我一次只畫幾個點的原因。另外,在你最後的陳述(示波器)中,我相信這是我的代碼完成的結果,矩形只涵蓋了所需的區域。也許我不太明白你的意思。 –