I am trying to create a Camera that defaults to the back camera (rather then the front) if it available, but I cannot get a preview to display. I have seen many guides on SO (and followed some of them to create what I have now) as well as the Android api, yet I couldnt find an easy way to specify which camera to use. Can someone give me a way to do that, or tell me what is wrong with the code below?
public Camera backCam()
{
Camera cam;
try{
cam=Camera.open(0);
return cam;
}catch(Exception e){}
try{
cam=Camera.open(1);
return cam;
}catch(Exception e){}
cam=Camera.open();
return cam;
}
public void sneakyCamera()
{
try{
Log.i("aaa","init camera. total cams: "+Camera.getNumberOfCameras());
Camera cam=backCam();
SurfaceView view=new SurfaceView(getApplicationContext());
cam.setPreviewDisplay(view.getHolder());
cam.startPreview();
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
File picFile = new File("/mnt/sdcard/","psychPic"+getTime()+".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(picFile);
fos.write(data);
fos.close();
} catch (IOException e) {
Log.i("aaa","pic tken error: "+e);
}
}
};
//shuttr callback, pic callback raw, pic callback
cam.takePicture(null, null,mCall);
}catch(Exception e)
{
Log.i("aaa","Camera error: "+e);
}
}
This sneakyCamera() is probably called from Activity onCreate(). This method creates a view, but to see preview, you have to add this view to the window hierarchy.
The easiest fix would be to add
parentActivity.setContentView(view);
before the call
cam.setPreviewDisplay()
Related
I want to take picture using camera app built in the device with touch event even though device doesn't support that function.
What i want to realize is following.
1) When I open the native or any other camera app,
2) Take a picture with touch event instead of camera button ( This part is what i want to develop)
Below code is What I try for this.
I tried to call transparent Activity on the camera app,
and When I get a touch event on the that Activity,
I call Take_picture() function.
But camera.takePicture() function in the Take_picture doesn't work. ( actually it doesn't call jpegCallback function)
private void Take_picture(){
camera = Camera.open();
if(camera != null)
{
camera.takePicture(null, null, jpegCallback);
}
}
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SaveImageTask().execute(data);
}
};
private class SaveImageTask extends AsyncTask<byte[], Void, Void> {
#Override
protected Void doInBackground(byte[]... data) {
FileOutputStream outStream = null;
System.out.println("66666");
// Write to SD Card
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/camtest");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
outStream.flush();
outStream.close();
//Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
//refreshGallery(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
}
I couldn't get any information How to I control native camera app for take picture instantly.
Please help.
How to I control native camera app for take picture instantly.
You can't. You are welcome to create your own camera app that takes pictures however you want. The authors of other camera applications are welcome to implement their camera apps however they want, and they do not have to provide any means for other developers to dictate when and how the pictures are taken.
But camera.takePicture() function in the Take_picture doesn't work
Your app should be crashing, as you should not have a valid Camera object. Only one app can use the camera at a time.
I am trying to take a picture without preview, immediately when my application starts running and after that to save the picture in new folder - "pictures123", in the root folder.
Could someone please tell me what's wrong in my code?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File directory = new File(Environment.getExternalStorageDirectory() + "/pictures123/");
if (!directory.exists()) {
directory.mkdir();
}
Camera camera = Camera.open(0);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
SurfaceView mview = new SurfaceView(getBaseContext());
camera.setPreviewDisplay(mview.getHolder());
camera.setPreviewDisplay(null);
camera.startPreview();
camera.takePicture(null,null,photoCallback);
camera.stopPreview();
}
Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/pictures123");
File file = new File (myDir, "pic1.jpeg");
FileOutputStream out = new FileOutputStream(file);
out.write(data);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
finish();
}
};
permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
You can't take a picture without a preview, but you don't have to show the preview on screen. You can direct the output to a SurfaceTexture instead (API 11+).
See this answer for more details.
I think the main problem is that you are calling takePicture immediately after startPreview which actually takes time to complete its setup. So adding a delay between those two could temporarily fix this issue, look here for more details.
It's impossible to take a picture without preview. You should read the Android online reference: http://developer.android.com/reference/android/hardware/Camera.html#takePicture.
Note:
This method is only valid when preview is active (after startPreview()). Preview will be stopped after the image is taken; callers must call startPreview() again if they want to re-start preview or take more pictures. This should not be called between start() and stop().
I'm doing an app, that needs the device(usually a tablet) to be in landscape, but the picture has to be shown in portrait in the screen.
Until here, I have done it. Bu now, when I take a picture the "preview" image, is showed in landsacape and looks very strange.
See image to see what I mean:
How you see before take image:
And thats after take picture:
And I don't know how to fix it
Thats surfaceView:
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// stop Preview Before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignored: is trying to stop a non-existent preview
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d("CAMERAPREVIEW", "Error starting camera preview : " + e.getMessage());
}
}
And the method overrided
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
// Not used for the moment
// Intent returnIntent = new Intent();
// setResult(RESULT_CANCELED, returnIntent);
// finish();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
You can use Camera.setDisplayOrientaion() to rotate the preview on the SurfaceView. But this does not effect the captured image. Your post does not reveal how you display the captured image from file (I assume this is what you show in the second picture). If you load it as a bitmap into an ImageView, you can request rotation for the bitmap.
It also looks like your picture dimensions have different aspect ratio from the preview. I suggest that you look at a recent discussion here.
But maybe I misunderstand what you are doing. Maybe your problem is that you don't restart preview in onPicturetaken()?
How can i capture a picture from front camera without preview and save it to SD card.
Kindly help me with source code.
public void takePictureNoPreview(Context context){
// open back facing camera by default
Camera myCamera=Camera.open();
if(myCamera!=null){
try{
//set camera parameters if you want to
//...
// here, the unused surface view and holder
SurfaceView dummy=new SurfaceView(context)
myCamera.setPreviewDisplay(dummy.getHolder());
myCamera.startPreview();
myCamera.takePicture(null, null, getJpegCallback()):
}finally{
myCamera.close();
}
}else{
//booo, failed!
}
private PictureCallback getJpegCallback(){
PictureCallback jpeg=new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream fos;
try {
fos = new FileOutputStream("test.jpeg");
fos.write(data);
fos.close();
} catch (IOException e) {
//do something about it
}
}
};
}
}
Not possible, however, there's work-arounds.
See this previous answer, and please, try searching before asking in the future: https://stackoverflow.com/a/3881027/181002
I'm trying to capture an image using Android Camera via simple activity.
Image is clicked and stored. But the problem is, image is either distorted or fragments of older image is concatenated with the currently clicked image. Image is too dark. Here's the CODE : -
public class Cameras extends Activity {
public Camera camera;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
camera=Camera.open();
camera.lock();
Parameters parameters = camera.getParameters();
parameters.setJpegQuality(1);
parameters.setJpegThumbnailQuality(1);
parameters.setJpegThumbnailSize(0,0);
parameters.setSceneMode("night");
parameters.setFocusMode("fixed");
parameters.setPictureSize(640,480);
camera.setParameters(parameters);
camera.takePicture(null,null, jpegCallback);
}
PictureCallback jpegCallback = new PictureCallback() { // <8>
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// Write to SD Card
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg",System.currentTimeMillis())); // <9>
outStream.write(data);
outStream.close();
camera.unlock();
camera.release();
Toast.makeText(Cameras.this,"Picture Taken",Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally
{
}
}
};
}
Please help regarding this...
I want a neat and clean small size image every time i execute the code.
Thanks... :-)
parameters.setJpegQuality(1);
parameters.setJpegThumbnailQuality(1);
You are requesting very low quality. Try using higher values for quality (like 70)