Related
I need to access the specific folder depending on the name of the created project. In Main_Activity the name of this project is filled and new folder is created. Thus, Camera_Activity saves the photos taken in that folder. Next I access Gallery_Activity, but it never goes to the folder of the created project. How can I access to that folder?
An example: Name of the created folder: Proj_1, but user select the photos from another one that opens by default, the uri that comes out is:
content://com.android.externalstorage.documents/document/primary%3APictures%2FCaptures_Camera2%2FProj_aa%2Fpic_040621_110254.jpeg
Part of AndroidManifest.xml
...
<uses-feature android:name="android.hardware.camera2.full" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
...
MainActivity.java
...
createNewProject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Coge el nombre de EditText, crea nueva carpeta y empieza la captura de las imagenes
if(newName.getText().toString().isEmpty()){
Toast.makeText(getApplicationContext(), "Please, fill in the field.", Toast.LENGTH_LONG).show();
} else {
name = newName.getText().toString();
GlobalVariables.ProjectName = name;
Intent intent = new Intent(MainActivity.this, Camera_Activity.class);
startActivity(intent);
}
}
});
...
Camera_Activity.java takes the necessary photos, saves them and has a button to enter the gallery:
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mTextureView = findViewById(R.id.camera_preview);
btn_take_pic = findViewById(R.id.button_take_photo);
acceptButton = findViewById(R.id.btn_ok);
cancelButton = findViewById(R.id.btn_cancel);
btn_gallery = findViewById(R.id.go_to_gallery);
imagePreview = findViewById(R.id.image_view_photo_preview);
...
// File name to save the picture
// First is getting the new project name from previous Activity:
String newProjName = GlobalVariables.ProjectName;
// Creating part of the name for image: timestamp. That will be: pic_tamestamp.jpeg
#SuppressLint("SimpleDateFormat") String timestamp = new SimpleDateFormat("ddMMyy_HHmmss").format(new Date());
directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Captures_Camera2/Proj_" + newProjName);
GlobalVariables.MyDirectoryPath = directory.getPath();
if (!directory.exists() || !directory.isDirectory())
directory.mkdirs();
mFile = new File(directory, "pic_" + timestamp + ".jpeg");
pathToFile = mFile.getPath();
....
// ------------ GO TO GALLERY ---------
btn_gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "You are going to Gallery...");
Intent GalleryIntent = new Intent(context, Gallery_Activity.class);
startActivity(GalleryIntent);
}
});
// ------------ SAVE PHOTO TO THE GALLERY ---------
acceptButton.setOnClickListener(new View.OnClickListener() {//26
#Override
public void onClick(View v) {
Toast.makeText(context, "Image saved to " + pathToFile, Toast.LENGTH_LONG).show();
// Recreating the activity with a new instance
recreate();
}
});
...
Gallery_Activity.java
public class Gallery_Activity extends AppCompatActivity implements View.OnClickListener, View.OnLongClickListener {
private static final String TAG = "GalleryActivity";
private final Context context = this;
private ImageView imageView1, imageView2;
private final int CODE_IMAGE_GALLERY_FIRST = 1;
private final int CODE_IMAGE_GALLERY_SECOND = 2;
private final int CODE_MULTIPLE_IMAGES_GALLERY = 3;
// Variables to check the name
private String directoryPath;
private String MyPath1 = null;
private String MyPath2 = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Keeping the screen on even when there is no touch interaction
final Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_gallery);
imageView1 = findViewById(R.id.imageView1);
// If you make a short click in the ImageView, you can choose only one image, if it is long click, you can choose two images
imageView1.setOnClickListener(this);
imageView1.setOnLongClickListener(this);
imageView2 = findViewById(R.id.imageView2);
imageView2.setOnClickListener(this);
imageView2.setOnLongClickListener(this);
directoryPath = GlobalVariables.MyDirectoryPath;
Log.d(TAG, " The path from Camera_Activity is: " + directoryPath); // /storage/emulated/0/Pictures/Captures_Camera2/Proj_*
chooseMultipleImages();
}
private void chooseMultipleImages() {
// TODO: here it does NOT enter the giving folder although using the path
startActivityForResult(Intent.createChooser(new Intent()
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
.setAction(Intent.ACTION_GET_CONTENT)
.setType("image/*")
,"Selecting two images.."), CODE_MULTIPLE_IMAGES_GALLERY);
}
....
public void processImages(View view) {
//Toast.makeText(context, "Going to detect features...", Toast.LENGTH_SHORT).show();
Intent processIntent = new Intent(context, ImageProcessing.class);
startActivity(processIntent);
finish();
}
#Override
public boolean onLongClick(View v) {
recreate();
return false;
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.imageView1){
startActivityForResult(Intent.createChooser(new Intent()
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
.setAction(Intent.ACTION_GET_CONTENT)
.setType("image/*")
,"Selecting first image.."), CODE_IMAGE_GALLERY_FIRST);
}
else if(v.getId() == R.id.imageView2){
startActivityForResult(Intent.createChooser(new Intent()
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
.setAction(Intent.ACTION_GET_CONTENT)
.setType("image/*")
,"Selecting second image.."), CODE_IMAGE_GALLERY_SECOND);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ContentResolver resolver = this.getContentResolver();
// Get data from the folder
assert data != null;
Uri MyData = data.getData(); // for simple image
ClipData MultiImg = data.getClipData(); // for multiple images
GlobalVariables.countImg = MultiImg.getItemCount();
/* ******************************************
To pick multiples images from Gallery
******************************************
*/
if (requestCode == CODE_MULTIPLE_IMAGES_GALLERY && resultCode == RESULT_OK ){
/*
// TODO: For multiple images, more than 2 change this
int count = data.getClipData().getItemCount(); //evaluate the count before the for loop --- otherwise, the count is evaluated every loop.
for(int i = 0; i < count; i++)
Uri imageUri = data.getClipData().getItemAt(i).getUri();*/
// MultiImg != null was simplifyed since you cannot continue without any selection -> data never be null
if(GlobalVariables.countImg == 2){
// Getting name of the picture and print it
MyPath1 = MultiImg.getItemAt(0).getUri().toString();
MyPath2 = MultiImg.getItemAt(1).getUri().toString();
String Name1 = StringUtils.right(MyPath1,22);
String Name2 = StringUtils.right(MyPath2,22);
//String Proj_name = StringUtils.
GlobalVariables.PictureName1 = Name1;
GlobalVariables.PictureName2 = Name2;
Log.d(TAG, "--- First data name: " + StringUtils.right(MyPath1,22));
Log.d(TAG, "--- Second data name: " + StringUtils.right(MyPath2,22));
//Log.d(TAG, "Selected Items: " + clipData.getItemCount());
Log.d(TAG, "The full path is: " + MultiImg.getItemAt(0).getUri().toString());
// Showing images in the imageView
imageView1.setImageURI(MultiImg.getItemAt(0).getUri());
imageView2.setImageURI(MultiImg.getItemAt(1).getUri());
} else if (MyData != null ){
Log.d(TAG, "Only one image selected..");
Toast.makeText(context, "You should select 2 images and not only one", Toast.LENGTH_LONG).show();
recreate();
}
// MultiImg != null was simplifyed since you cannot continue without any selection -> data never be null
else if (GlobalVariables.countImg > 2){
//Log.d(TAG, "More than two selected images...");
Toast.makeText(context, "You should select 2 images and not ..." + GlobalVariables.countImg, Toast.LENGTH_LONG).show();
recreate();
}
}
/* ******************************************
To pick only one image fom Gallery for
each of ImageView and check that they
are different.
******************************************
*/
// pick image to the imageView1
else if(requestCode == CODE_IMAGE_GALLERY_FIRST && resultCode == RESULT_OK && MyData != null){
MyPath1 = MyData.getPath();
//Log.d(TAG, "\n ******** imageView1 has an image: \n" + StringUtils.right(MyPaths1,22) + "\n imageView2 has an image: \n" + StringUtils.right(MyPaths2,22));
assert StringUtils.right(MyPath1, 22) != null;
if(StringUtils.right(MyPath1,22).equals(StringUtils.right(MyPath2,22))){
Toast.makeText(context, "The images have to be different. Choose other image." , Toast.LENGTH_LONG).show();
}
else{
GlobalVariables.PictureName1 = StringUtils.right(MyPath1,22);
imageView1.setImageURI(MyData);
}
}
// pick image to the imageView2
else if(requestCode == CODE_IMAGE_GALLERY_SECOND && resultCode == RESULT_OK && MyData != null) {
MyPath2 = MyData.getPath();
//Log.d(TAG, "\n ******** imageView1 has an image: \n" + StringUtils.right(MyPaths1,22) + "\n imageView1 has an image: \n" + StringUtils.right(MyPaths2,22));
if(StringUtils.right(MyPath1,22).equals(StringUtils.right(MyPath2,22))){
Toast.makeText(context, "The images have to be different. Choose other image." , Toast.LENGTH_LONG).show();
}
else{
GlobalVariables.PictureName2 = StringUtils.right(MyPath2,22);
imageView2.setImageURI(MyData);
}
}
}
....
}
Can someone advise me on how I can solve this problem?
It is clear that I could leave things as they are and tell the user to check the folder where he selects the photos. But I would like it to be something more fluid and intuitive.
Thanks in advance.
private ArrayList<File> m_list = new ArrayList<File>();
String folderpath = Environment.getExternalStorageDirectory()
+ File.separator + "folder_name/";
File dir = new File(folderpath);
m_list.clear();
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
if (!file.getPath().contains("Not_Found"))
m_list.add(file);
}
}
So we're trying to implement an upload image feature in our Android App.
In our registration page, there is an upload button and once pressed, it should redirect to the image gallery and once an image is selected, it should be displayed in the ImageView placed.
Here's an excerpt of the code we're trying to work on.
The issue is, for some images it is correctly displayed but for some, it is either rotated 90 degrees to the right or 180 degrees.
What could be the issue?
public class Register extends AppCompatActivity {
private String mName = "";
private String mUsername = "";
private String mPassword = "";
private String mCompany = "";
private String mContact = "";
private static final int PICK_IMAGE = 100;
ImageView imageView;
Uri imageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Intent recvdIntent = getIntent();
mName = recvdIntent.getStringExtra("NAME");
mUsername = recvdIntent.getStringExtra("USERNAME");
mPassword = recvdIntent.getStringExtra("PASSWORD");
mCompany = recvdIntent.getStringExtra("COMPANY");
mContact = recvdIntent.getStringExtra("CONTACT");
imageView = (ImageView)findViewById(R.id.imageView);
Button btnSubmit = (Button) findViewById(R.id.btn_register);
btnSubmit.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
submitUserData();
Intent launchIntent = new Intent(Register.this, Category.class);
return;
}
}
);
Button upload = (Button) findViewById(R.id.btn_upload);
upload.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
openGallery();
}
});
return;
}
private void openGallery() {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
imageUri = data.getData();
imageView.setImageURI(imageUri);
}
}
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
private void submitUserData() {
EditText edtName = (EditText) findViewById(R.id.edt_name);
EditText edtCompany = (EditText) findViewById(R.id.edt_company);
EditText edtContact = (EditText) findViewById(R.id.edt_contact);
EditText edtUsername = (EditText) findViewById(R.id.edt_username);
EditText edtPassword = (EditText) findViewById(R.id.edt_password);
TaraApp2 app = (TaraApp2) getApplication();
app.saveUserData(edtName.getText().toString(),edtUsername.getText().toString(),
edtPassword.getText().toString(),
edtCompany.getText().toString(),
edtContact.getText().toString() );
finish();
return;
}
}
Uri selectedImageUri = data.getData();
Bitmap bitmap = scaleImage(this,selectedImageUri);
public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
for getting url of the image use this
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
For accessing picture from your gallery you can use the croperino library.
https://android-arsenal.com/details/1/4374
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Croperino.prepareGallery(MainActivity.this);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CroperinoConfig.REQUEST_PICK_FILE:
if (resultCode == Activity.RESULT_OK) {
CroperinoFileUtil.newGalleryFile(data, MainActivity.this);
Croperino.runCropImage(CroperinoFileUtil.getmFileTemp(),
MainActivity.this, true, 1, 1, 0, 0);
}
break;
case CroperinoConfig.REQUEST_CROP_PHOTO:
if (resultCode == Activity.RESULT_OK) {
Uri i = Uri.fromFile(CroperinoFileUtil.getmFileTemp());
ivMain.setImageURI(i);
//Do saving / uploading of photo method here.
//The image file can always be retrieved via
CroperinoFileUtil.getmFileTemp()
}
break;
default:
break;
}
}
I am still a rookie in terms of java and android programming, I believe I have come far in the last weeks but now I'm a little bit stuck and I would really appreciate your help.
I am trying to develop an app that can create a User profile Layout. So far I have it ready, drawing the user's data from a web service. But now I have to add a way for the user to upload his photo from gallery or camera. So far I have achieved this with the next code:
public void loadimage (View view)
{
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri targetUri = data.getData();
picture_location = targetUri.toString();
textTargetUri.setText(picture_location);
Bitmap bitmap;
try
{
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
targetImage.setImageBitmap(bitmap);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}
This truly works in drawing the image from galley and displaying the path file on screen (well, this isn't gonna make it to my final version) however, when I enter another layout/activity, the loaded image banishes and I have to upload it again. I am trying with the next saving method:
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
image = savedInstanceState.getParcelable("BitmapImage");
targetImage.setImageBitmap(image);
textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
}
#Override
public void onSaveInstanceState (Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelable("BitmapImage", bitmap);
savedInstanceState.putString("path_to_picture", picture_location);
}
However, this only works on sreen orientarion changes, not for layout/activity changes. Is there a way to make the uploaded image stay even though the activity changes? My server is pretty small in terms of memory, so uploading to it isn't a good option, I have to keep it local. Please help :(
Try these two methods:
First, show them a dialog to select option:
private void selectImage() {
final CharSequence[] items = { getString(R.string.take_photo), getString(R.string.choose_from_gallery),
getString(R.string.cancel) };
AlertDialog.Builder builder = new AlertDialog.Builder(MyAccountActivity.this);
builder.setTitle(getString(R.string.upload_photo));
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals(getString(R.string.take_photo))) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
} else if (items[item].equals(getString(R.string.choose_from_gallery))) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, getString(R.string.select_file)),
SELECT_FILE);
} else if (items[item].equals(getString(R.string.choose_from_gallery))) {
dialog.dismiss();
}
}
});
builder.show();
}
Receiving the actual image when a user has taken picture or selected from Gallery:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE)
onSelectFromGalleryResult(data);
else if (requestCode == REQUEST_CAMERA)
onCaptureImageResult(data);
else if (requestCode == Crop.REQUEST_CROP) {
handleCrop(resultCode, data);
}
}
}
Next is to handle cropping if you need - this is not necessary for this code to work but you can use it;
private void onCaptureImageResult(Intent data) {
beginCrop(data.getData());
}
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Uri selectedImageUri = data.getData();
beginCrop(selectedImageUri);
}
private void beginCrop(Uri source) {
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
}
private void handleCrop(int resultCode, Intent result) {
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = handleSamplingAndRotationBitmap(this, Crop.getOutput(result));
saveToInternalStorage(bitmap);
mUserProfilePhoto.setImageBitmap(readFromInternalStorage("profile.png"));
}catch (IOException e){ /* do nothing here */}
} else if (resultCode == Crop.RESULT_ERROR) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}
Sometimes, you might want to rotate the image if it is not upright:
private static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage) throws IOException {
int MAX_HEIGHT = 1024;
int MAX_WIDTH = 1024;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
BitmapFactory.decodeStream(imageStream, null, options);
imageStream.close();
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
imageStream = context.getContentResolver().openInputStream(selectedImage);
Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);
img = rotateImageIfRequired(img, selectedImage);
return img;
}
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee a final image
// with both dimensions larger than or equal to the requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down further
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException {
ExifInterface ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}
For storing as soon as the user picks from gallery or takes from Camera:
private boolean saveToInternalStorage(Bitmap image) {
try {
FileOutputStream fos = this.openFileOutput("profile.png", Context.MODE_PRIVATE);
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
return true;
} catch (Exception e) {
return false;
}
}
Now for reading from storage:
private Bitmap readFromInternalStorage(String filename){
try {
File filePath = this.getFileStreamPath(filename);
FileInputStream fi = new FileInputStream(filePath);
return BitmapFactory.decodeStream(fi);
} catch (Exception ex) { /* do nothing here */}
return null;
}
Inside onResume, I have this code to set the image to imageview:
#Override
public void onResume(){
super.onResume();
Bitmap savedProfilePhoto = readFromInternalStorage("profile.png");
if (savedProfilePhoto != null){
mUserProfilePhoto.setImageBitmap(savedProfilePhoto);
}
}
Almost done here:
Add this to your dependencies (build.gradle)
dependencies{
compile 'com.soundcloud.android:android-crop:1.0.1#aar'
}
Finally, in your android manifest file, for cropping library to work, add this:
<activity android:name="com.soundcloud.android.crop.CropImageActivity"/>
That is all you need to enable selecting image from gallery or taking photo using your camera inside your app!
I hope this helps you and anyone else in need and good luck!
So I'm working on a project where I take in an image from either gallery or camera and get a series of statistics from the image (brightness, contrast, sharpness, etc). Currently I have this working from gallery. I can open gallery, pull an image, and if a face is detected it will be cropped in a 2nd imageview. The stats are gathered from the cropped image ( see showimage(bitmap) in the gallery button area ). I've been struggling for the last week trying to get the same thing to work from the camera.
I'm currently using the following open source projects for getting the image from gallery and for cropping the face from the image:
https://github.com/hanscappelle/SO-2169649
https://github.com/lafosca/AndroidFaceCropper
I've made some advancements, and then backtracked a lot because I think I was trying to do it wrong. Here is my current working code for JUST gallery:
public class MainActivity extends AppCompatActivity {
// this is the action code we use in our intent,
// this way we know we're looking at the response from our own action
private static final int SELECT_SINGLE_PICTURE = 101;
public static final String IMAGE_TYPE = "image/*";
/* Get the reference to the text label */
TextView label = null;
private ImageView selectedImagePreview;
private ImageView imageViewFace;
void showImage(Bitmap image)
{
/* Get the starting time */
long startTime = 0;
startTime = System.nanoTime();
/* Get the image statistics */
ImageStats imageStats = new ImageStats(image);
System.out.println("Execution time: " + (((double)(System.nanoTime() - startTime))/1000000000.0) + " seconds!");
/* Get the image statistics */
double[] stats = imageStats.getStats();
/* Decide whether or not the image is of good quality */
String results = imageStats.result;
/* Create the labels */
String[] labels = new String[]{"Standard Luminosity: ", "Contrast: ", "Face orientation: ", "Sharpness: "};
/* The string of statistics */
StringBuffer strStatsBuff = new StringBuffer();
/* Go through all the statistics */
for(int statIndex = 0; statIndex < stats.length; ++statIndex)
{
/* Add the statistics */
strStatsBuff.append(labels[statIndex]);
strStatsBuff.append(String.valueOf(stats[statIndex]));
strStatsBuff.append("\n");
}
/* Add the file name */
strStatsBuff.append("\n");
strStatsBuff.append(results);
/* Set the label and show the cropped image */
label.setText(strStatsBuff.toString());
FaceCropper mFaceCropper = new FaceCropper();
mFaceCropper.setEyeDistanceFactorMargin(0);
image = mFaceCropper.getCroppedImage(image);
imageViewFace.setImageBitmap(image);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// no need to cast to button view here since we can add a listener to any view, this
// is the single image selection
label = (TextView)findViewById(R.id.label);
findViewById(R.id.buttonGallery).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType(IMAGE_TYPE);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select image"), SELECT_SINGLE_PICTURE);
}
});
selectedImagePreview = (ImageView)findViewById(R.id.imageView1);
imageViewFace = (ImageView)findViewById(R.id.imageViewFace);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_SINGLE_PICTURE) {
Uri selectedImageUri = data.getData();
try {
Bitmap bitmap;
selectedImagePreview.setImageBitmap(new UserPicture(selectedImageUri, getContentResolver()).getBitmap());
bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImageUri));
showImage(bitmap);
} catch (IOException e) {
Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
e.printStackTrace();
}
}
} else {
// report failure
Toast.makeText(getApplicationContext(),"failed to get intent data", Toast.LENGTH_LONG).show();
Log.d(MainActivity.class.getSimpleName(), "Failed to get intent data, result code is " + resultCode);
}
}
}
My "closest to working" method pulled an image from the camera, but both the original imageview and the imageview that should have been cropped to face both just showed the original image.
I had the following included under oncreate -
findViewById(R.id.buttonCamera).setOnClickListener(new View.OnClickListener(){
public void onClick(View arg0 ){
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
and this included in onactivityresult -
else if (requestCode==CAMERA_REQUEST && resultCode == RESULT_OK){
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
selectedImagePreview.setImageBitmap(bitmap);
showImage(bitmap);
}
Welcome to any suggestions! If you need any more info or I haven't provided something obvious, let me know. I'm new to stackoverflow, java, and android. Thanks!
I have a solution now. If anyone needs to do the same or similar here's what mine looks like:
public class MainActivity extends AppCompatActivity {
// this is the action code we use in our intent,
// this way we know we're looking at the response from our own action
private static final int SELECT_SINGLE_PICTURE = 101;
private static final int CAMERA_REQUEST = 102;
public static final String IMAGE_TYPE = "image/*";
private final int RequestCode = 20;
Uri mImageCaptureUri1;
/* Get the reference to the text label */
TextView label = null;
ImageView selectedImagePreview;
ImageView imageViewFace;
void showImage(Bitmap image)
{
imageViewFace.setImageBitmap(null);
FaceCropper mFaceCropper = new FaceCropper();
mFaceCropper.setMaxFaces(1);
mFaceCropper.setEyeDistanceFactorMargin(0);
image = mFaceCropper.getCroppedImage(image);
String faceFound;
if (mFaceCropper.faceDetected==true){
faceFound = "Face Detected!";
}else faceFound ="No face detected!";
/* Get the starting time */
long startTime = 0;
startTime = System.nanoTime();
/* Get the image statistics */
ImageStats imageStats = new ImageStats(image);
System.out.println("Execution time: " + (((double)(System.nanoTime() - startTime))/1000000000.0) + " seconds!");
/* Get the image statistics */
double[] stats = imageStats.getStats();
/* Decide whether or not the image is of good quality */
String results = imageStats.result;
/* Create the labels */
String[] labels = new String[]{"Standard Luminosity: ", "Contrast: ", "Face orientation: ", "Sharpness: "};
/* The string of statistics */
StringBuffer strStatsBuff = new StringBuffer();
/* Go through all the statistics */
for(int statIndex = 0; statIndex < stats.length; ++statIndex)
{
/* Add the statistics */
strStatsBuff.append(labels[statIndex]);
strStatsBuff.append(String.valueOf(stats[statIndex]));
strStatsBuff.append("\n");
}
/* Add the file name */
strStatsBuff.append(faceFound);
/* Set the label and show the cropped image */
label.setText(strStatsBuff.toString());
if (mFaceCropper.faceDetected == true)
{
imageViewFace.setImageBitmap(image);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// no need to cast to button view here since we can add a listener to any view, this
// is the single image selection
label = (TextView)findViewById(R.id.label);
findViewById(R.id.buttonGallery).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType(IMAGE_TYPE);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select image"), SELECT_SINGLE_PICTURE);
}
});
findViewById(R.id.buttonCamera).setOnClickListener(new View.OnClickListener(){
public void onClick(View arg0 ){
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
mImageCaptureUri1 = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri1);
cameraIntent.putExtra("return-data", true);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
selectedImagePreview = (ImageView)findViewById(R.id.imageView1);
imageViewFace = (ImageView)findViewById(R.id.imageViewFace);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_SINGLE_PICTURE) {
Uri selectedImageUri = data.getData();
try {
Bitmap bitmap;
selectedImagePreview.setImageBitmap(new UserPicture(selectedImageUri, getContentResolver()).getBitmap());
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImageUri));
selectedImagePreview.setImageBitmap(bitmap);
showImage(bitmap);
} catch (IOException e) {
Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
e.printStackTrace();
}
}
else if (requestCode==CAMERA_REQUEST){
try {
Bitmap bitmap;
selectedImagePreview.setImageBitmap(new UserPicture(mImageCaptureUri1, getContentResolver()).getBitmap());
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageCaptureUri1));
selectedImagePreview.setImageBitmap(bitmap);
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
showImage(bitmap);
} catch (IOException e) {
Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
e.printStackTrace();
}
}
}
else {
// report failure
Toast.makeText(getApplicationContext(),"failed to get intent data", Toast.LENGTH_LONG).show();
Log.d(MainActivity.class.getSimpleName(), "Failed to get intent data, result code is " + resultCode);
}
}
}
I'm trying to save the bitmap in sharedpreferences, But when I'm trying to load that bitmap I give a "java.lang.OutOfMemoryError".
I guess I'm saving the unscaled version.
This is my scaling code:
public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 2048;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bmp = BitmapFactory.decodeFile(filePath, o2);
}
and this is how I'm saving the bitmap:
decodeFile(filePath);
img_logo.setImageBitmap(bmp);
settings = getSharedPreferences("pref", 0);
SharedPreferences.Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", filePath);
prefsEditor.commit();
what is wrong?
Edit:
this is my whole onActivityResult code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICTURE) {
if (resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
decodeFile(filePath);
img_logo.setImageBitmap(bmp);
settings = getSharedPreferences("pref", 0);
SharedPreferences.Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", filePath);
prefsEditor.commit();
}
} else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
else if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(mCapturedImageURI2, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String capturedImageFilePath = cursor.getString(column_index_data);
Log.d("photos*******"," in camera take int "+capturedImageFilePath);
decodeFile(capturedImageFilePath);
if(data != null)
{
img_logo.setImageBitmap(bmp);
settings = getSharedPreferences("pref", 0);
SharedPreferences.Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", capturedImageFilePath);
prefsEditor.commit();
}
}
}
}
Edit2:
my whole activity code:
public class MainActivity extends Activity {
ImageView img_logo;
protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_PICTURE = 1;
Uri mCapturedImageURI2;
SharedPreferences settings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settings = getSharedPreferences("pref", 0);
img_logo = (ImageView) findViewById(R.id.imageView1);
Log.d("SHAREDimagezzzz", "**********SHAREDzzzzzzz suckes******");
img_logo.setImageURI(Uri.parse(settings.getString("photo1", "android.resource://com.tiktak.babyalbum/" + R.drawable.ic_launcher)));
Log.d("SHAREDimage", "**********SHARED suckes******");
img_logo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
startDialog();
}
});
}
protected void startDialog() {
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(this);
myAlertDialog.setTitle("Upload Pictures Option");
myAlertDialog.setMessage("How do you want to set your picture?");
myAlertDialog.setPositiveButton("Gallery",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT);
galleryintent.setType("image/*");
galleryintent.putExtra("return-data", true);
startActivityForResult(galleryintent, GALLERY_PICTURE);
}
});
myAlertDialog.setNegativeButton("Camera",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "fileName");
mCapturedImageURI2 = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI2);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
myAlertDialog.show();
}
Bitmap bmp;
public String decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 2048;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bmp = BitmapFactory.decodeFile(filePath, o2);
return filePath;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICTURE) {
if (resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
String bb = decodeFile(filePath);
img_logo.setImageBitmap(bmp);
Log.d("galleryimage", "**********gallery suckes******");
settings = getSharedPreferences("pref", 0);
SharedPreferences.Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", bb);
prefsEditor.commit();
}
} else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
else if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(mCapturedImageURI2, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String capturedImageFilePath = cursor.getString(column_index_data);
Log.d("photos*******"," in camera take int "+capturedImageFilePath);
String bbd = decodeFile(capturedImageFilePath);
if(data != null)
{
img_logo.setImageBitmap(bmp);
Log.d("cameraimage", "**********camera suckes******");
settings = getSharedPreferences("pref", 0);
SharedPreferences.Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", bbd);
prefsEditor.commit();
}
}
}
}
}
I think I didn't place the sharedPreferences and prefsEditor right.
I dont think shared preference is causing the problem. you are only storing path to the bitmap in the sharedPreference. Out of memory error is most probably caused by
img_logo.setImageBitmap(bmp);
use some good Image loading library e.g picasso or universal image loader.
Each Android application is limited with 16Mb of memory. Even if you want to scale a 20MB image to small dimensions - you gonna load it to memory and get OOM.
The best practice to save/load large images is to use options.inJustDecodeBounds = true; in BitmapFactory. This will not load your image to memory and will scale it just in file system.
That's how i do it in my app:
public static Bitmap getThumbnail(String path, int target_width, int target_height, int max_size) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
int scale = 1;
while ((options.outWidth * options.outHeight) * (1 / Math.pow(scale, 2)) >
max_size) {
scale++;
}
Log.d("boom", "scale = " + scale + ", orig-width: " + options.outWidth + ", orig-height: " + options.outHeight);
Bitmap pic = null;
if (scale > 1) {
scale--;
options = new BitmapFactory.Options();
options.inSampleSize = scale;
pic = BitmapFactory.decodeFile(path, options);
Log.d("boom", "1th scale operation dimenions - width: " + target_width + ", target_height: " + target_height);
double y = Math.sqrt(max_size
/ (((double) target_width) / target_height));
double x = (y / target_height) * target_width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(pic, (int) x, (int) y, true);
pic.recycle();
pic = scaledBitmap;
System.gc();
} else {
pic = BitmapFactory.decodeFile(path, options);
}
Log.d("boom", "bitmap size - width: " +pic.getWidth() + ", height: " + pic.getHeight());
return pic;
} catch (Exception e) {
Log.e("boom", e.getMessage(),e);
return null;
}
}
More info here
But seems you did it fine, but you save/load SharedPreferences wrong. You saving empty string and try to parse URI them.
String bb = decodeFile(filePath);
...
prefsEditor.putString("photo1", bb);
and on load you do:
img_logo.setImageURI(Uri.parse(settings.getString("photo1", "android.resource://com.tiktak.babyalbum/" + R.drawable.ic_launcher)));
will return empty string and will cause an error.
Don't save bitmaps in SharedPreference.
Its only for storing small key-value pairs.
It isn't good practice, and probably unusual to store Bitmaps in SharedPreference.
Instead, cache your image in a file and save its path.
Use Universal Image Downloader to cache images as it will make your task easier.
Try converting bitmap into String and save it, instead of saving the file path. This will help. On the other hand, it's better you use SQLite for these kind of operations instead of Sharedpreference..
I solved my problem somehow.
I know that this is not the best answer to my question but it's working and that's enough for me! :)
Just Should do the Scaling progress once again before loading sharedPrefrences:
public class MainActivity extends Activity {
ImageView img_logo;
protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_PICTURE = 1;
Uri mCapturedImageURI2;
SharedPreferences settings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settings = getSharedPreferences("pref", 0);
Button b1 = (Button) findViewById(R.id.button1);
Button b2 = (Button) findViewById(R.id.bto2);
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
startActivity(new Intent(MainActivity.this, A2.class));
}
});
img_logo = (ImageView) findViewById(R.id.imageView1);
Log.d("SHAREDimagezzzz", "**********SHAREDzzzzzzz suckes******");
BitmapFactory.Options o3 = new BitmapFactory.Options();
o3.inJustDecodeBounds = true;
BitmapFactory.decodeFile(settings.getString("photo1", "android.resource://com.tiktak.babyalbum/" + R.drawable.ic_launcher), o3);
final int REQUIRED_SIZE = 2048;
int width_tmp = o3.outWidth, height_tmp = o3.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o4 = new BitmapFactory.Options();
o4.inSampleSize = scale;
Bitmap bit1 = BitmapFactory.decodeFile(settings.getString("photo1", "android.resource://com.tiktak.babyalbum/" + R.drawable.ic_launcher), o4);
img_logo.setImageBitmap(bit1);
// img_logo.setImageURI(Uri.parse(settings.getString("photo1", "android.resource://com.tiktak.babyalbum/" + R.drawable.ic_launcher)));
Log.d("SHAREDimage", "**********SHARED suckes******");
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
startDialog();
}
});
}
protected void startDialog() {
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(this);
myAlertDialog.setTitle("Upload Pictures Option");
myAlertDialog.setMessage("How do you want to set your picture?");
myAlertDialog.setPositiveButton("Gallery",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT);
galleryintent.setType("image/*");
galleryintent.putExtra("return-data", true);
startActivityForResult(galleryintent, GALLERY_PICTURE);
}
});
myAlertDialog.setNegativeButton("Camera",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "fileName");
mCapturedImageURI2 = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI2);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
myAlertDialog.show();
}
Bitmap bmp;
public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 2048;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bmp = BitmapFactory.decodeFile(filePath, o2);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICTURE) {
if (resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
decodeFile(filePath);
img_logo.setImageBitmap(bmp);
Log.d("galleryimage", "**********gallery suckes******");
settings = getSharedPreferences("pref", 0);
Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", filePath);
prefsEditor.commit();
}
} else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
else if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(mCapturedImageURI2, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String capturedImageFilePath = cursor.getString(column_index_data);
Log.d("photos*******"," in camera take int "+capturedImageFilePath);
decodeFile(capturedImageFilePath);
if(data != null)
{
img_logo.setImageBitmap(bmp);
settings = getSharedPreferences("pref", 0);
Editor prefsEditor = settings.edit();
prefsEditor.putString("photo1", capturedImageFilePath);
prefsEditor.commit();
}
}
}
}
}