Android:使用 DrawPoint() 的 onDraw 方法导致画布上出现抖动和扭曲
我正在开发一个应用程序,它或多或少地将二维值矩阵绘制到画布上。该矩阵的值被缩放到 Alpha 级别以说明强度,并且矩阵的坐标是简单地从行和列索引推断出来的。下面是我的 onDraw 例程。
public void onDraw(Canvas canvas, float [][] spectrum, float nsegs,int seglen) {
//canvas.translate(0,0);
//alpha = 0;
int canHeight = canvas.getHeight();
int canWidth = canvas.getWidth();
//float[] array = generateData(512);
float [] spec = new float[seglen];
final float bw = (float)(canWidth-2)/nsegs;
final float bh = (float)(canHeight-2)/(float) seglen;
for (int i = 0;i<seglen;i++){
spec[i] = spectrum[i][index]; // One column at a time
}
float max = maxVal(spec);
float min = minVal(spec);
xcoor = index;
for (int n = 0; n < seglen; n++){
//Scale value to alpha (0-255)
alpha =(int)Math.round((((spec[n] - min)/max)*255.0));
ycoor = n;
paint.setAlpha(alpha);
canvas.drawPoint(xcoor,ycoor, paint);
}
index = (int) (index +1);
if (index == nsegs-1){
index = 0;
}
}
这里的绘制配置被预定义为:
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
该程序一次绘制一个像素,填充一列像素,其数量等于矩阵一列中的元素数量。然后它从下一列开始,其中仍显示上一列,依此类推。在此阶段,当所有列都已满时,它会再次从第一列开始,在之前的元素之上绘制。
问题:虽然已经绘制了尾部列,但它们似乎会闪烁并跳跃,就像 Alpha 一样。我尝试使用 canvas.save() 和 canvas.restore() 捕获整个画布并在打印列后恢复它。我已经仔细检查了所有行和列索引以及 alpha 值,以确保坐标按需要增量(而且它们确实如此)。这与示例 APIdemo DrawPoints.java 非常相似,但存在三个主要区别。
- 我使用的是 DrawPoint 而不是 DrawPoints,并且
- 我不使用“canvas.setColour”,因为它会从画布中删除尾部列。
- 此 onDraw 函数在扩展 SurfaceView 的线程中运行
任何想法将不胜感激,谢谢您的时间。
I am developing an app which draws more or less a two-dimensional matrix of values to a canvas. The values of this matrix are scaled to Alpha levels to illustrate intensity, and the coordinates for the matrix are simply extrapolated from row and column indexes. Below is my onDraw routine.
public void onDraw(Canvas canvas, float [][] spectrum, float nsegs,int seglen) {
//canvas.translate(0,0);
//alpha = 0;
int canHeight = canvas.getHeight();
int canWidth = canvas.getWidth();
//float[] array = generateData(512);
float [] spec = new float[seglen];
final float bw = (float)(canWidth-2)/nsegs;
final float bh = (float)(canHeight-2)/(float) seglen;
for (int i = 0;i<seglen;i++){
spec[i] = spectrum[i][index]; // One column at a time
}
float max = maxVal(spec);
float min = minVal(spec);
xcoor = index;
for (int n = 0; n < seglen; n++){
//Scale value to alpha (0-255)
alpha =(int)Math.round((((spec[n] - min)/max)*255.0));
ycoor = n;
paint.setAlpha(alpha);
canvas.drawPoint(xcoor,ycoor, paint);
}
index = (int) (index +1);
if (index == nsegs-1){
index = 0;
}
}
Here paint configuration is pre-defined as:
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
This program draws one pixel at a time, fills one column of pixels equal to the number of elements in a column of the matrix. Then it starts on the next column, where the previous column is still displayed and so forth. At this stage when all columns are full it stars from the first column again, drawing on top of previous elements.
The Problem: The tailing columns although already drawn appear to flicker and jump around, as does the Alpha. I have attempted to canvas.save() and canvas.restore() to capture the entire canvas and restore it after a column is printed. I have double checked all my row and column indexing and alpha vales to ensure the coordinates increment as per desired (and they do). This is very similar to the sample APIdemo DrawPoints.java, however there are three primary differences.
- I am using DrawPoint not DrawPoints, and
- I don't use "canvas.setColour" as it removes the tailing columns from the canvas.
- This onDraw function is operating in a Thread which extends SurfaceView
Any idea's would be much appreciated, thank you for your time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在上面的例子中,我使用的是 SurfaceView 而不是 View。 Android 开发文档中
注意:每次从 SurfaceHolder 检索 Canvas 时,Canvas 的先前状态将被保留。为了正确地为图形设置动画,您必须重新绘制整个表面。例如,您可以通过使用drawColor()填充颜色或使用drawBitmap()设置背景图像来清除Canvas的先前状态。否则,您将看到之前绘制的痕迹。
解决方案,每次重新绘制整个画布以防止抖动。
In the case above, I was using a SurfaceView instead of a View. Out of the Android dev docs
Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed.
The Solution, re-draw the entire canvas each time to prevent the jitter.