I am working on an app for android that uses the front facing camera to simulate a mirror for the user. I need the app to take a picture every 5 seconds as a bitmap(automatically and without user interaction), which I then combine with another bitmap later on.
The difficult part for me: How to take a picture and get it as a bitmap?
I tried several solutions, but none have worked yet.
The other question that this is marked as a duplicate for is for doing this manually and not automatically.
Intent camera_intent = new Intent(MediaStore. ACTION_IMAGE_CAPTURE); startActivityForResult(camera_intent, pic_id); Now use the onActivityResult() method to get the result, here is the captured image.
I used the following code to show live camera feed in a layout background and the button saves the image as jpeg. Try and modify it as you wish : You can download the entire test project here so that you can test it fast : http://www.4shared.com/rar/v-ZQPybcce/Test.html
--->>The difference of this code from others using intents is that it takes the picture automatically without opening the camera app which makes the app look better :) <----
package com.mreprogramming.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
public class CameraActivity extends Activity implements SurfaceHolder.Callback{
protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
private SurfaceView SurView;
private SurfaceHolder camHolder;
private boolean previewRunning;
private Button button1;
final Context context = this;
public static Camera camera = null;
private ImageView camera_image;
private Bitmap bmp,bmp1;
private ByteArrayOutputStream bos;
private BitmapFactory.Options options,o,o2;
private FileInputStream fis;
ByteArrayInputStream fis2;
private FileOutputStream fos;
private File dir_image2,dir_image;
private RelativeLayout CamView;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
CamView = (RelativeLayout) findViewById(R.id.camview);
SurView = (SurfaceView)findViewById(R.id.sview);
camHolder = SurView.getHolder();
camHolder.addCallback(this);
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
button1 = (Button)findViewById(R.id.button_1);
camera_image = (ImageView) findViewById(R.id.camera_image);
button1.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
button1.setClickable(false);
button1.setVisibility(View.INVISIBLE); //<-----HIDE HERE
camera.takePicture(null, null, mPicture);
}
});
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if(previewRunning){
camera.stopPreview();
}
Camera.Parameters camParams = camera.getParameters();
Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
camParams.setPreviewSize(size.width, size.height);
camera.setParameters(camParams);
try{
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning=true;
}catch(IOException e){
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) {
try{
camera=Camera.open();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
finish();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera=null;
}
public void TakeScreenshot(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
int nu = preferences.getInt("image_num",0);
nu++;
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("image_num",nu);
editor.commit();
CamView.setDrawingCacheEnabled(true);
CamView.buildDrawingCache(true);
bmp = Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(false);
bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
fis2 = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="MyImage"+picId+".jpeg";
dir_image = new File(Environment.getExternalStorageDirectory()+
File.separator+"My Custom Folder");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis2.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis2.close();
fos.close();
Toast.makeText(getApplicationContext(),
"The file is saved at :/My Custom Folder/"+"MyImage"+picId+".jpeg",Toast.LENGTH_LONG).show();
bmp1 = null;
camera_image.setImageBitmap(bmp1);
camera.startPreview();
button1.setClickable(true);
button1.setVisibility(View.VISIBLE);//<----UNHIDE HER
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
dir_image2 = new File(Environment.getExternalStorageDirectory()+
File.separator+"My Custom Folder");
dir_image2.mkdirs();
File tmpFile = new File(dir_image2,"TempImage.jpg");
try {
fos = new FileOutputStream(tmpFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmp1 = decodeFile(tmpFile);
bmp=Bitmap.createScaledBitmap(bmp1,CamView.getWidth(), CamView.getHeight(),true);
camera_image.setImageBitmap(bmp);
tmpFile.delete();
TakeScreenshot();
}
};
public Bitmap decodeFile(File f) {
Bitmap b = null;
try {
// Decode image size
o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int IMAGE_MAX_SIZE = 1000;
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
// Decode with inSampleSize
o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
}
This is the camera.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camview">
<SurfaceView
android:id="@+id/sview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="@+id/camera_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/app_name" />
<Button
android:id="@+id/button_1"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
Add this to your manifest :
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Also in the manifest add the following to the "CameraActivity" activity tab to make sure that your activity will always be in landscape orientation because otherwise holding the phone in protrait(upright) unless you change the code it will reverse the image's aspect ratio and severely distort it.
<activity
android:name="com.mreprogramming.test.CameraActivity"
android:label="@string/app_name"
android:screenOrientation="landscape" > <-------ADD THIS ---!!!!!
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
And save this as styles.xml to make your layout fullscreen
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.NoTitleBar.Fullscreen">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowNoTitle">true</item>
</style>
In my app i want the image to capture every view of the layout not just the camera feed like this :
The test code I posted here hides the capture button so that it wont appear in your photo. If you have more views in your app and don't won't them to show in the photo either hide them while capturing (see code to know where to hide) or edit the code.
------>To sum up my post this code can do the basic capturing and saving a jpeg but if you want professional images you need to edit it a bit. Good Luck :)<------
I don't know if this solution is what you want. However the basics to take a picture as bitmap should be like this:
private static final int CAMERA_REQUEST = 1888; // field
private void takePicture(){ //you can call this every 5 seconds using a timer or whenever you want
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap picture = (Bitmap) data.getExtras().get("data");//this is your bitmap image and now you can do whatever you want with this
imageView.setImageBitmap(picture); //for example I put bmp in an ImageView
}
}
Don't forget to set permission for camera in your Manifest:
<uses-feature android:name="android.hardware.camera" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With