【问题标题】:Is there a maximum bitmap size when using getDrawingCache?使用 getDrawingCache 时是否有最大位图大小?
【发布时间】:2015-06-21 06:31:37
【问题描述】:

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

虽然我说的是“更长的文本”,但我并不是在说不合理的长。如果我创建一个 600 像素宽、24 号字体的 TextView,我会在 53 行文本处出现异常(但不是在 52 行处)。有解决办法吗?

起初我认为this answer 是解决方案,其中布局将自身绘制在canvas 上。但是,这对我不起作用,因为我正在以编程方式创建 TextView 和 the width and height are 0 在它们布局之前。我从来没有真正在屏幕上布置我的TextView

参考代码

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("\n");
    }

    // 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(至少不是外部原因,尽管这可能是内部原因。)

【问题讨论】:

  • 文本视图是添加到某个容器中的,比如相对布局还是线性布局?
  • tvText.getDrawingCache() 返回 null。
  • 尝试将您的 textview 添加到容器中,然后获取 textview 的测量值。那么你应该能够得到位图
  • 调用tvText.layout()后只需创建一个Bitmap,然后基于该Bitmap创建一个Canvas,最后调用tvText.draw(),@Raghunandan 无需将视图添加到任何容器
  • @pskinkn 我认为测量的宽度和高度为零。我从来没有想过把它画到画布上

标签: android bitmap nullpointerexception textview


【解决方案1】:

您可以放弃buildDrawingCache 方法而只使用canvas。由于您正在以编程方式构建视图,因此您还需要调用 measure()layout() 才能获得位图。

重点是:

    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("\n");
    }

    // 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2021-04-14
    相关资源
    最近更新 更多