Android Resolve Uri failed on bad bitmap Uri error - java

I'm creating a camera application and in the main activity it's retrieve the camera preview bitmap and save to the internal storage.after intent to another class I want to display the image by getting the path of the bitmap.however after taking the picture for the first time, it's displays the picture well but sometimes not display the image and gives the following error
"Resolve Uri failed on bad bitmap Uri : data/data/com.camera.app/files/287372639100.jpg"
mainclass
//IMG name
mName = System.currentTimeMillis();
dTime = mName;
try {
//get bitmap & save into internal storage
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = IN_SAMPLE_SIZE;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
try {
Uri uri = Uri.parse(dTime+".jpg");
File f = new File(uri.toString());
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
else{
angle = 0;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
//get rotated bitmap
Bitmap correctBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mat, true);
//save bitmap to internal storage
FileOutputStream fos = openFileOutput(dTime+".jpg", Context.MODE_PRIVATE);
correctBmp.compress(CompressFormat.JPEG, 90, fos);
correctBmp = Bitmap.createScaledBitmap(bitmap, 380, 600, false);
fos.close();
bitmap.recycle();
correctBmp.recycle();
}
catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
}
catch(OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
} catch (Exception e) {
e.printStackTrace();
}
// intent send data
Intent intent = new Intent(MainActivity.this,PhotoClass.class);
intent.putExtra("IMG_NAME", dTime);
startActivity(intent);
finish();
Log.d(TAG, "onPictureTaken - bitmap sending..");
Photoclass
//get intent
Intent intent = getIntent();
imgName = intent.getLongExtra("IMG_NAME", 0);
uri = Uri.parse(getFilesDir().getPath() + "/"+imgName+".jpg");
if(imgName != 0){
mImagePreView.setImageURI(uri);
}
need a help to solve this problem.

Related

How to share image with a button? [duplicate]

This question already has answers here:
How to use "Share image using" sharing Intent to share images in android?
(17 answers)
Closed 2 years ago.
I am making QR code generator
So far I made a generator button and save button.
It works fine.
I am trying to work on the sharing button.
It takes a few days to figure out as a beginner and still I cannot make it work.
At this code, if I click share, then the app closes.
/**Barcode share*/
findViewById(R.id.share_barcode).setOnClickListener(v -> {
Bitmap b = BitmapFactory.decodeResource(getResources(),R.id.qr_image);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(getContentResolver(), b, "Title", null);
Uri imageUri = Uri.parse(path);
share.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(share, "Select"));
});
I guessed the problem was path.
I use savepath to save qr code image. And then maybe it conflicts with String path
So I tried String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";;
It's not working. So maybe it's different problem and I don't know how to fix it.
Could you show me how to fix?
MainActivity
public class MainActivity extends AppCompatActivity {
private String inputValue;
private String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";
private Bitmap bitmap;
private QRGEncoder qrgEncoder;
private ImageView qrImage;
private EditText edtValue;
private AppCompatActivity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
qrImage = findViewById(R.id.qr_image);
edtValue = findViewById(R.id.edt_value);
activity = this;
/**Barcode Generator*/
findViewById(R.id.generate_barcode).setOnClickListener(view -> {
inputValue = edtValue.getText().toString().trim();
if (inputValue.length() > 0) {
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int width = point.x;
int height = point.y;
int smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 3 / 4;
qrgEncoder = new QRGEncoder(
inputValue, null,
QRGContents.Type.TEXT,
smallerDimension);
qrgEncoder.setColorBlack(Color.BLACK);
qrgEncoder.setColorWhite(Color.WHITE);
try {
bitmap = qrgEncoder.getBitmap();
qrImage.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
} else {
edtValue.setError(getResources().getString(R.string.value_required));
}
});
/**Barcode save*/
findViewById(R.id.save_barcode).setOnClickListener(v -> {
String filename = edtValue.getText().toString().trim();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, filename + ".jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
OutputStream fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Objects.requireNonNull(fos).close();
Toast toast= Toast.makeText(getApplicationContext(),
"Image Saved. Check your gallery.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
edtValue.setText(null);
} catch (IOException e) {
e.printStackTrace();
}
} else {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
try {
boolean save = new QRGSaver().save(savePath, filename, bitmap, QRGContents.ImageType.IMAGE_JPEG);
String result = save ? "Image Saved. Check your gallery." : "Image Not Saved";
Toast.makeText(activity, result, Toast.LENGTH_LONG).show();
edtValue.setText(null);
} catch (Exception e) {
e.printStackTrace();
}
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
});
/**Barcode share*/
findViewById(R.id.share_barcode).setOnClickListener(v -> {
Bitmap b = BitmapFactory.decodeResource(getResources(),R.id.qr_image);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(getContentResolver(), b, "Title", null);
Uri imageUri = Uri.parse(path);
share.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(share, "Select"));
});
}
}
I think you can solve this by:
Saving the bitmap in a file.
Then sharing the URI of that file in the intent.
In the code below, I am saving the image at the app level directory, you can choose your own and the code is written in kotlin.
Note: If you are using an app-level directory for saving the image then you must use the file provide to get the URI else it may result in FileUriExposedException
try {
val file = File(getExternalFilesDir(null),System.currentTimeMillis().toString() + ".png")
file.createNewFile()
val b = imageView.drawable.toBitmap()
FileOutputStream(file).use { out ->
b.compress(Bitmap.CompressFormat.PNG, 100, out)
}
val share = Intent(Intent.ACTION_SEND)
share.type = "image/jpeg"
val photoURI = FileProvider.getUriForFile(this, applicationContext.packageName.toString() + ".provider", file)
share.putExtra(Intent.EXTRA_STREAM, photoURI)
startActivity(Intent.createChooser(share, "Share Image"))
Toast.makeText(this, "Completed!!", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
e.printStackTrace()
Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show()
}
In JAVA:
public void shareImage(Activity activity, ImageView imageView) {
try {
File file = new File(activity.getExternalFilesDir(null), System.currentTimeMillis() + ".png");
file.createNewFile();
Bitmap bitmap = drawableToBitmap(imageView.getDrawable());
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
Intent share = new Intent("android.intent.action.SEND");
share.setType("image/jpeg");
Uri photoURI = FileProvider.getUriForFile(activity,activity.getPackageName(), file);
share.putExtra("android.intent.extra.STREAM", photoURI);
activity.startActivity(Intent.createChooser(share, "Share Image"));
} catch (Exception var14) {
}
}
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}

RecyclerView take Image form camera is rotating when show on the list

I have an issue with my code. When I take a photo from my app, it is rotating 90ยบ to show. But, when I choose gallery option to select my photo, it is showing normal.
Can someone help me??
Code bellow:
Adapter.java
public void onBindViewHolder(#NonNull final ProdutosListaViewHolder holder, final int i){
Produto prod = produtos.get(i);
File foto = mPicture.getImageProduto(prod.codProd);
if(foto == null || foto.exists()){
holder.foto.setImageResource(R.drawable.sem_foto_icon);
}else{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeFile(foto.getAbsolutePath(), options);
holder.foto.setImageBitmap(bitmap);
}
}
PictureManager.java
if the camera selected to take the photo
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
i.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(ctx, ....));
((Activity) ctx).startActivityForResult(i, 999);
if the gallery selected to take the photo
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
((Activity) ctx).startActivityForResult(i, 998);
ProductListActivity.java
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==999){
try{
File foto = (new PictureManager(FOTO_PRODUTO, ctx)).getImageProduto(produtoSelecionado.codProd);
if(foto != null){
mProdutosListaAdapter.notifyItemChanged(posicaoSelecionada);
}
}catch(Exception e){
e.printStackTrace();
}
}else if(requestCode==998){
try{
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = ctx.getContentResolver().query(selectedImage, filePathColumn, null null, null);
cursor.moveToFirst();
int columnIndex = cursor.ColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
File file = new File(picturePath);
int codigo = produtoSelecionado.codProd;
File foto = (new PictureManager(FOTO_PRODUTO, ctx)).salvarFoto(file, codigo, 1);
mProdutosListaAdapter.notifyDataSetChanged();
}
}
}
}
}
Camera always gives you the picture according to camera orientation. I have tried the below code to change orientation
public static Bitmap rotateImageOrientation(String photoFilePath) {
// Create and configure BitmapFactory
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoFilePath, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(photoFilePath, opts);
// Read EXIF Data
ExifInterface exif = null;
try {
exif = new ExifInterface(photoFilePath);
} catch (IOException e) {
e.printStackTrace();
}
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
// Rotate Bitmap
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
return Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
// Return result
}

Resizing image file rotate it horizontally android

Hey I have an app that choose an image from the gallery , resizing it and uploading it to ftp server , but I have notice that in some photo's the app flips the image horizontally and upload it backwards, I can't figure out why it is happening (It only happened on some photos and on others not, usually happened on photos taken from my camera)
Here is the code for the resize part:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK&&data!=null) {
selectedImageURI = data.getData();
showUri = data.getData();
imagePath = RealPathUtil.getPath(this,data.getData());
loadedImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
//loadedImage.setImageURI(data.getData());
Glide.with(this).load(data.getData())
.into((ImageView) findViewById(R.id.upload_image1));
ImageView m =(ImageView)findViewById(R.id.remove_image);
m.setFocusable(true);
m.setVisibility(View.VISIBLE);
File file = new File(RealPathUtil.getPath(this,data.getData()));
Bitmap bitmap = decodeFile(file);
ImageResizer(bitmap);
}
}
private Bitmap decodeFile(File f) {
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
final int REQUIRED_SIZE=200;
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Bitmap bit1 = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
//Matrix matrix = new Matrix();
//matrix.postRotate(45);
// Bitmap rotatedBitmap = Bitmap.createBitmap(bit1 , 0, 0, bit1 .getWidth(), bit1 .getHeight(), matrix, true);
return bit1;
} catch (FileNotFoundException e) {}
return null;
}
private void ImageResizer(Bitmap bitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Pic");
if(!myDir.exists()) myDir.mkdirs();
String fname = "resized.png";
File file = new File (myDir, fname);
if (file.exists()){
file.delete();
Log.d("exist","replace");
SaveResized(file, bitmap);
} else {
SaveResized(file, bitmap);
Log.d("saved","now");
}
selectedImageURI = Uri.fromFile(file);
imagePath = RealPathUtil.getPath(this,selectedImageURI);
}
private void SaveResized(File file, Bitmap bitmap) {
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
can someone help me and tell me why is it happening?

NullPointer When compressing bitmap image

I am trying to get an image from gallery or take one using camera in android. taking one using camera app works so fine but getting an image from gallery returs a nullpointer when compressing. below shows my code for sellecting from gallery and camera
#Override
protected void onActivityResult(int requestCode, int resultCode, #NonNull Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == CAMERA_PIC_REQUEST1) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
image_String = SessionManager.encodeTobase64(thumbnail);
Log.d("bm", image_String.toString());
profile_pic.setImageBitmap(thumbnail);
} else if (requestCode == SELECT_FILE1) {
Uri selectedImageUri = data.getData();
String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null,
null);
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
String selectedImagePath = cursor.getString(column_index);
cursor.close();
Bitmap bm;
BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
// BitmapFactory.decodeFile(selectedImagePath, options);
final int REQUIRED_SIZE = 200;
int scale = 1;
while (options.outWidth / scale / 2 >= REQUIRED_SIZE
&& options.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
options.inSampleSize = scale;
bm = BitmapFactory.decodeFile(selectedImagePath, options);
image_String = SessionManager.encodeTobase64(bm);
Log.d("bm", image_String.toString());
profile_pic.setImageBitmap(bm);
}
}
}
and here is my mothhod to perform the encoding of the imgage i just got
public static String encodeTobase64(Bitmap img){
Bitmap image = img;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
return imageEncoded;
}
can't figure out the encode method signals an error when compresing the bitmap taken from gallery of device. Please help me out

Saving an image with its thumb and showing on imageView android

I am trying to save an image taken from camera and then storing it on sdCard along with its Thumb also showing this thumb on an imageView.
However it gives error at Null pointer
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, 40, 40, false);
What is wrong?
{
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try
{
if (title.getText().toString().equals(""))
{
displayAlert("Please Input Title First","Error!");
}
else
{
Integer val = myMisc.miscId ;
String fileName = "image" + "_" + title.getText().toString()+"_" + val.toString();
photo = this.createFile(fileName, ".jpg");
myMisc.filename = photo.getAbsolutePath();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
startActivityForResult(intent, RESULT_CAMERA_SELECT);
}
}
catch(Exception e)
{
Log.v("Error", "Can't create file to take picture!");
displayAlert("Can't create file to take picture!","SDCard Error!");
}
}
public synchronized void onActivityResult(final int requestCode, int resultCode, final Intent data)
{
if (resultCode == Activity.RESULT_OK)
{
if (requestCode == RESULT_CAMERA_SELECT)
{
try
{
saveImage();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
public void saveImage() throws IOException
{
try
{
FileInputStream is2 = new FileInputStream(photo);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap imageBitmap = BitmapFactory.decodeStream(is2, null, options);
options.inSampleSize = calculateInSampleSize(options, 40, 40);
options.inJustDecodeBounds = false;
imageBitmap = BitmapFactory.decodeStream(is2 ,null, options);
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, 40, 40, false);
Integer val = myMisc.miscId;
String fileName = ".thumbImage" + "_" + title.getText().toString()+ "_" + val.toString();
photo = this.createFile(fileName, ".jpg");
myMisc.thumbFileName = photo.getAbsolutePath();
try {
FileOutputStream out = new FileOutputStream(photo);
imageBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
is2.close();
Uri uri = Uri.fromFile(photo);
photo = null;
imageBitmap = null;
imageView.setImageURI(uri);
}catch(Exception e)
{
displayAlert("Can't create file to take picture!","SD Card Error");
}
}
It's probably because of the decodeStream method.
Bitmap imageBitmap = BitmapFactory.decodeStream(is2, null, options);
You parsed null at the when it asks for a Rectangle and when you tried to create a scaled bitmap it was not valid.
i found my error Bitmap imageBitmap = BitmapFactory.decodeStream(is2, null, options); decoding twice

Categories

Resources