在缩放的画布上绘制文本

时间:2013-07-22 23:12:54

标签: android android-canvas scale

我在已缩放的画布上绘制文本时遇到问题。我想缩放画布,使绘图尺寸和坐标始终在0.0到1.0范围内,即与画布宽度和高度无关。 (如果这是不好的做法,请随意评论,说明为什么会这样。)虽然我可以正确地在缩放的画布上绘制线条和弧线,但是我很难在绘制文本时出现这个问题似乎只出现在Android上4.2

举个例子,我根据这个页面here创建了一些代码。但是,为了清晰起见,我没有删除很多代码。

首先,此代码正常工作,并且与上面的链接一样(尽管已经删除):

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
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1);
        paint.setColor(Color.MAGENTA);
        paint.setTextSize(30);
        canvas.drawText("Style.STROKE", 75, 75, paint);
    }
  }
}

接下来,我用标准化(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代码格式。

1 个答案:

答案 0 :(得分:2)

启用硬件加速后,文本将以您在绘画上指定的字体大小呈现为纹理。这意味着在您的情况下,文本被栅格化为0.2像素。然后在绘制时将该纹理放大,这就是为什么你没有看到任何东西。

虽然此问题已在Android的未来版本中得到解决,但我强烈建议您不要使用0..1值。您可能不仅会遇到精度问题,还会强制渲染管道(软件和硬件)绕过非常有用的优化。例如,使用路径而不是位图blits渲染使用软件中的缩放变换渲染的文本。