How can I specify the taken image quality on Android? [duplicate] - android

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);
}

Related

Android change the pixel or the image size when saving to SQLITE

I know this is quite common to ask but I'm really confused this time. All I need is to save the BLOB image to the SQLite and I have already done and saved it to SQLite, actually, I have two images saved as BLOB in SQLite I compared them but I really don't know the difference the other one contains 3000X4000 pixels 2.72 MIB which much heavier size and the other one is much lighter which is 182x250 50.81Kib and this is what I really want the lightier size. I upload two images to see what's really happening
Actually, I've been trying to develop Text Image Recognition. The image which bigger size sample, after capturing an image it should be crop and saves to SQLite while the lesser size just directly captured image and save to SQLite now they have the save function to save to SQLite I really don't know why they have different size and I think the problem is on the crop or Pickcamera()method which it changes the size of the image? is that possible?.
The bigger one
The lesser one
The bigger size code Image after clicking button it goes to pickCamera() method and the image display to the another activity
public void pickCamera() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "NewPic");
values.put(MediaStore.Images.Media.DESCRIPTION, "Image to Text");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
Intent cameraIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLER_CODE){
CropImage.activity(data.getData()).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
CropImage.activity(image_uri).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if(resultCode ==RESULT_OK){
Uri resultUri = result.getUri();
resultUri.getPath();
BitmapDrawable bitmapDrawable = (BitmapDrawable)mPreviewIv.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
TextRecognizer recognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if(!recognizer.isOperational()){
Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
}
else{
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<TextBlock> items = recognizer.detect(frame);
StringBuilder sb = new StringBuilder();
for (int i = 0; i<items.size(); i++){
TextBlock myItem = items.valueAt(i);
sb.append(myItem.getValue());
sb.append("\n");
}
Intent i = new Intent(ScanCashCard.this, ScannedDetails.class);
//camera I want to display the image view to another Activity and save to SQLite
i.putExtra("CashCardImage",image_uri.toString());
startActivity(i);
}
}
}
}
Display to another activity
String resultUri = extras.getString("CashCardImage");
Uri myUri = Uri.parse(resultUri);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),myUri);
mPreviewCashCard.setImageBitmap(bitmap);
This code is from the lesser size
public void pickcamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 101);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101){
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
mPreview4PsId.setImageBitmap(bitmap);
}
}
I think the problem is on the pickCamera() method which they different but when I follow the code from the lesser size the crop will not be available anymore, I stuck with this module anyone can help me? this is really help me a lot
So I just add a bunch of code which set and replace the default resolution of the Image pixel because I guess the default Pixel of the Image resolution from camera is 3000x4000 pixel so you just need to set the width and height of the ImageView. So I just set 187x250
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),myUri);
mPreviewCashCard.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 187, 250, false));

IMAGE_CAPTURE on resultActivity the file doesn't exist yet

This a rare case, i'm trying to capture an image from native camera activity on my samsung galaxy s3 and onActivityResult the file doesn't exist to read yet. If i disconnect the phone and connect again then the i can see the image on my explorer.
It likes that the camera activity writes the file with delay or something...
i have readed all questions and answers and other forums, but it is my problem; My code:
... onCreate
File file = new File( _path );
pathUri = Uri.fromFile( file );
...
protected void startCameraActivity()
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, pathUri);
startActivityForResult( intent, CAMERA_REQUEST_CODE );
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK)
{
// test if exits image
if((new File(_path)).exists())
... do something
}
... continue
if((new File(_path)).exists()) always retunrs FALSE, how is it possible?
Thans in advance
I have never seen this occur in my app. However, this could potentially be a workaround.
Note: Declare the Uri instance initialURI globally so you can use it throughout the Activity. You could also change the name to something that suits your naming convention.
In this, right before the Intent is triggered, I pass a specific path for the Image to be stored at along with the name for the File.
Intent getCameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
File cameraFolder;
if (android.os.Environment.getExternalStorageState().equals
(android.os.Environment.MEDIA_MOUNTED))
cameraFolder = new File(android.os.Environment.getExternalStorageDirectory(),
"SOME_FOLDER_NAME/");
else
cameraFolder= StatusUpdate.this.getCacheDir();
if(!cameraFolder.exists())
cameraFolder.mkdirs();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
String timeStamp = dateFormat.format(new Date());
String imageFileName = "picture_" + timeStamp + ".jpg";
File photo = new File(Environment.getExternalStorageDirectory(),
"SOME_FOLDER_NAME/" + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
initialURI = Uri.fromFile(photo);
startActivityForResult(getCameraImage, ACTION_REQUEST_CAMERA);
And finally, in the onActivityResult():
Note: This I'm guessing should work. My application uses the Aviary SDK and the code for that differs vastly from the conventional work done in this method.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) {
// USE EITHER THIS
imgView.setImageURI(initialURI);
// OR USE THIS
getContentResolver().notifyChange(initialURI, null);
ContentResolver cr = getContentResolver();
try {
// SET THE IMAGE FROM THE CAMERA TO THE IMAGEVIEW
Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, initialURI);
// SET THE IMAGE USING THE BITMAP
imgvwSelectedImage.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
If you do not need the the Image stored on the SD-Card, you could delete it once you are done with it. This I am guessing (guessing because I have never experienced what the OP is facing problem with) this should do it for you.
Oh. Almost forgot. You will need to declare this permission in your Manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

How to put a date watermarker in android camera activity

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 :(

Android Camera Intent woes

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 ;)

small size picture problem

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

Categories

Resources