how to display two surfaces over each other? - android

I have a 3D cube and I open the camera preview, and I want to see this rotating cube displayed over the camera.
What I attempted is, inside the SurfaceChanged method of the class that implements surfaceHolder.callback, I call camera.setPreviewCallback(new PreviewCallback(){ }
as follows:
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
.......
.......
.......
camera.setPreviewCallback(new PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
glSurface.setRenderer( new MyRender());
setContentView(glSurface);
}
});
This code results in, displaying the camera preview for a few seconds until the surface is changed, then, the camera preview disappears and the 3D cube appears on a black background.
Is there anyway to show both surfaces?

As far as I recall, you have to set the CameraPreview ontop of the GlView. Thats not intuitive, but should work.
here is a link that may help you: http://digitalbreed.com/2009/android-render-opengl-on-top-of-camera-preview

You can do your own offscreen compositing, then draw the result into a single SurfaceView. See this sample code for details.

Related

GLSurfaceView switching issue

I am having an issue with while switching GLSurfaceView. I have a GLSurfaceView (connected with Camera) and I want to move it to another view , but when I am moving it it's losing its frames and showing blackScreen after switching. and when I am reconnecting it to Camera, it starts show my Camera but with delay.
Could any one please tell me solution to move it to another parent without losing its frames (because when I am reconnecting it its showing frames with 2-3 seconds delay).
Please find code written below :
(Here VideoPanel (extends GLSurfaceView) is Frame provided by oovooSDK to show video)
final VideoPanel movingVideoView = parent1.getChildAt(0);
movingView.onPause();
parent1.removeView(movingView);
parent2.addView(movingView);
movingView.onResume();
movingView.requestRender();
for reconnecting :
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
// this methods shows delay of 2-3 seconds for binding view again
I tried following methods also
((VideoPanel) videoView.videoRender).setPreserveEGLContextOnPause(true);
// to save context when paused
((VideoPanel)videoView.videoRender).setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // to render frame again when requestRender is called
Camera is not proper release when your activity going to end.
If you are using a Surface view than release your camera in onSurfaceDestroy
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
Also recommend a release your camera if it's not ever going to use.
protected void onDestroy(){
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}

How can i monitor the current FocalLength of android Camera

I have a SurfaceView that holds a Camera Preview. I have set the camera focus mode to: Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
and added an AutoFocus callback. When i run the app, i can see the camera adjusting its' focus in real time, but the autoFocusCallback only ever gets fired once, and when it does, it always returns the same value. (2.95) regardless of how close or far i am from an in focus object.
Wondering what i am doing wrong.. is it even possible to get real time info on what the actual focal length is?
my SurfaceView, onSurfaceChanged code:
SurfaceHolder.Callback surfaceHolderListener = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
camera=Camera.open();
try {
camera.setPreviewDisplay(previewHolder);
camera.setDisplayOrientation(90);
}
catch (Throwable e){ }
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Parameters params = camera.getParameters();
Rect centralFocusArea = new Rect();
centralFocusArea.set(holder.getSurfaceFrame().width()/2-10, holder.getSurfaceFrame().height()/2-10, holder.getSurfaceFrame().width()/2+10, holder.getSurfaceFrame().height()/2+10);
ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
focusAreas.add(new Camera.Area(centralFocusArea, 1000));
//params.setPreviewSize(width, height);
params.setPictureFormat(PixelFormat.JPEG);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
// params.setFocusAreas(focusAreas);
camera.setParameters(params);
camera.startPreview();
camera.autoFocus(new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
Log.v("CAMERA", "FOCUS CHANGE:"+camera.getParameters().getFocalLength());
camera.getParameters().setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
});
}
public void surfaceDestroyed(SurfaceHolder arg0)
{
camera.stopPreview();
camera.release();
}
};
Maybe you are confusing two different concepts: focus distance and focal length.
It seems you are interested in the focus distance, i.e. the distance for which the optical system has perfect focus; this depends on how far or close you are from in focus objects.
On the contrary, the focal length is an intrinsic property of the optical system (i.e. of the camera lenses), and it is fixed in most standard mobile devices (optical zoom capabilities are needed to have a variable focal length).
The value you get, 2.95, is the focal length (in mm) of your camera. Nexus 7 2013 tablets have such focal length.
Thus, it is perfectly normal that the function getFocalLength() always gives you the same value.
Most Android implementations do not provide a proper value for the focus distance, despite the parameter being well-defined in the Android specification. Some time ago, I checked three different cameras, and none of them provided useful information.

How to get current view of android screen

I am developing an Android application which should record a video. There are certain classes that I cannot change due to restrictions of the project, like Preview and VideoRec classes.
Application has one main screen activity and there is a toggle button. Whenever toggle button is checked, video recording should start and vice versa for the unchecked state.
However, VideoRec class' constructor takes a View type parameter for input (VideoRec(View x)). Main activity's screen has a surfaceview and several buttons. What I am trying to do is to just initiate video recording on the same screen, just like the default mediarecorder application of any phone.
My question is; I keep on failing to obtain the View of the screen. I can't use preview or surfaceView types, I get errors saying either classCast Exceptions or invalid preview/surface preview.
Long story short, how can i get the activity's screen as a type of View?
you can provide a public method in your Main Activity which returns the view you need.
Obviously you have to save a reference of that view in your onCreate method activity:
View myView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.the_layout_id);
myView = (View)findViewByID(R.id.your_id_view);
}
public View getTheView(){
return myView;
}
What I understand is you have 1 surfaceview where reproducing what you are recording.
So you must attach your PreviewCallback in the surfaceChanged(...) SurfaceHolder.Callback! After doing this, you'll continue to get preview frame data after a MediaRecorder is running!
For example:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] _data, Camera _camera) {
Log.d("onPreviewFrame-surfaceChanged",String.format("Got %d bytes of camera data", _data.length));
}
});
}
Hope it helps!Cheers

Android Camera Surface View

I am trying to create a surface view for a camera so it renders on the surface whenever is in the view of the camera. At the moment all I can see on my camera view is a black screen view. I have tried to look on Google and here but so far I haven't found what I am looking for. Anyone can suggest me some idea.
I have written a class that can help you.
public class Preview_can_work extends Activity {
private SurfaceView surface_view;
private Camera mCamera;
SurfaceHolder.Callback sh_ob = null;
SurfaceHolder surface_holder = null;
SurfaceHolder.Callback sh_callback = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
if (surface_holder == null) {
surface_holder = surface_view.getHolder();
}
sh_callback = my_callback();
surface_holder.addCallback(sh_callback);
}
SurfaceHolder.Callback my_callback() {
SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mCamera.startPreview();
}
};
return ob1;
}
}
in your manifest file copy this code for camera permission
<uses-permission android:name="android.permission.CAMERA"/>
Explanation:
SurfaceView is a type of View which contains a SurfaceHolder. SurfaceHolder holds the surface on which we can display our media (generally frames).
mCamera is a Camera object which will contains the camera instance.
When you want to hold default Camera instance then you can simply call Camera.open();
Camera mCamera = Camera.open();
Now you have an open camera or you are having default camera instance. Now you need to capture frames from the camera and display it on a surface. But you cannot display it without any
surface. Here the surfaceView provides surfaceHolder and surfaceHolder provides surface to display camera frames. Now when surface will be created three callback functions will be
called.
1. public void surfaceCreated(SurfaceHolder holder)
2. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
3. public void surfaceDestroyed(SurfaceHolder holder)
Note:- Surface will be destroyed when your application will go on pause.
surfaceCreated:
surfaceCreated is a callback function which will be called when your surface will be created. In this, you can open your camera and set other attributes.
surfaceChanged:
This will be called atleast one time when your surface will be created. After that it will be called whenever your surface will change(In device rotation). Here you can
start your preview because your surface have already created.
surfaceDestroyed:
This will be called every time when your surface will destroy. Now if you dont have surface then where you can display you camera frames so I have released camera by using
mCamera.release(). This is very important because if your activity will be on pause and any other activity tries to open camera then it will not able to open it as you have
already open camera. Camera is a shared resource so one time only one application can use it. So remember one thing whenever you open a camera then always release it.
stopPreview:
When you start preview then your camera starts capturing your frames and display it on a surface. Now if your surface have destroyed then you need to stop capturing frames
from camera so you have to call mCamera.stopPreview.
Make shure you added the permission :
<uses-permission android:name="android.permission.CAMERA"/>
Also these window properties:
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Post some code if that doesn't work in order to help you

Processing camera frames on Android

i want to use my android phone to process image, for example, make any
operation with de frame and show it with the change (show the image in
black/white, grayscale, sepia, etc).
This is my code:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback,PreviewCallback {
SurfaceHolder mHolder;
Camera mCamera;
private Parameters parameters;
private Size previewSize;
private int[] pixels;
public CameraPreview(Context context) {
super(context);
SurfaceHolder mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
this.setFocusable(true);
this.requestFocus();
}
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
}
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
setImageSize();
mCamera.startPreview();
mCamera.setPreviewCallback(this);
}
public void onPreviewFrame(byte[] data, Camera camera) {
// transforms NV21 pixel data into RGB pixels
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
//here process the image
}
}
the problem is that i don't know how to show the new image processed.
In onPreviewFrame I convert yuv to rgb, then I process the image i.e.
convert in grayscale, but what i do for show the new image?
I need help, thanks!!!!!!!!!!!
You may want to consider using OpenCV or looking at one of their samples for image manipulations:
http://opencv.itseez.com/doc/tutorials/introduction/android_binary_package/android_binary_package.html
I read an article at: http://nhenze.net/?p=107
From what I read in the post, it's not very easy to do, because the onPreviewFrame is not synced with displaying the frames.
Instead, they use a trick to set another view on top of the SurfaceView. On that new View, they render images on an OpenGL texture with OpenGL ES.
I haven't played with it myself, but hope this will put you in the right direction.

Categories

Resources