안녕하세요. SurfaceView를 사용하여 들어오는 신호의 실시간 그래프를 플로팅하는 중입니다. 샘플링 속도는 128Hz이고 목표 그래프 새로 고침 빈도는 50Zh입니다.SurfaceView 캔버스를 지운 후에 고스트 그리기를 피하는 방법
점들은 실시간으로 제대로 그려집니다.
내가 path.computeBounds 전화 각 세그먼트 경로() 를 사용하여 몇 가지 포인트의 세그먼트의 데이터를 플롯() 나는 holder.lockCanvas (RECT)를 호출하고 경로를 그리는 데 사용할 구형 영역을 얻을 수 있습니다. 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
}
감사합니다. Simon. 이 경우에는 실제로 작동하지 않습니다. rewind()는 이전 점이 유지 된 이후 경로가 커지게합니다. 이로 인해 성능은 몇 백 포인트가 지나면 빠르게 떨어집니다. 이것이 내가 한 번에 몇 가지 점을 그리는 이유입니다. 또한, 귀하의 마지막 진술 (오실로 스코프)에서, 나는 이것이 내 코드에서 끝나는 것 같아요, rect는 필요한 영역만을 다루고 있습니다. 어쩌면 당신이 의미하는 바를 이해하지 못했을 수도 있습니다. –