与像素完美的文字canvas.drawText在画布上 [英] canvas.drawText with pixel perfect text on a canvas

查看:518
本文介绍了与像素完美的文字canvas.drawText在画布上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是不是消除锯齿,请在回答之前阅读问题谢谢。

添加赏金 - > 机器人转换文字宽度(像素)/屏幕宽度的百分比高度

质量信息 - > http://stackoverflow.com/a/1016941/1815624

我想画在画布上的文字时得到不一致的结果。请帮忙,谢谢。

I am getting inconsistent results when trying to draw text on a canvas. Please help, thank you.

我希望文字消耗上的所有设备的比例相同的空间量

I want the text to consume the same amount of scaled space on all devices

我不关心ANTI_ALIAS并添加了 paint.setFlags(Paint.ANTI_ALIAS_FLAG); 但问题是一样的...

I do not care about ANTI_ALIAS and have added the paint.setFlags(Paint.ANTI_ALIAS_FLAG); but the problem is the same...

在1画面的文字消耗宽度的一半,在另一只1/3和使用的全部宽度。甚至一

On 1 screen the text consumes half the width, on another only a 1/3 and even one that uses the full width.

我希望它们都使用的屏幕房地产等量。

例如

7寸1600x900的平板电脑奇巧物理:

1600X900 7inch tablet Kitkat physical:

1920.1080 5.2奇巧物理

1920.1080 5.2 kitkat physical

20英寸1600x900的模仿棒棒糖

1600x900 20in Lollipop emulated

1280×720 4.7inch

1280x720 4.7inch

这些都被用在的 http://www.gkproggy.com/2013/01/draw-text-on-canvas-with-font-size.html

在这里作为教程显示一致的结果

where as that tutorial is showing consistent results

要彻底这里是源:

public class MainActivity extends Activity
{
    Paint paint;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        paint = new Paint();
        View test = new TestView(this);

        setContentView(test);
    }

    public class TestView extends View
    {

        public TestView(Context context)
        {
            super(context);
            setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        }

        public float pixelsToSp(Context context, float px) {
            float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
            return px/scaledDensity;
        }

        public float spToPixels(float sp) {
            Context context = getContext();
            float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
            return scaledDensity*sp;
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            int size = getResources().getDimensionPixelSize(R.dimen.sp20);
            int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
            Log.v("intSize", Integer.toString(size));
            Log.v("intSize", Integer.toString(px));
            Log.v("intSize", Float.toString(spToPixels(20f)));
            if(true) {
                Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
                paint.setTypeface(myTypeface);
            }
            paint.setColor(Color.BLACK);
            paint.setTextSize(size);
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);
            canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
            super.onDraw(canvas);
        }
    }
}

我曾尝试从建议
http://stackoverflow.com/a/5369766/1815624

展望本

<一个href=\"http://stackoverflow.com/a/21895626/1815624\">http://stackoverflow.com/a/21895626/1815624

<一个href=\"http://stackoverflow.com/a/14753968/1815624\">http://stackoverflow.com/a/14753968/1815624

http://stackoverflow.com/a/21895626/1815624 &LT; - 现在正试图

http://stackoverflow.com/a/21895626/1815624 <-- trying now

推荐答案

使用资源:

http://stackoverflow.com/a/4847027/1815624

<一个href=\"http://stackoverflow.com/a/21895626/1815624\">http://stackoverflow.com/a/21895626/1815624

必须让屏幕宽度,文字大小的一些参考的屏幕比例,并计算。这样的结果是:

Got to get screen width, some reference of text size to screen ratio, and calculate. so the results are:

更好的结果

更好的结果

注意第二HELLOOOOOOOOOOOOOOOOO!

notice the second HELLOOOOOOOOOOOOOOOOO!

public class MainActivity extends Activity
{
    Paint paint;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        paint = new Paint();
        View test = new TestView(this);

        setContentView(test);
    }

    public class TestView extends View
    {

        public TestView(Context context)
        {
            super(context);
            setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        }

        public float pixelsToSp(float px) {
            Context context = getContext();
            float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
            return px/scaledDensity;
        }

        public float spToPixels(float sp) {
            Context context = getContext();
            float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
            return scaledDensity*sp;
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            int size = getResources().getDimensionPixelSize(R.dimen.sp20);
            int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
            Log.v("intSize", Integer.toString(size));
            Log.v("intSize", Integer.toString(px));
            Log.v("intSize", Float.toString(spToPixels(20f)));

            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);

            Log.v("intSize hm", Integer.toString(metrics.heightPixels));
            Log.v("intSize wm", Integer.toString(metrics.widthPixels));

            if(true) {
                Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
                paint.setTypeface(myTypeface);
            }
            paint.setColor(Color.BLACK);
            paint.setTextSize(size);
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);
            canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
            setTextSizeForWidth(paint, metrics.widthPixels * 0.5f, "HELLOOOOOOOOOOOOOO!");
            canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size*3, paint);
            super.onDraw(canvas);
        }
        /**
         * Sets the text size for a Paint object so a given string of text will be a
         * given width.
         *
         * @param paint
         *            the Paint to set the text size for
         * @param desiredWidth
         *            the desired width
         * @param text
         *            the text that should be that width
         */
        private void setTextSizeForWidth(Paint paint, float desiredWidth,
                                                String text) {

            // Pick a reasonably large value for the test. Larger values produce
            // more accurate results, but may cause problems with hardware
            // acceleration. But there are workarounds for that, too; refer to
            // http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
            final float testTextSize = 48f;

            // Get the bounds of the text, using our testTextSize.
            paint.setTextSize(testTextSize);
            Rect bounds = new Rect();
            paint.getTextBounds(text, 0, text.length(), bounds);

            // Calculate the desired size as a proportion of our testTextSize.
            float desiredTextSize = testTextSize * desiredWidth / bounds.width();

            // Set the paint for that size.
            paint.setTextSize(desiredTextSize);
        }

    }
}

请注意,如果你不扩大活动中使用

please note if you not extending Activity use

    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager windowManager = (WindowManager) context
            .getSystemService(Context.WINDOW_SERVICE);
    windowManager.getDefaultDisplay().getMetrics(metrics);

而不是

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

这篇关于与像素完美的文字canvas.drawText在画布上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆