Reputation: 2058
I'm trying to create a Bitmap from an existing URI, rotate the Bitmap and save it to the same place as a JPEG file. This is my current code after having tried several solutions:
try {
// Get the Bitmap from the known URI. This seems to work.
Bitmap bmp = MediaStore.Images.Media.getBitmap(this.getContentResolver(), this.currUserImgUri);
// Rotate the Bitmap thanks to a rotated matrix. This seems to work.
Matrix matrix = new Matrix();
matrix.postRotate(-90);
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
// Create an output stream which will write the Bitmap bytes to the file located at the URI path.
File imageFile = new File(this.currUserImgUri.getPath());
FileOutputStream fOut = new FileOutputStream(imageFile); // --> here an Exception is catched; see below.
// The following doesn't work neither:
// FileOutputStream fOut = new FileOutputStream(this.currUserImgUri.getPath());
// Write the compressed file into the output stream
bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The catched exception is as follows:
java.io.FileNotFoundException: /external/images/media/8439: open failed: ENOENT (No such file or directory)
Can anyone explain to me how can the file not exist if I just created it and have access to its URI?
Perhaps I'm going all wrong about it? In this case, what would be the correct way to save the rotated image to the same location based on its URI?
Upvotes: 2
Views: 7071
Reputation: 1818
Here's a Kotlin extension function which, given a URI to an image, will rotate the image and store it again at the same URI.
fun Context.rotateImage(imageUri: uri, angle: Float) {
// (1) Load from where the URI points into a bitmap
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri)
// (2) Rotate the bitmap
val rotatedBitmap = bitmap.rotatedBy(angle)
// (3) Write the bitmap to where the URI points
try {
contentResolver.openOutputStream(imageUri).also {
rotateBitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
}
} catch (e: IOException) {
// handle exception
}
}
fun Bitmap.rotatedBy(angle: Float) {
val matrix = Matrix().apply { postRotate(angle) }
return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}
You could instead define the function to accept the context as an argument, making the receiver whatever is convenient for you.
Upvotes: 1
Reputation: 1432
hey you can do this to write bitmap to file using .
// Rotate the Bitmap thanks to a rotated matrix. This seems to work.
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), photoURI);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//learn content provider for more info
OutputStream os=getContext().getContentResolver().openOutputStream(photoURI);
bmp.compress(Bitmap.CompressFormat.PNG,100,os);
don't forget flush and close output stream. actually content provider have it's own uri scheme.
Upvotes: 8