Android : FileNotFoundException when trying to get an image from Uri - java

I am trying to get an image's width and height in order to rezize it in case it is too big before showing it. My method receive an uri of the image but I always get a FileNotFoundException when trying to decode it using BitmapFactory.
Here is a sample of my code :
Uri myUri;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(myUri.getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
Decode File returns throws a FileNotFoundException here. However, I can still show the image using the uri without using a bitmap factory using this :
Uri myUri;
Bitmap myBitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), myUri);
The problem with this code is that the returned bitmap might cause an OutofMemoryError when using big images.
When I debug my Uri, I get this :
content://com.android.providers.media.documents/document/image%3A20472
UPDATE || Here is the working code
Uri myUri;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// This is the part that changed
InputStream inputStream = context.getApplicationContext().getContentResolver().openInputStream(myUri);
BitmapFactory.decodeStream(inputStream,new Rect(),options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
All of this of course surrounded by try/catch.

Use decodeStream instead of decodeFile.
Open the stream with getContentResolver().openInputStream(myUri).

After playing around with this for a while, I think the issue is probably that the image file really isn't there.
If you are attempting to access a local file on your computer, that file won't be in the Android sandbox where the app is actually running. You'll need to add it to the app as a resource, then access it as a resource instead of a file.
If you are attempting to access a web image, you need to download it first. The AbsolutePath of a web image 'http://example.com/example.jpg' would be '/example.jpg', which won't do you much good when you try to open it.

Related

Convert Java Code of Bitmap into C# code In Console app

I am trying to convert Java code into c#
So here is Java code
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap decodeStream = BitmapFactory.decodeStream(openInputStream, null, options);
Then I am saving this bitmap by
File appDirectory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File dest = new File(appDirectory, "yourImage.jpg");
try (FileOutputStream out = new FileOutputStream(dest)) {
decodeStream.compress(Bitmap.CompressFormat.JPEG, 100, out); // bmp is your Bitmap instance
} catch (IOException e) {
e.printStackTrace();
}
Now can anyone help me to convert this code into c#. I Tried to import Xamrine Android DLL but got success no far.
I am
As far as I understand you only need to load simple jpg image. That is all your java code do.
If you want to load jpg image from stream you can use
Bitmap.FromStream()
e.g.
using (FileStream fs = new FileStream(#"Image Address.jpg", FileMode.Open, FileAccess.Read))
{
var decodeStream = Bitmap.FromStream(fs);
}
of course you can open your image without stream too.
var image = Bitmap.FromFile(#"Image Address.jpg");
So your code will be something like this
File appDirectory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File dest = new File(appDirectory, "yourImage.jpg");
var image = Bitmap.FromFile(dest.FullName);
You can not access Bitmap class out of the box.
For dot net core install package System.Drawing.Common.
For dot net framework add reference to System.Drawing.
For Xamarin see this answer https://stackoverflow.com/a/34869330/5964792

Create a Bitmap/Drawable from file path

I'm trying to create a Bitmap or Drawable from existing file path.
String path = intent.getStringExtra("FilePath");
BitmapFactory.Options option = new BitmapFactory.Options();
option.inPreferredConfig = Bitmap.Config.ARGB_8888;
mImg.setImageBitmap(BitmapFactory.decodeFile(path));
// mImg.setImageBitmap(BitmapFactory.decodeFile(path, option));
// mImg.setImageDrawable(Drawable.createFromPath(path));
mImg.setVisibility(View.VISIBLE);
mText.setText(path);
But setImageBitmap(), setImageDrawable() doesn't show an image from the path. I've printed path with mText and it looks like : /storage/sdcard0/DCIM/100LGDSC/CAM00001.jpg
What am i doing wrong? Anyone can help me?
Create bitmap from file path:
File sd = Environment.getExternalStorageDirectory();
File image = new File(sd+filePath, imageName);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(),bmOptions);
bitmap = Bitmap.createScaledBitmap(bitmap,parent.getWidth(),parent.getHeight(),true);
imageView.setImageBitmap(bitmap);
If you want to scale the bitmap to the parent's height and width then use Bitmap.createScaledBitmap function.
I think you are giving the wrong file path.
It works for me:
File imgFile = new File("/sdcard/Images/test_image.jpg");
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
//Drawable d = new BitmapDrawable(getResources(), myBitmap);
ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
myImage.setImageBitmap(myBitmap);
}
Edit:
If above hard-coded sdcard directory is not working in your case, you can fetch the sdcard path:
String sdcardPath = Environment.getExternalStorageDirectory().toString();
File imgFile = new File(sdcardPath);
here is a solution:
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
Well, using the static Drawable.createFromPath(String pathName) seems a bit more straightforward to me than decoding it yourself... :-)
If your mImg is a simple ImageView, you don't even need it, use mImg.setImageUri(Uri uri) directly.
For Drawable -
Drawable drawable = Drawable.createFromPath(your path in string);
For Bitmap -
Bitmap bitmap = BitmapFactory.decodeFile(your path in string);
How simple it was hope you like
static ArrayList< Drawable> d;
d = new ArrayList<Drawable>();
for(int i=0;i<MainActivity.FilePathStrings1.size();i++) {
myDrawable = Drawable.createFromPath(MainActivity.FilePathStrings1.get(i));
d.add(myDrawable);
}
you can't access your drawables via a path, so if you want a human readable interface with your drawables that you can build programatically.
declare a HashMap somewhere in your class:
private static HashMap<String, Integer> images = null;
//Then initialize it in your constructor:
public myClass() {
if (images == null) {
images = new HashMap<String, Integer>();
images.put("Human1Arm", R.drawable.human_one_arm);
// for all your images - don't worry, this is really fast and will only happen once
}
}
Now for access -
String drawable = "wrench";
// fill in this value however you want, but in the end you want Human1Arm etc
// access is fast and easy:
Bitmap wrench = BitmapFactory.decodeResource(getResources(), images.get(drawable));
canvas.drawColor(Color .BLACK);
Log.d("OLOLOLO",Integer.toString(wrench.getHeight()));
canvas.drawBitmap(wrench, left, top, null);

Relative path using setImageResource

I am trying to display an image in my app that changes everytime I press a button.
The name of the image that should be shown is in my object. I can get the name of the image with
String nameOfImage = myObhect.get(i).getImageName();
Now, I want to display the current image with
iv.setImageResource(R.drawable.notruf);
Using setImageResource , I don´t know how to bring the name of my image in setImageResource because, for example
iv.setImageResource(R.drawable. + aktbild) isn´t possible for sure.
I also tried the way with setImageDrawable but that does not work for me.
I use similar solution in my application :
Context mContext = this; // I supposed you're in Activity
String imgName = fragenkatalog.get(i).getBild();
int resId = mContext.getResources().getIdentifier(imgName,
"drawable", mContext.getApplicationInfo().packageName);
if(resId > 0){
iv.setImageResource(resId);
}
I believe that this code will help u..
String aktbild = fragenkatalog.get(i).getBild();
byte[] decodedString = Base64.decode(aktbild , Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
decodedString.length);
After that, if you want to resize that image use this code.
int width=75;
int height=75;
Bitmap resizedbitmap=Bitmap.createScaledBitmap(decodedByte, width, height, true);
finally set image into ImageView.
Icon.setImageBitmap(resizedbitmap);`

Decode a part of Bitmap from file in Android

I have a file with a very large image: for example 9000x9000.
I can't load the Bitmap in memory because the heap size. But I only need to display a small part of this bitmap for example the rect width=100-200 and height =200-400 (resulting size of the sub-bitmap =100x200)
How can I retrieve this bitmap from the file?
Note: I dont want to lose quality in the 100x200 image
Thanks
is it possible that there is a solution for this?
for example , BitmapRegionDecoder .
It should work for API10 and above...
Usage:
BitmapRegionDecoder.newInstance(...).decodeRegion(...)
It can easily be done using RapidDecoder.
I actually generated a 9000x9000 png which its file size is about 80MB and the 200x400 sized region was successfully loaded.
import rapid.decoder.BitmapDecoder;
Bitmap bitmap = BitmapDecoder.from("big-image.png")
.region(145, 192, 145 + 200, 192 + 400)
.decode();
imageView.setImageBitmap(bitmap);
It works for Android 2.2 and above.
I think that you can use the BitmapFactory method that allows you to specify the Rect that you want to decode.
public static Bitmap decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options opts)
Try this code:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float) height / (float) reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
I don't think you can. Not even on a PC, I fail to see how you could do that without loading the entire image: most image formats, for example PNGs, have the pixel data zipped, so you need to at least unzip the IDAT chunk before you can start doing anything else and that will basically decode the whole image.
In your shoes I would try to have a server do it for me. Where do you get the image anyway? Not from a server? Then try to make a WS request that will give you the proper part of the image. If the image does NOT come from the server you can nevertheless send it to your server to get back only the part of the image that you want.
try this code:
private Bitmap decodeFile(File f) {
Bitmap b = null;
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
b=Bitmap.createBitmap(BitmapFactory.decodeStream(fis, null, o), 100, 200, 200, 400, null, null);
fis.close();
} catch (IOException e) {
}
return b;
}
Am not sure, but this may give some idea to you

Display jpg from sdcard android

I cant get this to work anymore
Here is my code:
ImageView jpgView = (ImageView)findViewById(R.id.ImageView01);
String myJpgPath = "/sdcard/pic.jpg";
jpgView.setVisibility(View.VISIBLE);
//jpgView.setScaleType(ImageView.ScaleType.FIT_CENTER);
jpgView.setAdjustViewBounds(true);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bm = BitmapFactory.decodeFile(myJpgPath, options);
jpgView.setImageBitmap(bm);
Can anyone help?
You can just use bitmapdrawable, e.g.
ImageView jpgView = (ImageView)findViewById(R.id.ImageView01);
String myJpgPath = "/sdcard/pic.jpg";
BitmapDrawable d = new BitmapDrawable(getResources(), myJpgPath);
jpgView.setImageDrawable(d);
The image won't be shown if you open the emulator directly from the eclipse, by clicking run. You'll be able to access the SD card if you start the emulator using the command line, then click your app on the emulator.

Categories