Extract exif information of image in android - android

Im new to android development and trying to get metadata of image using ExifInterface. I stored the image under drawable and trying to get the metadata but getting null values for all fields(date, imagelength, imagewidth). I tried to access image path as this :
String path = "drawable://" + R.drawable.testimage;
and provided this path to ExifInterface.
ExifInterface exif = new ExifInterface(path);
I dont know if storing image under drawable is correct or not because when I run the app in emulator I get something like this :
E/JHEAD﹕ can't open 'drawable://2130837561'
So if this is wrong then please tell me where should I store the image and how to provide image path to ExifInterface.
Thank you in advance.

To get a drawable, you can you this snippet:
Drawable drawable = getResources().getDrawable(android.R.drawable.your_drawable);
I'm not sure if your way is correct, as I've never seen it like that. Do you really need the path to your image to use it on that ExifInterface class?
Ok, I did some digging and found this question, which led me to this one. As it seems, you can not get an absolute path from a resource inside your apk. A good solution would be for you to save it as a file on the external memory, and then you can get the path you want.
First of all, add this to your AndroidManifest.xml, so your app can write to the cellphone memory:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Ok, to save it you can try this, first create a bitmap from your drawable resource:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.your_drawable);
After that get the path you want to save your images, and put it on a String. More info on that here.
The Android docs have a good example on how to get the path. You can see it here.
To keep it simple, I'll copy and paste the snippet from the docs.
void createExternalStoragePrivateFile() {
// Create a path where we will place our private file on external
// storage.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
file.delete();
}
}
boolean hasExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
return file.exists();
}
return false;
}
After that, get the path of the file you saved on the external memory, and do as you wish.
I'll keep the old example as well. You can use the method getExternalStorageDirectory() to get the path, or getExternalCacheDir(). After that, you can use File method called getAbsolutePath() to get your String.
String path = (...) // (you can choose where to save here.)
File file = new File(path, "your_drawable.png");
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // You can change the quality from 0 to 100 here, and the format of the file. It can be PNG, JPEG or WEBP.
out.flush();
out.close();
For more info on the Bitmap class, check the docs.
If you need more info, let me know and I'll try to show more samples.
EDIT: I saw your link, and there was this snippet there:
//change with the filename & location of your photo file
String filename = "/sdcard/DSC_3509.JPG";
try {
ExifInterface exif = new ExifInterface(filename);
ShowExif(exif);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(this, "Error!",
Toast.LENGTH_LONG).show();
}
As you can see, if you really want to see the exif data of a internal image resource, you'll have to save it somewhere else, and then you can try to get the absolute path for that File, then, call the method to show the exif.

Related

Where should I have users save the images that they made on my app

My users make custom images on my app and I am unsure what directory I should use when they save. Should I use MediaStore.Images.Media.EXTERNAL_CONTENT_URI?
Basically MediaStore.Images.Media.EXTERNAL_CONTENT_URI is part of Content Resolver which allow you to read and write resource from your user device. You need to ask yourself wether it is good to save their image into device. You could save your image in private or public which still decided by you. There is internal and external storage, wether you need all image to be deleted when your app is deleted or you don't want other app access the photo you user created use internal storage otherwise use external storage.Take a look on this link which take you step by step to understand why, which,how to save file into your app.
You can make a directory of your own app in the internal storage of the device and store all the pictures made from your app there.
You can make the directory using
File directory = new File(Environment.getExternalStorageDirectory() + File.separator + "<app name>");
if(!directory.exists){
directory.mkdirs;
}
And then store the pictures in this path
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String name = "<image name>"+n+".jpg";
File pictureFile = new File(directory, name);
pictureFile.createNewFile();
try {
FileOutputStream out = new FileOutputStream(pictureFile);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}

internal storage for app and uri

So I'm using the twitter api and I want to tweet with an image I use:
TweetUri = Uri.fromFile(saveIT);
TweetComposer.Builder builder = new TweetComposer.Builder(this)
.text("")
.image(TweetUri);
builder.show();
The original image is a bitmap, so what I did (not sure if this is the optimal way) was save in the internal storage:
private File saveToInternalStorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
String mImageName="MI_"+ timeStamp +".jpg";
File mypath=new File(directory,mImageName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try
{
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
return mypath;
}
The file it returns will be the "saveIT" in the TweetUri when it does the fromfile method. Of course this will overload the storage so what I plan to do is wipe the internal storage for the app when it is stopped (no other data is saved in the internal storage other than the temp images I save for the tweet):
#Override
protected void onStop() {
super.onStop();
File MSD = this.getApplicationContext().getFilesDir();
File [] lisFiles = MSD.listFiles();
for(int i=0;i<lisFiles.length;i++)
{
boolean deleted = lisFiles[i].delete();
}
}
None of this works... I can't seem to find any of the images when I save them to verify if the deleting is happening. Also, when the user clicks tweet no image is added to the tweet as well. No idea what I'm doing wrong here... In reality I don't want to save the image in the internal storage but I do because the tweet api uses a URI to tweet and not a bitmap.
I switched it to write to external storage and it worked fine. Also I switched it to delete at onDestroy. This is better because, when I invoke the Twitter API it switches activities so the onstop is invoked which would delete the temp picture too early. It's too early becuase if the user clicks cancel at the twitter api, comes back to my api and then invokes the twitter api again the uri will point to nothing since the picture was already deleted. THATS ALL FOLKS :)

Android. How to load the picture from memory knowing its full path?

I saved the picture on phone from application. I found a file manager it and I made sure that it really remained. Further I try to load on its full path it by BitmapFactory.decodeFile() method transferring a full path to the picture, a way to pictures at me such there, I will give an example from application:
/storage/emulated/0/Android/data/com .example.home.page/files/2015218161530.jpg
But me jumps out Exception, what decoding is impossible since the file isn't found, what for nonsense? Thanks in advance
You can use this method this will work for you
just pass path of images(where your image is store and object reference of you ImageView as a second argument)
1st argument Path of images want ot display
2nd argument object reference of `ImageView`
public static void ShowPicture(String filePath, ImageView pic) {
File f = new File(filePath);
FileInputStream is = null;
try {
is = new FileInputStream(f);
} catch (FileNotFoundException e) {
Log.d("error: ",String.format( "ShowPicture.java file[%s]Not Found",fileName));
return;
}
Bitmap = BitmapFactory.decodeStream(is, null, null);
pic.setImageBitmap(bm);
}
please also put this permission in manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
try below code that might help you.
File f = new File(PathToFiles +yourFileName);
if (f.exists()) {
Drawable d = Drawable.createFromPath(f.getPath());
imageview.setImageDrawable(d);
}

Save an Image in app folder

I'm new in Android development and I have an app that saves a 'jogador' (player) record with some attributes (name, birthday...) and a photo.
When the user picks the image from gallery, I populate an ImageView with the photo so that the user can see it before he saves the record. (It's working here).
My problem is that I want to save that photo in a folder created by me (Inside res/ folder). eg: res/myFolder.
I don't know how I will access that folder to put an image inside. Follow my code bellow:
Bitmap bmp = BitmapFactory.decodeFile(fotoPath); //---> It works
FileOutputStream fos;
try {
// 'fotos_jogador' is my folder inside res folder.
// I think that 'Environment.getExternalStorageDirectory()'
// gives me access to sdcard, but i don't want this, I want to save in a local app folder.
File file = new File(Environment.getExternalStorageDirectory() +
File.separator + "/fotos_jogador/" + ".png");
fos = new FileOutputStream(file);
//I want do store a low quality image, just for contact photo.
if(fos != null){
bmp.compress(CompressFormat.PNG, 20, fos);
fos.close();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
Then, guys, my doubts:
How can I give a custom name for my Image?
How can I Save the image in my folder 'fotos_jogador'?
How can I retrieve the Image after it's saved?
I appreciate the help. Thanks!
no you can not save anything in resource folder here is the link of duplicate post Is it possible to save image in assets folder from application
you can save image in sd card or in internal memory.

Compare one image with other images stored in the sdcard

How to compare one image token with camera with all the other images stored in the sd card and display the result?
public class SearchForFaces extends Activity {
Bitmap bitmapOriginale;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b1 = getIntent().getExtras();
String cin= b1.getString("cin");
//getting the image
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Student");
File file = new File(directory, cin+"jpg");
try {
FileInputStream streamIn = new FileInputStream(file);
bitmapOriginale = BitmapFactory.decodeStream(streamIn);
streamIn.close();
} catch (IOException e) {
Log.d("SearchForFaces Exception", e.getMessage());
}
if(bitmapOriginale.sameAs(//images from sdcard))
{
//display founded image
}
}
}
i think, its not necessary read all images..if you want compare images from camera, you can "easy" take the images in DCMI folder. But ok, user will move some files in another folder. So in that case i will advice just open first folder, read files in there and check the format, after that open another folder, read files in there and again check the formats and save the paths to the jpg files.
So in this case just easy some for, foreach, while cykl or you can do it with recursion.
You will have some ArrayList (linkedList, whatever) and in this list you can put the paths. Then just call your sameAs method.
On this you can use Environment.getExternalStorageDirectory().listFiles();
But..i am not sure if your "algorithm" will work..image recognition is really hard part of computer science..and if you dont know how to get the files on SDcard..the algorithm wouldnt probably work..
But if you want to check the similarity with byte by byte comparsion, then its ok..
Check also this blog http://mihaifonoage.blogspot.com/2009/09/displaying-images-from-sd-card-in.html It shows how to read an images from sd card. Once you read them you can use your sameAs() written method to compare them.

Categories

Resources