【问题标题】:Null bitmap in Android SurfaceviewAndroid Surfaceview中的空位图
【发布时间】:2015-08-23 18:33:32
【问题描述】:

我正在尝试从 Android 中的相机预览中获取位图,然后检查位图并根据相机所看到的内容在屏幕上绘制一些内容。由于我正在从事的项目的性质,这一切都必须现场完成。

目前我正在使用表面视图来显示实时预览,并且我正在使用我在此处的单独问题上找到的以下代码获取位图。

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    snipeCamera.setPreviewCallback(new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            Camera.Parameters parameters = camera.getParameters();

            int width = parameters.getPreviewSize().width;
            int height = parameters.getPreviewSize().height;

            ByteArrayOutputStream outstr = new ByteArrayOutputStream();
            Rect rect = new Rect(0, 0, width, height);
            YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width, height, null);
            yuvimage.compressToJpeg(rect, 100, outstr);
            Bitmap bmp = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());

            bit = bmp.copy(Bitmap.Config.ARGB_8888, true);

        }
    });
}

位是:

public static Bitmap bit;

每当我尝试在其他任何地方访问此位图时,都会收到空异常错误。我猜这与它被设置在 setPreviewCallback 中的事实有关,但我对 Android 的了解不够,无法修复它。我可以做些什么来访问这个位图吗?还是有其他方法可以处理相机所见内容的实时位图?

【问题讨论】:

  • “我猜这与它被设置在 setPreviewCallback 中的事实有关”——更重要的是,它还没有被设置。 “我可以做些什么来访问这个位图吗?” -- 将您的代码直接或通过onPreviewFrame() 放入现有的onPreviewFrame() 方法中,并去掉static Bitmap。或者,如果使用位图完成的工作可能比您在主应用程序线程上花费的时间更长,请使用AsyncTask 或其他方式来完成这项工作。
  • 除此之外,使用调试器或Log 语句来确认您的decodeByteArray() 方法正在被调用并返回非null Bitmap,并摆脱@987654331 @调用以节省堆空间和CPU时间。
  • 如果我将我的代码放在现有的 OnPreviewFrame() 方法中,我不能在屏幕上绘制,可以吗?
  • "如果我把我的代码放在现有的 OnPreviewFrame() 方法中,我不能在屏幕上绘图,对吗?" -- 在主应用程序线程上调用onPreviewFrame(),或者不调用。如果在主应用程序线程上调用它,欢迎您更新您的 UI。如果没有,您可以使用事件总线,或post(),或runOnUiThread(),或Handler,安排在主应用程序线程上运行一些代码。
  • 抱歉,我的回答不清楚。现在,surfaceview 被锁定以进行绘图,因为相机一直在锁定它。我最初的想法是获取这个位图,修改我需要的像素,然后使用单独的表面绘制它。我无法将这些数据传递给单独的视图。我可以在这个函数内绘制到表面吗?

标签: android bitmap android-camera


【解决方案1】:

我可以做些什么来访问这个位图吗?

您已经可以访问您的Bitmap。您是从decodeByteArray() 获取的。

(请注意,我假设导致并包括 decodeByteArray() 的代码是正确的 - 可能还有其他问题潜伏在那里)

您只需要在您的onPreviewFrame() 方法中使用Bitmap。如果你要做的工作很快(亚毫秒),可能就在那儿做那个工作。如果您的工作不是那么快,您现在需要制定后台线程计划,安排使用主应用程序线程上的工作结果更新您的 UI,以及相关问题。

如果要使用 Bitmap,您需要访问相机 UI 中的其他对象,只需确保 SurfaceHolder 具有对这些其他对象的引用。您的onPreviewFrame() 方法位于SurfaceHolder 内的匿名内部类中,并且onPreviewFrame() 可以访问SurfaceHolder 拥有的所有内容。

【讨论】:

  • 显然我的位图代码有一些奇怪的问题,它返回 null。否则,这对我有用。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
相关资源
最近更新 更多