Android 在缩放的画布上绘制文本
我在已缩放的画布上绘制文本时遇到问题。我想缩放画布,使绘图尺寸和坐标始终在0.0到1.0范围内,即与画布宽度和高度无关。(如果这是一个糟糕的做法,请随意评论并给出原因。)虽然我可以在缩放画布上正确绘制直线和圆弧,但我在绘制文本时遇到了很大困难,而且这个问题似乎只发生在Android 4.2上 作为一个例子,我已经基于这个页面创建了一些代码。然而,为了清晰起见,我去掉了很多代码 首先,此代码工作正常,与上面的链接相同(尽管已精简): 接下来,我用标准化(0到1.0)值替换绝对像素大小,并缩放画布:Android 在缩放的画布上绘制文本,android,android-canvas,scale,Android,Android Canvas,Scale,我在已缩放的画布上绘制文本时遇到问题。我想缩放画布,使绘图尺寸和坐标始终在0.0到1.0范围内,即与画布宽度和高度无关。(如果这是一个糟糕的做法,请随意评论并给出原因。)虽然我可以在缩放画布上正确绘制直线和圆弧,但我在绘制文本时遇到了很大困难,而且这个问题似乎只发生在Android 4.2上 作为一个例子,我已经基于这个页面创建了一些代码。然而,为了清晰起见,我去掉了很多代码 首先,此代码工作正常,与上面的链接相同(尽管已精简): 接下来,我用标准化(0到1.0)值替换绝对像素大小,并缩放画布:
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
public class DrawDemo extends Activity {
DemoView demoview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
demoview = new DemoView(this);
setContentView(demoview);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class DemoView extends View{
private int width = 0;
private int height = 0;
public DemoView(Context context){
super(context);
}
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh){
width = w;
height = h;
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// custom drawing code here
// remember: y increases from top to bottom
// x increases from left to right
int x = 0;
int y = 0;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
// make the entire canvas white
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
// draw some text using STROKE style
canvas.scale(width, height);
paint.setStyle(Paint.Style.STROKE);
//paint.setStrokeWidth(1);
paint.setColor(Color.MAGENTA);
paint.setTextSize(0.2f);
canvas.drawText("Style.STROKE", 0.5f, 0.5f, paint);
}
}
}
结果是屏幕上没有显示任何内容。有人能告诉我我做错了什么吗?请记住,在Android<4.2上,用后者绘制文本对我很有用。对于代码示例的格式设置表示歉意,我仍然无法掌握Stackoverflows代码的格式设置。当启用硬件加速时,文本将以您在绘图上指定的字体大小渲染为纹理。这意味着在您的情况下,文本以0.2f像素光栅化。然后,该纹理在绘图时放大,这就是为什么您什么都看不到的原因
虽然这个问题已经在Android的未来版本中得到解决,但我强烈建议您不要使用0..1值。您可能不仅会遇到精度问题,还会强制渲染管道(软件和硬件)绕过非常有用的优化。例如,在软件中使用比例变换渲染的文本是使用路径而不是位图blit来渲染的。谢谢Romain。只要你能澄清一件事。我不太清楚为什么0.2f的像素高度不能放大。例如,画布高度=200像素,0.2f缩放到40像素,这应该是可见的,或者我误解了你的答案?因为字体被光栅化为高度为0.2px的纹理,四舍五入为0px,所以你得到了一个透明纹理,然后它缩放到200px高。好的,感谢你填补了我知识中的空白。谢谢你所有的Android工作!
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
public class DrawDemo extends Activity {
DemoView demoview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
demoview = new DemoView(this);
setContentView(demoview);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class DemoView extends View{
private int width = 0;
private int height = 0;
public DemoView(Context context){
super(context);
}
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh){
width = w;
height = h;
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// custom drawing code here
// remember: y increases from top to bottom
// x increases from left to right
int x = 0;
int y = 0;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
// make the entire canvas white
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
// draw some text using STROKE style
canvas.scale(width, height);
paint.setStyle(Paint.Style.STROKE);
//paint.setStrokeWidth(1);
paint.setColor(Color.MAGENTA);
paint.setTextSize(0.2f);
canvas.drawText("Style.STROKE", 0.5f, 0.5f, paint);
}
}
}