I want to create an android app with a surfaceview that fills the left part of the screen and with another second surfaceview that fills the right part of the screen.
In both surfaceviews should be a preview of the camera. So that there are two exactly similar camera pictures side by side.
I tried it like this (i will remove the button and onclick part etc when i solved my surfaceview problem):
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView2 = (SurfaceView)findViewById(R.id.SurfaceView02);
surfaceHolder2 = surfaceView2.getHolder();
surfaceHolder2.addCallback(this);
surfaceHolder2.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
buttonStartCameraPreview.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(!previewing){
camera = Camera.open();
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.setPreviewDisplay(surfaceHolder2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
previewing = true;
}
}
}});
But obviously it just displays the preview in the "last" surfaceHolder (here: surfaceHolder2). I hope you can help me :)
Related
i need to capture image from required portion of the screen.
capture image from camera.
at that time other screen content as it is.
how is this possible?
try to use Surface View for creating dynamic camera view and set in your required portion.
following code try
variables set Class level (Global)
Button btn_capture;
Camera camera1;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
public static boolean previewing = false;
Following code in onCreate() method
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = new SurfaceView(this);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btn_capture = (Button) findViewById(R.id.button1);
surfaceView.setBackgroundResource(R.drawable.your_background_image);
if(!previewing){
camera1 = Camera.open();
if (camera1 != null){
try {
camera1.setDisplayOrientation(90);
camera1.setPreviewDisplay(surfaceHolder);
camera1.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
btn_capture.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if(camera != null)
{
camera1.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);
}
}
});
Following code put after onCreate() in your class.
ShutterCallback myShutterCallback = new ShutterCallback(){
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
Bitmap correctBmp = Bitmap.createBitmap(bitmapPicture, 0, 0, bitmapPicture.getWidth(), bitmapPicture.getHeight(), null, true);
}};
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera1.stopPreview();
previewing = false;
}
if (camera1 != null){
try {
camera1.setPreviewDisplay(surfaceHolder);
camera1.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera1.stopPreview();
camera1.release();
camera1 = null;
previewing = false;
}
in AndroidManifest.xml give user-permissions.
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
and also not forgot ( implements SurfaceHolder.Callback ) to the class.
I already created like that kind of Camera. What I did is, I covered the other area of the camera with an image, and cut the center part of the image and save it as png file, to make the center transparent.
You will set background image of your frame(camera preview) with that image. So that it will look like the camera is only that portion that is transparent or the circle.
I used this tutorial to open,create preview,and take picture from camera device
http://developer.android.com/guide/topics/media/camera.html
in this part(u can see this in the link I provide above)
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//this is where you crop your image
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true;
Bitmap bitmap = BitmapFactory
.decodeByteArray(data, 0, data.length, opt);
bitmap=Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas mcanvas=new Canvas(bitmap);
//do the cropping here, bitmap is the image you will use to crop
}
}
follow this tutorial on how to crop the image to circle
Cropping circular area from bitmap in Android
you can use surface view.after capture image u can get in bitmap and draw canvas also
http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)
http://developer.android.com/reference/android/view/SurfaceView.html#setZOrderMediaOverlay(boolean)
If the part of the screen is actually a view, you can capture only this view. Like this:
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(),Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
If you want to capture only small portion of a view, you have to calculate rectangle of this side. Then:
Bitmap bitmap = Bitmap.createBitmap(rect.width(),rect.height(),Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.save();
canvas.translate(-rect.left,-rect.top);
view.draw(canvas);
canvas.restore();
It's only a pseudocode, but I hope you get the idea. Simply translate and draw only the part you need.
I use the CameraPreview in ApiDemos application and edit it as your requirement.
First, copy the code of the Preview class into a new class file in the same package so that it is public and you can declare it in the xml layout file. Remember to add one more constructor as below:
public Preview(Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Sample layout file with sample width and height:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Abow"/>
<com.example.android.apis.graphics.Preview
android:id="#+id/camera_view"
android:layout_width="240dp"
android:layout_height="180dp">
</com.example.android.apis.graphics.Preview>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Below"/>
</LinearLayout>
In the onCreate() method of the CameraPreview activity, change the setContentView part as followed:
setContentView(R.layout.camera_layout);
mPreview = (Preview) findViewById(R.id.camera_view);
use TextureView for preview,set layout_width and layout_height what ever you want.
here is the code:
public class MainActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;
private TextureView mTextureView;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextureView = (TextureView) findViewById(R.id.textureView);
mTextureView.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(surfaceTexture);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException exception) {
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
mCamera.startPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
//To change body of implemented methods use File | Settings | File Templates.
}
}
and xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextureView
android:layout_gravity="center"
android:id="#+id/textureView"
android:layout_width="200dp"
android:layout_height="300dp"/>
</LinearLayout>
I have a project,where i have a button when the user click the button,then camera preview is set as wallpaper,can any one give me an idea how can i do that?
I am using Following code to camera preview
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera=camera;
// TODO Auto-generated constructor stub
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
Log.d("DEBUG", "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("DEBUG", "Error starting camera preview: " + e.getMessage());
}
}
}
But my problem was how to add the camera preview to WallpaperService?
First, when the user clicks the button, take a picture of the camera preview and find out the path where the picture is saved.
Then refer to this link to set a particular image as wallpaper by specifying its path.
How to set image as wallpaper programmatically?
You need to create a live wallpaper, with a WallpaperService. Then you'll need to have your service create its own rendering surface that it draws the camera preview into.
I am using Google's example for using CameraPreview Mode by using it in a ViewGroup. I like the idea of it, but I am trying to place views on top of it and the Camera always supersedes it. I removed the Camera to see my image below it (meaning the view is being added, it is just being added beneath the Camera, even though I place the Camera beneath the Image AND call bringChildToFront(myImageView) a million times.
public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
private DrawOnTop mDraw;
public ImageView myImageView;
CameraPreview(Context context) {
super(context);
myImageView = new ImageView(context);
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
Drawable drawable = new BitmapDrawable(bmp);
myImageView.setImageDrawable(drawable);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView,0);
addView(myImageView,1);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
Log.d("",drawable+"");
bringChildToFront(myImageView);
debug(2);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
bringChildToFront(myImageView);
}
public void switchCamera(Camera camera) {
setCamera(camera);
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
camera.setParameters(parameters);
mSurfaceView.setBottom(0);
bringChildToFront(myImageView);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
bringChildToFront(myImageView);
}
....
Anyone have any ideas?
The Answer is ViewGroup works from bottom up. Meaning that 0 is in fact the top most exposed view and not the bottom. I switched the order from:
addView(mSurfaceView,0);
addView(myImageView,1);
To:
addView(myImageView, 0);
addView(mSurfaceView, 1);
And it put the image on top. I spent way too much time working on this for that simple of an answer.
I created 3D object and I'm also displaying a camera preview. The CameraPreview is
displayed on a SurfaceView definded in the XML file, and the 3D object is displayed on a
framelayout defined in the XML file. I want to display the rotating 3D object over the
CameraPreview, but when I run the App, the CameraPreview is being displayed for few
seconds and after that the activity shows the 3D rotating object independent from the
cameraPreview, I mean, the rotating 3D object is not displayed on the Camerapreview
surface. Is there any way to fix this mistake?
Your help is highlu appreciated.
Code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mpinfo);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceView.setZOrderOnTop(true);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = android.hardware.Camera.open();
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer
glSurface.setRenderer(new Lesson05());
//Set the GLSurface as View to this Activity
fl01 = (FrameLayout) findViewById(R.id.fl01);
//setContentView(glSurface);
//fl01.addView(cameraSurface);
fl01.addView(glSurface);
}
xml File
<FrameLayout
android:id="#+id/fl01"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</FrameLayout>
<SurfaceView
android:id="#+id/camerapreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
In my android app i m using the camera and starting it programmatically .I run my code on samsung gt-s5360 ,but the view is rotated by 90 degree anti clock wise.my code works fine on HTC wildfire-s.On this device the camera view is showing correctly without rotating the view .But it is not showing the correct view on each device.So how can i write the code that works for all devices(android) .My android jar is 2.2 and API level is 8.Please help me .Here is my code.
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
int rotate=90;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
public static ArrayList<Activity> activities=new ArrayList<Activity>();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
activities.add(this);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Intent i=new Intent();
i.setClassName("a.b.c","a.b.c.DialPad");
startActivity(i);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
//this.camera.setDisplayOrientation(90);
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
//camera.setDisplayOrientation(90);
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
camera.setDisplayOrientation(rotate);
//Parameters p= camera.getParameters();
//p.setRotation(90);
/*if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
p.set("orientation", "portrait");
p.set("rotation",90);
Toast.makeText(getApplicationContext(), "Potrait Mode", Toast.LENGTH_SHORT).show();
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
p.set("orientation", "landscape");
p.set("rotation", 90);
Toast.makeText(getApplicationContext(), "Landscape Mode", Toast.LENGTH_SHORT).show();
}*/
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}