繁体   English   中英

Android,manpulate相机预览帧

[英]Android, manupulate camera preview frames

我想制作一个使用相机的Android应用程序,并在预览帧上应用图像处理过滤器。

package alex.filter;

import java.io.IOException;

import android.content.Context;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

class Preview extends SurfaceView implements SurfaceHolder.Callback {

    SurfaceHolder mHolder;
    public Camera camera;

    Preview(Context context) {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {        
        camera = Camera.open();        

        try {
            camera.setPreviewDisplay(holder);

            camera.setPreviewCallback(new PreviewCallback() {
                public void onPreviewFrame(byte[] data, Camera arg1) {                    
                    for( int i = 0 ; i < data.length ; i ++ ){
                        data[ i] = 0; // or some sirius filter
                    }                                                            
                    Preview.this.invalidate();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        }

    public void surfaceDestroyed(SurfaceHolder holder) {        
        camera.stopPreview();        
        camera = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(w, h);
        camera.setParameters(parameters);
        camera.startPreview();
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);        
    }
}

但是,无论我在onPreviewFrame方法中做什么,我都看不到模拟器中的任何变化。

另一个选择是使用OpenCV框架,它有一个Android端口:

http://opencv.willowgarage.com/wiki/Android2.3.0

它是开源Open Computer Vision项目的NDK端口,它将采用原始预览帧并允许在使用OpenCV处理它们,然后在SurfaceView上显示它们。 因为它操纵帧,它的运行速度与硬件优化预览中直接连接的帧速率完全相同,但由于它本身的大部分是本机的,所以它做得非常好。

在上面链接的那个版本中有一个OpenCV_Sample应用程序,它编译成一个演示应用程序,可以完成您正在寻找的大部分内容。 它具有菜单选项,可以在预览区域启用反转,模糊图像或进行边缘检测。 即使它不是您想要的,也可以在源代码中学习一些很好的示例。

看到这个链接 ,我认为它与您想要实现的类似。

那是因为你在回调中得到的预览缓冲区只是预览缓冲区的副本,因此你所做的任何修改都不会显示,因为你得到的缓冲区是你的副本。 这里提到android sdk

我不知道该怎么做但我已经考虑过如何解决这个问题,这就是我认为应该做的事情 -

  • 注册预览缓冲区
  • 禁用默认预览显示
    • 如果你没有将预览显示设置为表面,那么你不应该得到任何显示(但我不确定它是否会起作用 - 在某个论坛中读过它无法回想起来源)
    • 如果以上不起作用,那么我们将不得不隐藏视图(我知道几乎没有效率,但我想不出别的......)
  • 降低预览的帧率,这样我们就不会被缓冲区所淹没
  • 现在要显示我们的缓冲区,我们可以使用默认的位图绘制功能,也可以使用opengl来显示缓冲区。 但是到目前为止我还没用过,所以甚至不知道它是否可行,对此有什么想法?

UPDATE
重新访问SDK文档我发现了这个API - setPreviewTexture这个API允许我们 - “将图像流中的帧捕获为OpenGL ES纹理”。 使用应用的纹理获得图像后,可以使用OpenGL显示帧。 (看看@Stephan发布的关于如何做到这一点的答案。)

注意 - setPreviewTexture可从API级别11开始提供! SDK链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM