In a React Native app for Android, I am trying to write an image (passed as base64) onto the filesystem and later decode it using BitmapFactory.
Why is BitmapFactory still unable to decode the image after using (Base64.decode) while storing it?
The error:
Cannot decode bitmap:
file:///data/data/com.reactnativeapp/files/rct-image-store/1
The custom written method storing the image:
#ReactMethod
public void addImageFromBase64(String base64_image_data, Callback successCallback, Callback failureCallback){
String imageStorageDir = this.reactContext.getApplicationContext().getFilesDir()+"/rct-image-store/";
String file_uri = imageStorageDir+"1";
try {
File f = new File(imageStorageDir);
if(!f.exists()) {
f.mkdir();
}
FileOutputStream fos = new FileOutputStream(file_uri, false);
byte[] decodedImage = Base64.decode(base64_image_data, Base64.DEFAULT);
fos.write(decodedImage);
fos.close();
successCallback.invoke("file://"+file_uri);
} catch (IOException ioe) {
failureCallback.invoke("Failed to add image from base64String"+ioe.getMessage());
} catch (Exception e) {
failureCallback.invoke("Failed to add image from base64String"+e.getMessage());
}
}
Shortened method for accessing the image (fullResolutionBitmap is null):
InputStream inputStream = mContext.getContentResolver().openInputStream(Uri.parse(uri));;
BitmapFactory.Options outOptions = new BitmapFactory.Options();
Bitmap fullResolutionBitmap = BitmapFactory.decodeStream(inputStream, null, outOptions);/// fullResolutionBitmap==null
Here is the image, the bottom part looks cropped. Since both original and converted image have the grey area, the problem seems to be not with the conversion of the image, but with the source (camera).
Original image:
Converted image:
Related
Working on Android fashion app and downloading various images from AWS Cloudfront, then storing them locally on internal storage.
The same image looks different if I show it from my app or from the gallery app. It's not about display, I'm sure of this because I tested with the Photoshop color picker.
I guess it may depend on compression but I have maximum value (100). Also, I tried to write directly array byte to my memory and decode the array without any compression.
Look this image to better understand:
I know that Android handles different color profile and I've tried many of those, with no effects.
Also, I use Glide library to load the images and I set no cache and ARGB8888 color profile.
Then I tried to use Picasso, but nothing changed.
That's how I download and save the images:
#Override
protected Bitmap doInBackground(String... strings) {
try {
return BitmapFactory.decodeStream((InputStream)new URL(strings[0]).getContent());
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap != null) {
try {
String filename = colorImage.getUniqueId() + "_zoom.jpg";
// I tried this
File file = new File(getContext().getFilesDir(), filename);
FileOutputStream fos = new FileOutputStream(file, false);
// Writing the bitmap to the output stream
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
// But also this
// File file = new File(getContext().getFilesDir(), filename);
// FileOutputStream fos = new FileOutputStream(file, false);
// FileUtils.writeByteArrayToFile(file, array);
fos.close();
} catch (Exception e) {
Log.e("mylog", "saveInternalStorageError(): " + e.getMessage());
}
}
}
That's how I show the image (after I read all issues referenced here https://github.com/bumptech/glide/issues/515):
Glide.with(this)
.load(imageUriF)
.asBitmap()
.encoder(new BitmapEncoder(Bitmap.CompressFormat.JPEG, 100))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(firstImage);
I also tried to show the image without Glide with same results
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
img.setImageBitmap(myBitmap);
And Picasso too, with same results.
Have you got any idea about this issue?
Trying to get image from gallery, my photo uri : content://com.android.providers.media.documents/document/image%3A15672
when i don't use bmOptions(BitmapFactory.decodeStream(inStream)) i get bitmap image succesfully, but when i add bmOptionsBitmapFactory.decodeStream(inStream,null,bmOptions)) i get null bitmap, unable to figure out what am doing wrong.
private void setPic(Uri photoUri) {
InputStream inStream = null;
try {
inStream = getContentResolver().openInputStream(photoUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
Log.i("response", "INPUT STREAM| Bitmap : "+ BitmapFactory.decodeStream(inStream,null,bmOptions));
}
That is expected behavior if you use bmOptions.inJustDecodeBounds = true;, which can be translated to human language as don't load the bitmap, just resolve it's size and some other metadata. It is usually used to know Bitmap size before loading it to memory to prevent OOM exceptions, and load bitmap pre-down-scaled.
I'm stuck trying to load an image placed in assets folder with OpenCV 3.0 in Android. I've read a lot of answers here, but I can't figure out what I'm doing wrong.
"my image.jpg" is place directly in the assets folder created by Android Studio.
This is the code I'm using. I've checked and the library has been loaded correctly.
Mat imgOr = Imgcodecs.imread("file:///android_asset/myimage.jpg");
int height = imgOr.height();
int width = imgOr.width();
String h = Integer.toString(height);
String w = Integer.toString(width);
if (imgOr.dataAddr() == 0) {
// If dataAddr() is different from zero, the image has been loaded
// correctly
Log.d(TAG, "WRONG UPLOAD");
}
Log.d(h, "height");
Log.d(w, "width");
When I try to run my app, this is what I get:
08-21 18:13:32.084 23501-23501/com.example.android D/MyActivity: WRONG UPLOAD
08-21 18:13:32.085 23501-23501/com.example.android D/0: height
08-21 18:13:32.085 23501-23501/com.example.android D/0: width
It seems like the image has no dimensions. I guess because it has not been loaded correctly. I'va also tried to load it placing it in the drawable folder, but it doesn't work anyway and I'd prefer to use the assets one.
Anyone can please help me and tell me how to find the right path of the image?
Thanks
Problem: imread needs absolute path and your assets are inside a apk, and the underlying c++ classes cannot read from there.
Option 1: load image into Mat without using imread from drawable folder.
InputStream stream = null;
Uri uri = Uri.parse("android.resource://com.example.aaaaa.circulos/drawable/bbb_2");
try {
stream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmp = BitmapFactory.decodeStream(stream, null, bmpFactoryOptions);
Mat ImageMat = new Mat();
Utils.bitmapToMat(bmp, ImageMat);
Option 2: copy image to cache and load from absolute path.
File file = new File(context.getCacheDir() + "/" + filename);
if (!file.exists())
try {
InputStream is = context.getAssets().open(filename);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(buffer);
fos.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (file.exists()) {
image = cvLoadImage(file.getAbsolutePath(), type);
}
Hi I am working on application which gets .png files in byte stream from server. When I got it I try to make from it bmp and later convert it to .png file, but the following method ( Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length); ) returns me null.
Here is my code:
byte[] result
Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length);
try {
File filename = new File(imageUri.getPath()+name);
File parentFile = new File(imageUri.getPath());
parentFile.mkdirs();
FileOutputStream out = new FileOutputStream(filename);
img.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
Log.e("imageDownloaded", e.toString());
} catch (Exception e) {
Log.e("imageDownloaded", e.toString());
}
but the img Bitmap is always, null. I uploaded the image as multi part data and it was png file parsed to byte array, but now when i want to retrieve it i get this ugly null. Thanks for any help.
I'm working with bitmap and have some problems need to help:
My app works as below:
Load JPG image file(1) from SDcard to bitmap1
Save this bitmap1 to new JPG file(2).
Load new JPG image(2) file to bitmap2
Save bitmap2 to new JPG file(3) ....
.... repeat again and again
Now I can load/save bitmap to file, but problem is quality of image reduces after load/save.
So if I do load/save stuff for 10 times, so my image become ugly.
This is my code:
private void saveBitmapToFile(String imgPath) {
Log.e("Filename-----------------", imgPath);
// Decode image file to bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
// options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(imgPath, options);
// Get filename
long currentMili = System.currentTimeMillis();
currentName = currentMili + "";
String filePath = FOLDER_PATH + currentMili + ".jpg";
// Save bitmap to new file
try {
File file = new File(filePath);
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You're re-compressing a lossy file format. You're going to get image artifacts doing that. If you need to do this for some reason, use a lossless format like png.