使用 getDrawingCache 时是否有最大位图大小? [英] Is there a maximum bitmap size when using getDrawingCache?

查看:16
本文介绍了使用 getDrawingCache 时是否有最大位图大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 TextView 中创建文本的位图.过去,我使用 getDrawingCache 完成了此操作.但是,现在我需要创建一个 TextView 的位图,其中的文本比以前长得多.这导致 getDrawingCache 抛出 NullPointerException.

I'm trying to create a bitmap of the text in a TextView. In the past I have done this using getDrawingCache. However, now I have a need to create a bitmap of a TextView with much longer text than before. This is causing getDrawingCache to throw a NullPointerException.

虽然我说的是更长的文本",但我并不是在说不合理的长.如果我创建一个宽度为 600 像素、字体大小为 24 的 TextView,我会在 53 行文本(但不是 52 行)处得到异常.有解决方法吗?

Although I say "much longer text," I am not talking about unreasonably long. If I create a TextView that is 600 pixels wide at size 24 font, I get the exception at 53 lines of text (but not at 52 lines). Is there a workaround for this?

起初我想到了这个答案,其中布局在画布上绘制自己,是解决方案.但是,这对我不起作用,因为我正在以编程方式创建 TextView 并且 宽度和高度在布局之前都是 0.我从来没有真正在屏幕上布置过我的 TextView.

At first I thought this answer, in which the layout draws itself on a canvas, was the solution. However, that didn't work for me because I am creating the TextView programmatically and the width and height are 0 before they get laid out. I never actually layout my TextView on screen.

private Bitmap getBitmap(Context context){

    final int NUMBER_OF_LINES = 53; // 53 crashes, 52 doesn't
    final int width = 600; // width of TextView in pixels
    final int fontSize = 24;

    // create string with NUMBER_OF_LINES
    StringBuilder testString = new StringBuilder();
    for (int i = 0; i < NUMBER_OF_LINES; i++) {
        testString.append("
");
    }

    // Create TextView
    TextView tvText = new TextView(context);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    tvText.setTextSize(fontSize);
    tvText.setWidth(width);
    tvText.setLayoutParams(params);
    tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
    tvText.setText(testString);

    // Create bitmap
    tvText.setDrawingCacheEnabled(true);
    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
    tvText.buildDrawingCache(true);
    Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache()); // crashes here
    tvText.setDrawingCacheEnabled(false);

    // This also didn't work because width and height are 0
    /*Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);*/

    return bitmap;
}

空指针异常

06-21 14:20:24.628    8036-8036/com.example.testsomecode E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testsomecode/com.example.testsomecode.MainActivity}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
        ...
 Caused by: java.lang.NullPointerException
        at android.graphics.Bitmap.createBitmap(Bitmap.java:494)
        at com.example.testsomecode.MainActivity.getBitmap(MainActivity.java:57) // -> Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache());
        at com.example.testsomecode.MainActivity.onCreate(MainActivity.java:25)
        ...

注意

这不是 IllegalArgumentException 或 OutOfMemoryError(至少不是外部的,尽管这可能是内部的原因.)

Note

This is not an IllegalArgumentException or OutOfMemoryError (At least not externally, though maybe this is the reason internally.)

推荐答案

您可以删除 buildDrawingCache 方法而只使用 canvas.由于您是以编程方式构建视图,因此您还需要在获取位图之前调用 measure()layout().

You can drop the buildDrawingCache method and just use canvas. Since you are building the view programmatically you also need to call measure() and layout() before you can get a bitmap.

关键行是:

    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
    Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);

这里是完整的例子:

private Bitmap getBitmap(Context context){

    final int NUMBER_OF_LINES = 153;
    final int width = 600;
    final int fontSize = 24;

    // create string with NUMBER_OF_LINES
    StringBuilder testString = new StringBuilder();
    for (int i = 0; i < NUMBER_OF_LINES; i++) {
        testString.append("
");
    }

    // Create TextView
    TextView tvText = new TextView(context);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    tvText.setTextSize(fontSize);
    tvText.setWidth(width);
    tvText.setLayoutParams(params);
    tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
    tvText.setText(testString);
    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());


    // Create the bitmap from the view
    Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);

    return bitmap;
}

这篇关于使用 getDrawingCache 时是否有最大位图大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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