I'm getting pictures with the next code:
public void foto(View v) {
nom_foto = Environment.getExternalStorageDirectory()+ aptr.ruta_temp + cuadrilla + "/" + medidor + "_"+ cont_foto + ".jpg";
File arch = new File(Environment.getExternalStorageDirectory()+ aptr.ruta_temp+ cuadrilla);
if (!arch.exists())
arch.mkdirs();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
int code = TAKE_PICTURE;
Uri output = Uri.fromFile(new File(nom_foto));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, code);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE) {
ImageView iv = (ImageView) findViewById(R.id.minifoto);
if (resultCode == RESULT_OK) {
new MediaScannerConnectionClient() {
private MediaScannerConnection msc = null;
{
msc = new MediaScannerConnection(getApplicationContext(), this);
msc.connect();
}
public void onMediaScannerConnected() {msc.scanFile(nom_foto,null);
}
public void onScanCompleted(String path, Uri uri)
{ msc.disconnect();}};
Toast.makeText(usuario_lectura.this,"Foto N° " + cont_foto + " agregada correctamente", Toast.LENGTH_LONG).show();
cont_foto++;
iv.setVisibility(View.VISIBLE);
iv.setImageBitmap(BitmapFactory.decodeFile(nom_foto));
}
}
if (resultCode == RESULT_CANCELED) {
File file = new File(nom_foto);
if (file.exists())
file.delete();
}
}
}
Everything works properly, the picture has taken correctly and saved on the SD card... But, I have to add a watermarker, including the date... How can I add it?, the camera activity doesn't give me these option...
In order to add a textual or graphical watermark to your image from the camera, you must open the image, edit it in a Canvas with Paint/Graphics overlays, then re-encode it as a .jpg image, and re-save it as a file on the SD card. You can save over the original file from the camera. All of these steps are fairly straightforward.
There is, however, a serious hurdle.
Most devices will not be able to open the full-size image from the camera in a single Bitmap. There is not enough heap memory available. Therefore, you will have to use a scale factor inSampleSize to open your image. Thus, the watermarked image will be forever smaller by some factor than the original from the camera.
I do not think there is any way around this issue :(
Related
This question already has answers here:
How to make Android Camera Intent return full size picture
(2 answers)
Closed 4 years ago.
I found these two part of code, to how to take a photo from the camera in Android:
Inside the onCreate() method:
Button capture;
capture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
});
And
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
}
}
And it works, but the problem is that, the quality of the result image is very low! I like to know how can I specify what quality of image I want to take?
Also like to know, are there other options that bitmap to store or work on images?
EDIT:
This is what I see before pushing the capture button:
And this is what it takes after pushing the capture button(it reduces the quality):
I must say, when I take photos with my phone(outside of this app I mean) it works good, but inside the my written app, it reduces the taken image quality!
**Also I have another question...how can I remove this second page that shows after it took the image(the page shows RETRY-OK options I mean).
Check below solution for your problem.
public static File IMAGE_PATH = null;
public static final int CAMERA_REQUEST = 100;
private void openCameraApp(Context mContext) {
Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
String file_path = Environment.getExternalStorageDirectory().toString() +
"/" + mContext.getResources().getString(R.string.app_name);
File dir = new File(file_path);
if (!dir.exists())
dir.mkdirs();
IMAGE_PATH = new File(dir, mContext.getResources().getString(R.string.app_name) + System.currentTimeMillis() + ".png");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
picIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(mContext, mContext.getPackageName()+".fileprovider", IMAGE_PATH));
}
else {
picIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(IMAGE_PATH));
}
((Activity) mContext).startActivityForResult(picIntent, CAMERA_REQUEST);
}
Sorry to bother you guys, but I am not able to get a solution where In we take picture using intents. I know the default behavior of native camera is to save the picture at default directory/place of O.S. The thing is I have some requirements where I do not want to save the picture when clicked using camera app. There has to be a solution of this issue, be it like once we take a picture we could delete it right away, or there should be an alternate by which we won't allow O.S to save Image, please help.
Here is a piece of code I tried, tried several ways by creating a directory and then deleting file, nothing works.
public void takeImageFromCamera() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check for the integer request code originally supplied to startResolutionForResult().
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
if (isCameraPermissionGranted()) {
bitmap= (Bitmap) data.getExtras().get("data");
// bitmap = processReuiredImage(picUri);
getProfileDetailViaFace(encodeImageBitmapToString(bitmap));
Log.d("path",String.valueOf(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)));
// getApplicationContext().getContentResolver().delete(, "/storage/emulated/0/Pictures", null);
// mediaStorageDir.getPath().delete();
} else {
requestCameraPermission();
}
}
public void takeImageFromCamera() {
File file = getOutputMediaFile(CAMERA_FILE_TYPE);
if (Build.VERSION.SDK_INT >= 24) {
try {
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
picUri = Uri.fromFile(file);
Intent takePictureIntent = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, picUri);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, CAMERA_REQUEST);
}
}
private File getOutputMediaFile(int type) {
mediaStorageDir = new
File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "peppercard");
/**Create the storage directory if it does not exist*/
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
/**Create a media file name*/
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
if (type == CAMERA_FILE_TYPE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpeg");
} else {
return null;
}
}
return mediaFile;
}
The thing is I have some requirements where I do not want to save the picture when clicked using camera app
The decision of whether or not to save an image is up to the camera app, not you. There are hundreds of camera apps that might respond to ACTION_IMAGE_CAPTURE, and the developers of those apps can do whatever they want.
There has to be a solution of this issue, be it like once we take a picture we could delete it right away, or there should be an alternate by which we won't allow O.S to save Image,
Take the photo yourself, using the camera APIs or libraries that wrap around them (e.g., CameraKit-Android, Fotoapparat).
There has to be a solution of this issue, be it like once we take
a picture we could delete it right away
Indeed there is. You could specify a path (even using a file provider) where the camera app has to put the image in a file.
Then when the camera app is done you can get the image from that file and then delete the file.
Have a look at Intent.EXTRA_OUTPUT.
Pretty standard your question. You can find a lot of example code on this site.
Final I have found the answer after waiting from past 2 days, yay..It will not save the file as I am just deleting the file after returning from the activity.
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null)
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
String imagePath = cursor.getString(column_index_data);
Bitmap bitmapImage = BitmapFactory.decodeFile(imagePath );
Log.d("bitmapImage", bitmapImage.toString()); /*delete file after taking picture*/
Log.d("imagePath", imagePath.toString());
File f = new File(imagePath);
if (f.exists()){
f.delete();
}
sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(f)));
I tried to take a picture using camera intent and want to get the file path of the full size image. I am following the tutorial from http://developer.android.com/training/camera/photobasics.html. The problem, when I look into the file path in MediaStore.Images.Media.DATA column using MediaStore.Images.Media.EXTERNAL_CONTENT_URI, the image have different path. How do I supply the same file path? I looked at taking a photo and placing it in the Gallery, I though it is simply just change Environment.DIRECTORY_PICTURES to Environment.DIRECTORY_DCIM, but it still didn't work.
Below is my code for taking photo.
private Uri photoPath;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
getContentResolver().notifyChange(photoPath, null);
System.out.println(photoPath);
}
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.camera_button) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
try {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String image = "IMG_" + timestamp;
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File photo = File.createTempFile(image, ".jpg", storageDir);
photoPath = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoPath);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
my code above produce file path /storage/emulated/0/Pictures/IMG_20150805_121624.jpg while it is actually /storage/emulated/0/DCIM/100MEDIA/IMAG0531.jpg in the gallery. the former path is really my image (as I specified it on photoPath), but I want to get the later path instead. How could I do that?
You will have to use Environment.DIRECTORY_DCIM.
The android API DOC clearly has the details of various directories which can be used.
I hope this will help you to save your file to /storage/emulated/0/DCIM/.
Hope someone may give some pointers (or an out right answer)...
Simple app, take an image using the built-in camera app, save the image to a separate application. Be done.
Problem: The camera application saves the image in the default app location (/mnt/sdcard/external_sd/DCIM/Camera) as well as my custom path (in code below).
Both files are exactly the same except for the file name. The external_sd file (the one I want gone) is saved with dashes (-) vs my custom file path saved with underscores. File sizes are exactly the same.
How can I stop this double image issue?
Is there an extra intent option I'm missing?
Or am I doing this completely wrong, missing something?
I'm using a Galaxy S Vibrant.
Code snippet:
private static Uri _outputFileUri;
private static File _file;
private ImageView _image;
private SimpleDateFormat _simpleDateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
_takePicture = (Button) findViewById(R.id.takePicture);
_takePicture.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
_file = new File(Environment.getExternalStorageDirectory() +
"/Android/data/my own folder/files/",
_simpleDateFormat.format(new Date()).toString() +
".jpg");
_outputFileUri = Uri.fromFile(_file);
_intent.putExtra(MediaStore.EXTRA_OUTPUT, _outputFileUri);
startActivityForResult(_intent, CAMERA_ACTIVITY);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Activity cancelled", Toast.LENGTH_LONG).show();
return;
}
switch (requestCode) {
case CAMERA_ACTIVITY:
if (resultCode == RESULT_OK) {
try{
Bitmap b = MediaStore.Images.Media.getBitmap(getContentResolver(), _outputFileUri);
_image.setImageBitmap(b);
_image.invalidate();
}
catch(Exception e){
e.printStackTrace();
}
}
break;
}
}
This is device-dependent behavior. My observation is that HTC devices do not have this duplication problem, but Samsung devices do.
Please remove the following lines:
_file = new File(Environment.getExternalStorageDirectory() +
"/Android/data/my own folder/files/",
_simpleDateFormat.format(new Date()).toString() +
".jpg");
_outputFileUri = Uri.fromFile(_file);
_intent.putExtra(MediaStore.EXTRA_OUTPUT, _outputFileUri);
Also update the code to get the image from intent:
Bitmap b = (Bitmap) data.getExtras().get("data");
_image.setImageBitmap(b);
_image.invalidate();
This way picture wouldn't be saved on sd card or default location.
I had the same problem and gave up. Sometime later I found out that I was not getting it anymore and I'm not sure what change I made to my code, but I think that it was MediaStore's fault (check my unsolved question: Weird camera Intent behavior)
As you already have the image URI, why don't you use it to set the ImageViews' bitmap?
// void setImageURI(Uri uri)
_image.setImageBitmap(_outputFileUri);
I had this issue and here is how i solved it :
File createImageFile() throws IOException{
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String filename = "IMG_"+timestamp+"_";
File image = File.createTempFile(filename,".jpg",mGalleryFolder );
if (image.length() == 0 ){
boolean delete = image.delete();
}
mLocation = image.getAbsolutePath();
return image;
}
It's not exactly solving but works for me ;)
I've got a problem in saving a picture in a full size after capturing it using ACTION_IMAGE_CAPTURE intent the picture become very small , its resolution is 27X44 I'm using 1.5 android emulator, this is the code and I will appreciate any help:
myImageButton02.setOnClickListener
(
new OnClickListener()
{
#Override
public void onClick(View v)
{
// create camera intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Grant permission to the camera activity to write the photo.
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
//saving if there is EXTRA_OUTPUT
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File
(Environment.getExternalStorageDirectory(), "testExtra" + String.valueOf
(System.currentTimeMillis()) + ".jpg")));
// start the camera intent and return the image
startActivityForResult(intent,1);
}
}
);
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// if Activity was canceled, display a Toast message
if (resultCode == RESULT_CANCELED)
{
Toast toast = Toast.makeText(this,"camera cancelled", 10000);
toast.show();
return;
}
// lets check if we are really dealing with a picture
if (requestCode == 1 && resultCode == RESULT_OK)
{
String timestamp = Long.toString(System.currentTimeMillis());
// get the picture
Bitmap mPicture = (Bitmap) data.getExtras().get("data");
// save image to gallery
MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp);
}
}
}
Look at what you are doing:
you specify a path where your just taken picture is stored with intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File (Environment.getExternalStorageDirectory(), "testExtra" + String.valueOf (System.currentTimeMillis()) + ".jpg")));
when you access the picture you 'drag' the data out of the intent with Bitmap mPicture = (Bitmap) data.getExtras().get("data");
Obviously, you don't access the picture from its file. As far as I know Intents are not designed to carry a large amount of data since they are passed between e.g. Activities. What you should do is open the picture from the file created by the camera intent. Looks like that:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
// Limit the filesize since 5MP pictures will kill you RAM
bitmapOptions.inSampleSize = 6;
imgBitmap = BitmapFactory.decodeFile(pathToPicture, bitmapOptions);
That should do the trick. It used to work for me this way but I am experiencing problems since 2.1 on several devices. Works (still) fine on Nexus One.
Take a look at MediaStore.ACTION_IMAGE_CAPTURE.
Hope this helps.
Regards,
Steff