android camera implementation - android

I am going to implement camera feature for my android app.for this, I searched a lot on internet and found 2 way to implement camera feature
design your own camera class using
android.view.SurfaceHolder and
android.view.SurfaceView
but this approach does look good to me as in this i have to take care of many things which will make my code complex.
2. I can use intent to call device camera. now again in this , i have 2 option
i ) using MediaStore.EXTRA_OUTPUT and not using MediaStore.EXTRA_OUTPUT
if i dont use MediaStore.EXTRA_OUTPUT I get a thumbnail which is not my actual requirement. i need image larger than this so if I scale this thumbnail, i find low quality image.
if i use MediaStore.EXTRA_OUTPUT I dint get any image on some device like samsung as in
onActivityResult(int requestCode, int resultCode, Intent intent)
I find intent is null . after searching a lot on internet, i found that this is device specific issue. i have Samsung Galaxy with me. and on this i am facing this issue.
i dont want my code to be a device specific code. so can any one tell me how to make my code generic. for your analysis, i am using following code
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
File root = new File(Environment
.getExternalStorageDirectory()
+ File.separator + "myDir" + File.separator)
if(!root.exists()){
root.mkdirs();
}
sdImageMainDirectory = new File(root, "myPicName");
startCameraActivity();
}
catch (Exception e) {
finish();
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
}
Uri outputFileUri;
protected void startCameraActivity() {
outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (resultCode) {
case 0:
finish();
break;
case -1:
try {
if(intent != null)
StoreImage(this, Uri.parse(intent.toURI()),
sdImageMainDirectory);
} catch (Exception e) {
e.printStackTrace();
}
Intent i = new Intent(this,Home.class);
i.putExtra("url", outputFileUri);
startActivity(i);
finish();
}
}
public static void StoreImage(Context mContext, Uri imageLoc, File imageDir) {
Bitmap bm = null;
try {
bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
FileOutputStream out = new FileOutputStream(imageDir);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
bm.recycle();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

Please check this link: Capture image using Intent
This code works fine in all the Samsung devices I have used (like Galaxy S, Galaxy Tab, Galaxy Pro).

Related

Capture a custom image size with the camera or crop it

Am working on OCR system which is requiring to capture image and do OCR, i would like to capture part of the paper (Exact where intended text is) or crop captured image before passing it to OCR processing for better results.
I tried bellow code but i can't make it to what am trying to archive as am beginner to android java
private void startCameraActivity() {
try {
String IMGS_PATH = Environment.getExternalStorageDirectory().toString() + "/ocr/imgs";
prepareDirectory(IMGS_PATH);
String img_path = IMGS_PATH + "/ocr.jpg";
outputFileUri = Uri.fromFile(new File(img_path));
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
takePictureIntent.putExtra("crop", "true");
takePictureIntent.putExtra("scale", true);
takePictureIntent.putExtra("aspectX", 1);
takePictureIntent.putExtra("aspectY", 1);
takePictureIntent.putExtra("outputX", 150);
takePictureIntent.putExtra("outputY", 100);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
//making photo
if (requestCode == PHOTO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
doOCR();
} else {
Toast.makeText(this, "ERROR: Image was not obtained.", Toast.LENGTH_SHORT).show();
}
}
private void doOCR() {
prepareTesseract();
startOCR(outputFileUri);
}
Am someone help me out here, Thanks.
NOTE
takePictureIntent.putExtra("crop", "true");
takePictureIntent.putExtra("scale", true);
takePictureIntent.putExtra("aspectX", 1);
takePictureIntent.putExtra("aspectY", 1);
takePictureIntent.putExtra("outputX", 150);
takePictureIntent.putExtra("outputY", 100);
After clearning my cache i noted the above code is opening complete action with apps which can crop image and everything is fine now.
Thanks.

How to process a photo taken by an intent?

I'm completely news on android thing and unfortunately with little few time to learn it by the right way, I have a work to release.
The problem is: I need to take a picture and process her with an algorithm that I made.
I did it by the easiest way that I could find, I know it looks like really trahsie for those who really get android (sorry)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePic();
protected void takePic(){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, 100);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Bundle extras = data.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
Algorithm(mImageBitmap)
But it doesn't process, it takes a photo, ask to save or cancell and leaves the application, I have already made by different ways (creating a new activity), but nothing seems to work
Heres how I did it
To go to the camera:
Somewhere, declaire a fileUri variable and hold onto it
Uri fileUri;
final int TAKE_PICTURE=100;//this can be any int, really
public void goToCamera(){
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo;
try
{
// place where to store camera taken picture
photo = this.createTemporaryFile("picture", ".jpg");
Log.v(TAG, "Here(after createTempFile)");
photo.delete();
}
catch(Exception e)
{
Log.v(TAG, "Can't create file to take picture!" + e.getMessage());
Toast.makeText(context, "Please check SD card!", Toast.LENGTH_SHORT).show();
return;
}
fileUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE);
}
Then to retreive the image
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK){
this.getContentResolver().notifyChange(uri, null);
ContentResolver cr = this.getContentResolver();
Bitmap bitmap;
try
{
BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(uri.getPath().toString(), ops);
}
catch (Exception e)
{
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Failed to load", e);
}
}
}
The create temp file mentioned above:
private File createTemporaryFile(String part, String ext) throws Exception
{
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
Log.i(TAG, tempDir.toString());
if(!tempDir.exists())
{
Log.i(TAG, "Dir doesnt exist");
tempDir.mkdirs();
}
return File.createTempFile(part, ext, tempDir);
}
I realize this isn't probably as simple as you were hoping for, but this approach seemed to be as flexible and compatible as possible. Let me know if I left anything else out

Android : force close where get picture image from camera landscape

I have code to show capture image from camera device like this
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String file_name = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
File file = new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + file_name + ".jpg");
mImageCaptureUri = Uri.fromFile(file);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intent.putExtra("return-data", true);
intent.putExtra("mImageCaptureUri", mImageCaptureUri);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
and set image bitmap from path , it works when I capture image from portrait view camera device , but when I capture image from landscape view camera its getting error , I think its because my activity to retrieve image is portrait . So can u give me advice in order to I can capture image from portrait or landscape view camera?? thanks
try this
at first start intent
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
and then activity for result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST) {
if(data!=null && resultCode == RESULT_OK)
{
bitMapForProfilePic = (Bitmap) data.getExtras().get("data");
bitMapForProfilePic =Bitmap.createScaledBitmap(bitMapForProfilePic, getWindowManager().getDefaultDisplay().getWidth()/5, getWindowManager().getDefaultDisplay().getHeight()/4, true);
registration_profilePicID.setImageBitmap(bitMapForProfilePic); bitMapForProfilePic=null;
}
}
}
if u want to store the bitmap
extStorageDirectory = Environment.getExternalStorageDirectory().toString();
OutputStream outStream = null;
File file = new File(extStorageDirectory, "profilepicture.PNG");
try {
outStream = new FileOutputStream(file);
bitMapForProfilePic.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
then set the image
view.setImageBitmap(BitmapFactory.decodeFile("/sdcard/profilepicture.PNG"));
if u have any doubts let me know...
I've faced the similar problem in one of my apps, I've fixed it in the following way:
First save your instance state:
#Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putString(IMAGE_FILE_PATH, imageFilePath); }
And then restore it:
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
ImageFilePath = state.getString(IMAGE_FILE_PATH); }
That works for me, but variable ImageFilePath should be global for your Activity so maybe there is more graceful way to achieve this

Using phones camera , after capturing image activity doesn't return back to particular activity

I am capturing an image from my application using phone's camera and using android.provider.MediaStore.ACTION_IMAGE_CAPTURE.
After clicking capture button it shows save or discard. Clicking save button it returns back to camera not to application. and the image is saved in gallary not to the output file which i have declared.
Below is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Intent in=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(in, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK) {
Bitmap bm=(Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
//you can create a new file name "test.jpg" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "player1.jpg");
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//write the bytes in file
FileOutputStream fo = null;
try {
fo = new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fo.write(bytes.toByteArray());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
Intent pic=new Intent(pic1.this, GameMenu.class);
startActivity(pic);
finish();
}
}
else {
Toast.makeText(getApplicationContext(), "Canceled", Toast.LENGTH_LONG).show();
Intent pic=new Intent(pic1.this, Menu.class);
startActivity(pic);
finish();
}
Kindly suggest if any solution..
Thanks in advance...
EDIT 1: I have checked this code on samsung galaxy y duos (android 2.3.6) its not working properly. And checked same on galaxy pop(2.2.1) and HTC wildfire(2.3.5) its working perfect.
Use below intent to capture the image and getTempFile() is where you mention the storage path
Intent photoPickerIntent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempFile());
photoPickerIntent.putExtra("outputFormat",Bitmap.CompressFormat.JPEG.toString());
photoPickerIntent.putExtra("return-data", true);
startActivityForResult(photoPickerIntent,TAKE_PICTURE);
getTempFile:
private Uri getTempFile() {
File root = new File(Environment.getExternalStorageDirectory(), "Directory");
if (!root.exists()) {
root.mkdirs();
}
File file;
file = new File(root,filename+".jpeg" );
muri = Uri.fromFile(file);
photopath=muri.getPath();
Log.e("getpath",muri.getPath());
return muri;
}
Read here for more threads
If this is your whole code you have omitted setContentView(); Could be the reason it is not returning.
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// setContentView() here
Intent in=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(in, 0);
}
Is the onActivityResult() method called?
I got the same problem, I have restart my device and test my application it works fine now. It might be possible with different code implementation application not responding. Try to reboot your device and test and let me know its working or not
you should creat your file opening your camera. you give the file URI as extra to the camera intent:
/**
* Capturing Camera Image will lunch camera app request image capture
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
this is how I creat the file :
/**
* Creating file uri to store image
*
*
* #return Uri
*/
public Uri getOutputMediaFileUri() {
return Uri.fromFile(getTempOutputMediaFile());
}
/**
* returning File
*
*
* #return File
*/
private File getTempOutputMediaFile() {
File appDirectory = this.getFilesDir();
File mediaStorageDir = new File(APP_NAME,
YOUR_IMAGE_DIRECTORY_NAME);
Log.i("mediaStorageDir", mediaStorageDir.getAbsolutePath());
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.i(YOUR_IMAGE_DIRECTORY_NAME,
"Oops! Failed create "
+ YOUR_IMAGE_DIRECTORY_NAME
+ " directory");
return null;
}
}
// Create a media file name
UUID temporaryImageUuid = UUID.randomUUID();
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ temporaryImageUuid + "." + YOUR_EXTENSION);
return mediaFile;
}
hi check the following code.after capturing image use startPreview() to release.it works for me
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.autoFocus(null);
mCamera.takePicture(null, null, mPicture);
Log.e("in capture button","onclick of this button"+ mCamera);
mCamera.startPreview();
}
});

How to capture an image and store it with the native Android Camera

I am having a problem capturing an image and storing it from the native camera app. Here is a sample of some of my code.
_path = Environment.getExternalStorageDirectory() + "make_machine_example.jpg";
File file = new File( _path );
Uri outputFileUri = Uri.fromFile( file );
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );
startActivityForResult( intent, 0 );
After the picture has been taken and I'm returned back to my original Activity, When I navigate to my sd card via Android DDMS File Explorer the picture is not there. Anyone know why this is not being saved?
Here was the final product in case anyone is still visiting this thread:
public class CameraCapture extends Activity {
protected boolean _taken = true;
File sdImageMainDirectory;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
File root = new File(Environment
.getExternalStorageDirectory()
+ File.separator + "myDir" + File.separator);
root.mkdirs();
sdImageMainDirectory = new File(root, "myPicName");
startCameraActivity();
}
} catch (Exception e) {
finish();
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
}
protected void startCameraActivity() {
Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case 0:
finish();
break;
case -1:
try {
StoreImage(this, Uri.parse(data.toURI()),
sdImageMainDirectory);
} catch (Exception e) {
e.printStackTrace();
}
finish();
startActivity(new Intent(CameraCapture.this, Home.class));
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
_taken = true;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
}
public static void StoreImage(Context mContext, Uri imageLoc, File imageDir) {
Bitmap bm = null;
try {
bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
FileOutputStream out = new FileOutputStream(imageDir);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
bm.recycle();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Have you checked what the output of Environment.getExternalStorageDirectory() is, because if it does not contain a trailing file seperator (/) then your image will end up in a directory that does not reside on the SDcard such as:
/mnt/sdcardmake_machine_example.jpg
When what you really want is:
/mnt/sdcard/make_machine_example.jpg
Try this code instead:
_path = Environment.getExternalStorageDirectory() + File.separator + "make_machine_example.jpg";
1 . Just use
new File(Environment.getExternalStorageDirectory(), "make_machine_example.jpg");
and don't bother about separators.
2 . Faced the same problem before. SenseUI phones have a custom camera application that doesn't create file. What device are you using? It may already be fixed in latest devices but it may also still be an issue. So here's a complete sample how to overcome it Problems saving a photo to a file.
You should perform a media scanning after saving the image
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Add this line into AndroidManifest.xml file and remove extension make_machine_example:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
It will start to capture the Photo and store into the SDcard.

Categories

Resources