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()?
Related
I created a burst camera and i want that when the activity starts, the camera starts taking pictures automatically without pressing any button.
It says: Unfortunately, FrontVerify has stopped when i try to put:
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
on the onCreate method.
The thing is: I want to create a series of photos ta simulate a button. When the user put the finger near the camera and it stays all black, i have the algorithm that tells me that BLACK = TRUE, so move on to the next activity. Therefore i don't need any physical or digital button, i could use the camera for that issue.
So the only way so far i made it work so far was with the onClick method and
i really want to get rid of the onClick method that is here:
public void onClick(View v) {
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
buttonClick.setEnabled(false);
}
And the algorithm for the burst camera is this one:
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// write to local sandbox file system
// outStream =
// CameraDemo.this.openFileOutput(String.format("%d.jpg",
// System.currentTimeMillis()), 0);
// Or write to sdcard
outStream = new FileOutputStream(String.format(
"/sdcard/eyeverify/still%d.jpg",
System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
try {
stillCount++;
camera.startPreview();
if (stillCount < 10) {
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
} else {
stillCount = 0;
buttonClick.setEnabled(true);
}
} catch (Exception e) {
Log.d(TAG, "Error starting preview: " + e.toString());
}
}
};
}
So i cant figure it out, how to start the App and the camera start bursting automatically.
Just:
new Handler().postDelayed(new Runnable(){
public void run(){
yourBtn.performClick();
}
}, 1000).
Call this in your OnStart or you OnCreate:
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
Depending on how you want to manage your app on OnPause and OnResume it may be better to put it into OnResume. If you want it to start with the camera burst whenever paused, or just when first launched.
I would also ensure you clean up your resources in OnStop.
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()
I want my app to be able to capture photos without using another application. The code i used :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = null;
try
{
photo = this.createTemporaryFile("picture", ".jpg");
photo.delete();
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
mImageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
But this code uses the phone's main camera app. Can anyone give me some code ?
Taking a picture directly using the Camera class is insanely complicated to get right.
I am working on a library to simplify this, where you just add a CameraFragment to your app for the basic preview UI, and call takePicture() on it to take a picture, with various ways to configure the behavior (e.g., where the pictures get saved). However, this library is still a work in progress.
Can anyone give me some code ?
"Some code" is going to be thousands of lines long (for a complete implementation, including dealing with various device-specific oddities).
You are welcome to read the Android developer documentation on the subject.
once you have the camera preview set, you need to do the following...
protected static final int MEDIA_TYPE_IMAGE = 0;
public void capture(View v)
{
PictureCallback pictureCB = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera cam) {
File picFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (picFile == null) {
Log.e(TAG, "Couldn't create media file; check storage permissions?");
return;
}
try {
FileOutputStream fos = new FileOutputStream(picFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found: " + e.getMessage());
e.getStackTrace();
} catch (IOException e) {
Log.e(TAG, "I/O error writing file: " + e.getMessage());
e.getStackTrace();
}
}
};
camera.takePicture(null, null, pictureCB);
}
And the getOutputMediaFile function:
private File getOutputMediaFile(int type)
{
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), getPackageName());
if (!dir.exists())
{
if (!dir.mkdirs())
{
Log.e(TAG, "Failed to create storage directory.");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss", Locale.UK).format(new Date());
if (type == MEDIA_TYPE_IMAGE)
{
return new File(dir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
}
else
{
return null;
}
}
And you are done!!!
found it here
Camera was deprecated in API 21, the new way is the use android.hardware.camera2.
To enumerate, query, and open available camera devices, obtain a CameraManager instance.
To quickly summarize:
Obtain a camera manager instance by calling Context.getSystemService(String)
Get a string[] of device camera IDs by calling CameraManager.GetCameraIdList().
Call CameraManager.OpenCamera(...) with the desired camera ID from the previous step.
Once the camera is opened, the callback provided in OpenCamera(...) will be called.
I get a green screen with the front camera from samsung galaxy s, but the preview is correct. With the Back-Camera can I make photos.
Where is the problem?
This is my PictureCallback:
public void onIvButtonShutterClick(View view) {
PictureCallback pictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
File picture = new File(My_Camera.this.getFilesDir()
+ "/bild.jpg");
FileOutputStream pictureOut = new FileOutputStream(picture);
pictureOut.write(data);
pictureOut.flush();
pictureOut.close();
Toast.makeText(
My_Camera.this,
getResources().getString(
R.string.tx_my_camera_save)
+ "\n" + picture.getAbsolutePath(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
//mCamera.startPreview(); // Preview wird weiter ausgeführt
}
};
mCamera.takePicture(null, null, pictureCallback);
}
I access on the front camera with:
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mParameters = mCamera.getParameters();
mParameters.set("camera-id", 2);
mParameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setDisplayOrientation(270);
mCamera.setParameters(mParameters);
mCamera.startPreview();
}
I had the same problem but never found a real solution.
What I ended up using was to grab frames from the camera preview. This has some issues – like, pictures are much more likely to be blurry.
The relevant method for grabbing preview frames is Camera.setOneShotPreviewCallback.
I think the problem might be the processing of the result. I'm guessing you are sending the originally captured byte array containing the raw image data to a file with jpg extension, but the byte array is not in jpg data (i.e. missing headers and with uncompressed content).
Here's a relevant piece from some code I have (the MeToo project that you saw), imageData being the raw content:
Bitmap backCameraImage = BitmapFactory.decodeByteArray(imageData,
0, imageData.length).copy(Bitmap.Config.RGB_565, true);
FileOutputStream out = null;
out = new FileOutputStream(file);
backCameraImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
Hope this helps...
Did you try to set this parameter:
mParameters.setPreviewFormat(PixelFormat.JPEG);
It helped me, but on Motorola Droid causing problems.
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)