[英]Android, manupulate camera preview frames
I want to make an Android application that uses the camera and applies image processing filters on the 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);
}
}
However, I see no changes in the emulator no matter what I do in the onPreviewFrame
method. 但是,无论我在
onPreviewFrame
方法中做什么,我都看不到模拟器中的任何变化。
Another option is to use the OpenCV framework, which has an Android port: 另一个选择是使用OpenCV框架,它有一个Android端口:
http://opencv.willowgarage.com/wiki/Android2.3.0 http://opencv.willowgarage.com/wiki/Android2.3.0
It's an NDK port of the open source Open Computer Vision project, and it'll take raw preview frames and allow for processing them with OpenCV before displaying them on a SurfaceView. 它是开源Open Computer Vision项目的NDK端口,它将采用原始预览帧并允许在使用OpenCV处理它们,然后在SurfaceView上显示它们。 Because it manipulates the frames it doesn't run at quite the same framerate as just a directly hooked in hardware optimized preview, but because so much of it is native it does a pretty good job.
因为它操纵帧,它的运行速度与硬件优化预览中直接连接的帧速率完全相同,但由于它本身的大部分是本机的,所以它做得非常好。
There's an OpenCV_Sample app in that version linked above which compiled into a demo app which can do much of what you're looking for. 在上面链接的那个版本中有一个OpenCV_Sample应用程序,它编译成一个演示应用程序,可以完成您正在寻找的大部分内容。 It has menu options to enable inverse, blur the image, or do edge detection on the preview area.
它具有菜单选项,可以在预览区域启用反转,模糊图像或进行边缘检测。 Even if it's not exactly what you want, there are some great samples in the source code to learn from.
即使它不是您想要的,也可以在源代码中学习一些很好的示例。
看到这个链接 ,我认为它与您想要实现的类似。
Well that's because the preview buffers that you are getting in the callback is only a copy of the preview buffers, hence any modifications that you do will not be displayed since the buffer that you get is your copy. 那是因为你在回调中得到的预览缓冲区只是预览缓冲区的副本,因此你所做的任何修改都不会显示,因为你得到的缓冲区是你的副本。 Mentioned in the android sdk here
这里提到android sdk
I am not sure how to do this but I have been giving it some thought on how to go about this and here is what I think should be done - 我不知道该怎么做但我已经考虑过如何解决这个问题,这就是我认为应该做的事情 -
UPDATE UPDATE
Revisiting the SDK documentation I found this API - setPreviewTexture
this API allows us to - "captures frames from an image stream as an OpenGL ES texture". 重新访问SDK文档我发现了这个API -
setPreviewTexture
这个API允许我们 - “将图像流中的帧捕获为OpenGL ES纹理”。 Once you have the images with the applied texture you can use OpenGL to display your frames. 使用应用的纹理获得图像后,可以使用OpenGL显示帧。 (Take a look at the answer posted by @Stephan on how to do this.)
(看看@Stephan发布的关于如何做到这一点的答案。)
NOTE - setPreviewTexture
is available from API level 11 onwards! 注意 -
setPreviewTexture
可从API级别11开始提供! SDK Link SDK链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.