i want to check orientation of an image so i found some code but it doesn't work because cursor is always null. My code is
File f = createImageFile(bitmap);
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = context.getContentResolver().query(Uri.parse(f.toString()), orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
private static File createImageFile(Bitmap bitmap) {
//create a file to write bitmap data
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(fullPath, "image"+ System.currentTimeMillis()+".jpg");
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//Convert bitmap to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (bitmap != null) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 /*ignored for PNG*/, bos);
}
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return f;
}
But cur always returns null.I searched for converting file to uri so i found two methods Uri.parse(f.toString() and Uri.fromFile(f) but none has worked.
Related
Here i am making drawable view into bitmap.
mDrawingPad.setVisibility(View.VISIBLE);
BitmapDrawable ob = new BitmapDrawable(getResources(),
bitmapconv);
DrawingView mDrawingView=new
DrawingView(Previewimage.this);
mDrawingPad.addView(mDrawingView);
mDrawingView.setBackground(ob);
mDrawingView.buildDrawingCache();
drawbitmap=mDrawingView.getDrawingCache();
I need to convert this into URI to send to image cropper library
CropImage.activity(uri).start(Previewimage.this);
/*This saveImage method will return String path*/
path = saveImage();
Uri uri = Uri.parse(path);
/****************************************************/
private String saveImage()
{
Bitmap bitmap;
mDrawingView.setDrawingCacheEnabled(true);
mDrawingView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mDrawingView.buildDrawingCache();
bitmap = Bitmap.createBitmap(mDrawingView.getDrawingCache());
String state = Environment.getExternalStorageState();
String root = "";
String fileName = "/MyImage" + System.currentTimeMillis() + "Image"+ ".jpg";
String parent = "App_Name";
File mFile;
if (Environment.MEDIA_MOUNTED.equals(state)) {
root = Environment.getExternalStorageDirectory().toString();
mFile = new File(root, parent);
if (!mFile.isDirectory())
mFile.mkdirs();
} else {
root = FriendsImageSending.this.getFilesDir().toString();
mFile = new File(root, parent);
if (!mFile.isDirectory())
mFile.mkdirs();
}
String strCaptured_FileName = root + "/App_Name" + fileName;
File f = new File(strCaptured_FileName);
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 95, bytes);
FileOutputStream fo;
fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
bitmap.recycle();
System.gc();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return strCaptured_FileName;
}
This part of code works:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
your_bitmap_image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(your_context.getContentResolver(), your_bitmap_image, "your_title", null);
Uri uri = Uri.parse(path);
just try to replace the areas that I mentioned in it
in the place of "your_context" if you are in an activity put this:
MediaStore.Images.Media.insertImage(getContentResolver(), your_bitmap_image, "your_title", null);
Uri uri = Uri.parse(path);
if you are in a fragment :
MediaStore.Images.Media.insertImage(getContext().getContentResolver(), your_bitmap_image, "your_title", null);
Uri uri = Uri.parse(path);
Use this method:
public Uri getImageUri(Context ctx, Bitmap bitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(ctx.getContentResolver(),
bitmap, "Temp", null);
return Uri.parse(path);
}
If you are calling this method inside an Activity then call this method like this:
getImageUri(YourClassName.this, yourbitmap);
But if you are calling this in an Fragment then call like this:
getImageUri(getActivity(), yourbitmap);
In my app I'm trying to add an EXIF attribute to a contact photo when I add it to either a new or existing contact. This is so I can later check to see if it was My_App that changed the photo. I add the EXIF data like this:
private void addPhotoToExistingContact(long rawContactId, byte[] photoByteArray) {
if (photoByteArray != null) {
try {
photoByteArray = addExifDataToContactPhoto(photoByteArray);
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photoByteArray);
context.getContentResolver().insert(
ContactsContract.Data.CONTENT_URI,
values);
}
}
private byte[] addExifDataToContactPhoto(byte[] photoByteArray) throws IOException {
// Convert to temp file
File file = new File(context.getCacheDir(), "contact_photo_exif_temp_file.jpg");
if (file.exists()) {
file.delete();
}
FileOutputStream fos = new FileOutputStream(file.getAbsoluteFile());
fos.write(photoByteArray);
fos.close();
// Add EXIF data
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
exif.setAttribute(MY_EXIF_TAG, MY_EXIF_VALUE);
exif.saveAttributes();
// Convert back to byte[]
byte[] photoByteArrayWithExifData = FileUtils.readFileToByteArray(file);
// Delete temp file
file.delete();
return photoByteArrayWithExifData;
}
My check for EXIF data (done at a later time) is as follows:
private boolean shouldReplaceContactPhoto(long contactId) {
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = ?",
new String[] { ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE, String.valueOf(contactId) },
null);
if (cursor != null) {
if (cursor.moveToFirst()) {
long photoId = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data.PHOTO_ID));
if (photoId == 0) {
cursor.close();
return true;
}
else {
// Read EXIF data to check if photo is a My_App photo
File contactPhotoTempFile = getExistingContactImageFile(contactId);
if (contactPhotoTempFile != null) {
try {
ExifInterface exif = new ExifInterface(contactPhotoTempFile.getAbsolutePath());
String swopTag = exif.getAttribute(MY_EXIF_TAG);
// Temporary image, so delete it when we're done reading EXIF data
contactPhotoTempFile.delete();
cursor.close();
// If tag is null, the photo came from a different source - return 'true'
// so it is not replaced.
return myTag != null;
} catch (IOException e) {
e.printStackTrace();
// Temporary image, so delete it when we're done reading EXIF data
contactPhotoTempFile.delete();
}
}
cursor.close();
return true;
}
}
cursor.close();
}
return true;
}
private File getExistingContactImageFile(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
byte[] imageBytes;
try {
AssetFileDescriptor fd = context.getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
InputStream inputStream = fd.createInputStream();
imageBytes = IOUtils.toByteArray(inputStream);
} catch (IOException e) {
return null;
}
if (imageBytes == null) {
return null;
}
File file = new File(context.getCacheDir(), "contact_photo_temp_file.jpg");
if (file.exists()) {
file.delete();
}
try {
FileOutputStream fos = new FileOutputStream(file.getPath());
fos.write(imageBytes);
fos.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
return file;
}
I've added break points and log statements and I'm almost 100% positive that the attribute is being written, but when I read the data, the property is missing. I also noticed that the orientation attribute is changed from 1 to 0 as well, which leads me to believe that Android is overwriting the EXIF data.
Is this the case, or am I doing something incorrectly? Any help at all is extremely appreciated!
At start up of my app I want to extract my images (if they does not exists) from drawable folder to internal app folder to use later with FileProvider. Images have dimensions 2000*2000 and average size 380kb, format png.
Those images are not to be displayed (smaller ones are used to display). They are only for file sharing and I have to keep their original size.
I get out of memory at calling
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
Code
private void extractImages() {
TypedArray imgs = getResources().obtainTypedArray(R.array.smile_list_share);
File imagePath = new File(getFilesDir(), "images");
File checkImage;
for (int i = 0; i < imgs.length(); i++) {
int imageResID = imgs.getResourceId(i, 0);
if (imageResID > 0) {
String name = getResources().getResourceEntryName(imageResID);
checkImage = new File(imagePath, name + ".png");
if (!checkImage.exists()) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
boolean b = saveBitmapToFile(imagePath, name + ".png", bm, Bitmap.CompressFormat.PNG, 100);
Log.e("mcheck","saved "+b+", file "+name);
Log.e("mcheck", "file does not exists " + name);
} else {
Log.e("mcheck", "file exists " + name);
}
} else {
Log.e("mcheck", "ERROR " + i);
}
}
imgs.recycle();
}
public boolean saveBitmapToFile(File dir, String fileName, Bitmap bm,
Bitmap.CompressFormat format, int quality) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
bm.compress(format, quality, fos);
bm.recycle();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
You have to call recycle on your bitmap object everytime you are done with it.
Here is a good guide on how to manipulate bitmaps efficiently
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I found that I dont need to create bitmap object at all. It is possible to obtaine intput stream from getResourses directly.
public boolean saveBitmapToFile(File dir, String fileName, int imageResourse) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
InputStream inputStream = null;
try {
fos = new FileOutputStream(imageFile);
inputStream = getResources().openRawResource(imageResourse);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
inputStream.close();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
I was looking at the Parse Android docs and saw that to save photos and videos, you have to initialize a new ParseFile with a name and a byte[] of data and save it.
What's the easiest way to convert an image Uri and video Uri to a byte array?
Here are my attempted solutions:
mPhoto = new ParseFile("img", convertImageToBytes(Uri.parse(mPhotoUri)));
mVideo = new ParseFile ("vid", convertVideoToBytes(Uri.parse(mVideoUri)));
private byte[] convertImageToBytes(Uri uri){
byte[] data = null;
try {
ContentResolver cr = getBaseContext().getContentResolver();
InputStream inputStream = cr.openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
data = baos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return data;
}
private byte[] convertVideoToBytes(Uri uri){
byte[] videoBytes = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(new File(getRealPathFromURI(this, uri)));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
videoBytes = baos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return videoBytes;
}
private String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Video.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null,
null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
The convertImageToBytes and convertVideoToBytes methods work for now, but I'm just wondering If I'm doing doing this correctly.
From Uri to get byte[] I do the following things,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(new File(yourUri));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
byte[] videoBytes = baos.toByteArray(); //this is the video in bytes.
I m not able to convert the bitmap into string and pass it to the JSON by send the intent.putExtra.....And on receiving it on Create method of next activity....
The Default is giving error and i have jpeg images ...
How to fix this problem....
Intent Intent inn=getIntent()
bitmap = (Bitmap) inn.getParcelableExtra("bmp_img");
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] b=baos.toByteArray();
String temp=Base64.encodeToString(b, Base64.DEFAULT);
public String imageCompression(String image) {
// to compress image
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
Bitmap b = BitmapFactory.decodeFile(image, bmpFactoryOptions);
Bitmap out = Bitmap.createScaledBitmap(b, 300, 300, false);
String[] bits = image.split("/");
String lastOne = bits[bits.length - 1];
File imageFile = null;
File imagesFolder = new File(Environment.getExternalStorageDirectory(),
"CompressedImages");
if (imagesFolder.isDirectory()) {
imageFile = new File(imagesFolder, lastOne);
FileOutputStream fOut;
try {
fOut = new FileOutputStream(imageFile);
out.compress(Bitmap.CompressFormat.JPEG, 90, fOut);
fOut.flush();
fOut.close();
b.recycle();
out.recycle();
} catch (Exception e) {
e.printStackTrace();
}
} else {
imagesFolder.mkdirs();
imageFile = new File(imagesFolder, lastOne);
FileOutputStream fOut;
try {
fOut = new FileOutputStream(imageFile);
out.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
b.recycle();
out.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
File file = new File(imageFile.getPath());
byte imageData[] = new byte[(int) file.length()];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e3) {
e3.printStackTrace();
}
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
try {
bis.read(imageData, 0, imageData.length);
} catch (IOException e1) {
e1.printStackTrace();
}
imageDataString = Base64.encodeToString(imageData, 0);
return imageDataString;
}
Use this methord and for intent passing pass just as String ......
i assume u are navigate from TO Activity A and B in sort of A->B
in A
Uri imageUri = Uri.parse("android.resource://your.package/drawable/fileName");
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(intent)
and in B
Intent intent = this.getIntent();
(Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);