ImageView - image lost on change in orientation - android

I have an application where I take a picture and set it as the image on image button. On change in orientation, the image vanishes. Please help.
I click a picture and set it as the image on the ImageItem
public void onImageButtonClicked(View view)
{
Intent camIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camIntent, TAKE_PHOTO);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PHOTO && resultCode == Activity.RESULT_OK)
try {
InputStream stream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(stream);
stream.close();
ImageButton imageButton = (ImageButton) findViewById(R.id.itemImage);
int mDstWidth = getResources().getDimensionPixelSize(R.dimen.destination_width);
int mDstHeight = getResources().getDimensionPixelSize(R.dimen.destination_height);
scaledBmp = Bitmap.createScaledBitmap(bitmap, mDstWidth, mDstHeight, true);
imageButton.setImageBitmap(scaledBmp);
} catch (Exception e) {
e.printStackTrace();
}
super.onActivityResult(requestCode, resultCode, data);
}
When the orientation is changed, image disappears.
I saved the image in
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
if (scaledBmp != null) {
savedInstanceState.putByteArray("image", getBitmapAsByteArray(scaledBmp));
}
}
and retrieved in
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
byte[] savedImage;
savedImage = savedInstanceState.getByteArray("image");
if (savedImage != null) {
scaledBmp = BitmapFactory.decodeByteArray(savedImage, 0, savedImage.length -1);
}
}
Should I set the image on the button manually now? Is there something I am missing?

I was missing onResume()
protected void onResume()
{
super.onResume();
if (scaledBmp != null)
{
ImageButton ib = (ImageButton) findViewById(R.id.itemImage);
if (ib != null)
ib.setImageBitmap(scaledBmp);
}
}
With this change, things started working. I am getting the image in landscape as well as portrait mode.
Asthme's comment helped me, thanks.

Related

An error occurs during the operation to place Uri as bitmap in imageView

public class addBoard extends AppCompatActivity {
private final int GET_GALLERY_IMAGE = 200;
Uri image;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addboard);
final EditText EDTITLE = findViewById(R.id.editTitle);
final EditText EDTEXT = findViewById(R.id.editText);
ImageView imgView = (ImageView)findViewById(R.id.imageView);
Button addPhoto = findViewById(R.id.photo);
addPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, GET_GALLERY_IMAGE);
}
});
try {
Bitmap bm = MediaStore.Images.Media.getBitmap(getContentResolver(), image);
imgView.setImageBitmap(bm);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Button backButton = findViewById(R.id.backButton);
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("Input_Title", EDTITLE.getText().toString());
intent.putExtra("Input_Text", EDTEXT.getText().toString());
intent.putExtra("Input_Image", image);
setResult(RESULT_OK, intent);
finish();
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GET_GALLERY_IMAGE && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri selectImage = data.getData();
image = selectImage;
}
}
}
If you run this code in another project, there is no error, but if you use it in this project, you will get an error. Why is that?
Error :Caused by: java.lang.NullPointerException: uri
at com.example.toolbar.addBoard.onCreate**(addBoard.java:45)** // blue line
An error occurs during the operation to place Uri as bitmap in imageView.

Save/Read Bitmap in internal storage doesn't work

I tried to code a simple functionallity that would crop an image (stored in the drawable folder) after pressing a button, and return the cropped image in the first Activity in an imageView.
Aftrer trying to pass the bitmap in a arraybyte through an intent that didn't work, I am now trying to save the cropped image into the internal storage and read it in the OnActivityResult function, however when I am done cropping I get nothing in my ImageView.
For the cropping I used the following library : https://github.com/ArthurHub/Android-Image-Cropper/wiki
Here is the code:
public class MainActivity extends AppCompatActivity {
Button b;
ImageView preview;
final int REQUEST_CODE_TEST = 63;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button) findViewById(R.id.chooser);
preview = (ImageView) findViewById(R.id.preview);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), Cropper.class);
startActivityForResult(intent, REQUEST_CODE_TEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_TEST && resultCode == RESULT_OK) {
try {
String path=data.getData().toString();
File f=new File(path,"profile.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(f));
preview.setImageBitmap(bitmap);
}catch (Exception e){
e.printStackTrace();
}
}
}
The crop actvity :
public class Cropper extends Activity {
CropImageView cropImageView;
Bitmap bitmap;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cropper);
bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.ic_bonnasse);
cropImageView=(CropImageView)findViewById(R.id.cropImageView);
cropImageView.setCropShape(CropImageView.CropShape.RECTANGLE);
cropImageView.setImageBitmap(bitmap);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
public void finish() {
super.finish();
Intent retour=new Intent();
Bitmap crop=cropImageView.getCroppedImage();
Bitmap out=Bitmap.createScaledBitmap(crop, 200, 200, true);
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir("Profile_pic", Context.MODE_PRIVATE);
File mypath=new File(directory,"profile.jpg");
FileOutputStream outputStream=null;
try{
outputStream=new FileOutputStream(mypath);
out.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
}catch (Exception e){
e.printStackTrace();
}
retour.putExtra("directory",directory.getAbsolutePath());
}
Thanks for your help.
when you are finishing your crop activity , you are suppose to set your result status for your parent activity , otherwise the parent activity can not detect the result code .
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_TEST && resultCode == RESULT_OK) {
Bitmap bitmap = (Bitmap) data.getParcelableExtra("bitmap");
preview.setImageBitmap(bitmap);
}
In this figure the result code is always RESULT_CANCEL , therefore your If block does not run.
Solution :
Do not override finish() method , just use it and change your listener with this in crop activity .
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent retour=new Intent();
Bitmap crop = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
Bitmap out=Bitmap.createScaledBitmap(crop, 200, 200, true);
retour.putExtra("bitmap", out);
setResult(RESULT_OK, retour);
finish();
}
});
In this case I just passed the bitmap into main activity , but if you are willing to save the bitmap then send it to main activity , you are suppose to save it and put it into retour.putExtra("directory",directory.getAbsolutePath());
in your crop activity , then get it by String directory = data.getStringExtra("directory"); in onActivityResult .
Although in my view the first way is better , you have a second one.

bitmap bad quality after set to imageview

I am creating a app that opens camera for user and after image captured it will be shows on ImageView! But the image in ImageView has very bad quality
here is the code:
public class Camera extends AppCompatActivity implements View.OnClickListener {
ImageView imgView;
Button camera, setBackground;
Intent i;
int cameraData = 0;
Bitmap bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
initialize();
}
private void initialize() {
imgView = (ImageView) findViewById(R.id.bPicture);
camera = (Button) findViewById(R.id.bOpenCamera);
setBackground = (Button) findViewById(R.id.bSetBackground);
camera.setOnClickListener(this);
setBackground.setOnClickListener(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
Bundle extras = data.getExtras();
bitmap = (Bitmap) extras.get("data");
Bitmap resizedBmp = Bitmap.createScaledBitmap(bitmap, imgView.getWidth(),imgView.getHeight(), false);
imgView.setImageBitmap(resizedBmp);
}
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.bOpenCamera:
i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
break;
case R.id.bSetBackground:
try {
WallpaperManager wallmngr = WallpaperManager.getInstance(this);
wallmngr.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
what should I do to increase image quality?
Use something other than the thumbnail. Quoting the documentation for ACTION_IMAGE_CAPTURE, with emphasis added:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.
So, specify a Uri in EXTRA_OUTPUT where a full camera image should be written to. Then, use an image-loading library, like Picasso, to load the photo into your ImageView.
Here is a sample app that demonstrates using EXTRA_OUTPUT.
This is how I made it work for me! Assuming you are capturing an image, and would like to show the captured image in a new Activity, you can follow this way:
First on the click of button you can:
public void cameraFuture(View view) // <-- onClick() method of Camera Button
{
Intent intent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(),
"MyPhoto.jpg");
outPutfileUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutfileUri);
startActivityForResult(intent, TAKE_PIC);
}
Then on the onActivityResult() method, you can do this way:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PIC && resultCode==RESULT_OK){
Toast.makeText(this, outPutfileUri.toString(),Toast.LENGTH_LONG).show();
Intent bitIntent = new Intent(this, CameraTake.class);
bitIntent.putExtra("imageUri", outPutfileUri);
startActivity(bitIntent);
finish();
}
}
And in the next Activity, you can receive the file this way:
Intent receiveIntent = getIntent();
uri = receiveIntent.getParcelableExtra("imageUri");
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
receiveImg= null;
} else {
receiveImg= extras.getString("PASSER");
}
} else {
receiveImg= (String) savedInstanceState.getSerializable("PASSER");
}
File imgFile = new File(Environment.getExternalStorageDirectory(),"MyPhoto.jpg");
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.camOut);
myImage.setImageBitmap(myBitmap);
}

Load Bitmap picture after savedInstanceState Error

Threr is what i have done. On my activity. I take 2 picture correctly but if i change the orientation of the phone app crash
public class MyactivityTakePicture extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//initialisation
setContentView(R.layout.picture_main_layout);
img1 = (ImageView)findViewById(R.id.photo1);
img2 = (ImageView)findViewById(R.id.photo2);
//creation des dossiers
dir1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/g0/";
newdir1 = new File(dir1);
newdir1.mkdirs();
dir2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/g1/";
newdir2 = new File(dir2);
newdir2.mkdirs();
capture1 = (Button) findViewById(R.id.btnCapture1);
capture1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
takepicture1();
}
});
capture2 = (Button) findViewById(R.id.btnCapture2);
capture2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
takepicture2();
}
});
if(savedInstanceState != null){
filePath1 = savedInstanceState.getString("chemin1");
filePath2 = savedInstanceState.getString("chemin2");
bitmap1 = BitmapFactory.decodeFile(filePath1);
img1.setImageBitmap(bitmap1);
//filePath2 = savedInstanceState.getString("chemin1");
Log.w("A", ""+filePath1);
Log.i("F", ""+filePath2);
bitmap2 = BitmapFactory.decodeFile(filePath2);
img2.setImageBitmap(bitmap2);
}
}
//prise de photo N°1
..................
//prise de photo N°2
protected void takepicture2(){
//nom des photos photo1.jpg, photo2.jpg ...
count++;
file2 = dir2+"photo.jpg";
File newfile2 = new File(file2);
filePath2 = dir2+"photo.jpg";
try {
newfile2.createNewFile();
} catch (IOException e) {
Log.e("Error", e.toString());
}
Uri outputFileUri2 = Uri.fromFile(newfile2);
Intent cameraIntent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent2.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri2);
startActivityForResult(cameraIntent2, TAKE_PHOTO_CODE2);
}
//Enregistrement OK
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE1 && resultCode == RESULT_OK) {
Log.d("CameraDemo1", "Pic saved");
bitmap1 = BitmapFactory.decodeFile(filePath1);
img1.setImageBitmap(bitmap1);
}
if (requestCode == TAKE_PHOTO_CODE2 && resultCode == RESULT_OK){
Log.d("CameraDemo2", "Pic saved");
bitmap2 = BitmapFactory.decodeFile(filePath2);
img2.setImageBitmap(bitmap2);
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(newdir1==null){
newdir1 = new File(file1);
}// if
if(newdir2==null){
newdir2 = new File(file2);
}
outState.putString("chemin1", filePath1);
outState.putString("chemin2", filePath2);
}
}
First, Activity lauch correctely, take the two picture.
If i try to change orientation of my phone. She crash.
Please you see?
The problem is that your images aren't getting deallocated from memory.
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
read this articles, would be helpful for you
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
http://mobi-solutions.blogspot.mx/2010/08/how-to-if-you-want-to-create-and.html
UPDATE:
I have seen your code and i suggest the use of the method onDestroy() to set the bitmap instances to null:
#Override
protected void onDestroy(){
super.onDestroy();
bitmap1 = null;
bitmap2 = null;
}

Is there anything wrong with the code of saving camera image to file?

I thought it was simple to capture camera image to a file, since there are many examples. But after tying a lot of them, I still not get it work.
My code is:
public class MyActivity extends Activity {
private Button btn;
private ImageView imageView;
private static final File photoPath = new File(Environment.getExternalStorageState(), "camera.jpg");
private static final int CAMERA = 1;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
setListeners();
}
private void setListeners() {
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoPath));
startActivityForResult(intent, CAMERA);
}
});
}
private void findViews() {
btn = (Button) findViewById(R.id.btn);
imageView = (ImageView) findViewById(R.id.imageView);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA) {
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = getCameraBitmap(data);
if (bitmap == null) {
Toast.makeText(MyActivity.this, "Can't get bitmap from camera", Toast.LENGTH_LONG).show();
} else {
imageView.setImageBitmap(bitmap);
}
} catch (IOException e) {
Toast.makeText(MyActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
public Bitmap getCameraBitmap(Intent data) throws IOException {
if (data == null) {
// try solution 1
try {
return MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(photoPath));
} catch (FileNotFoundException e) {
return BitmapFactory.decodeFile(photoPath.getAbsolutePath());
}
} else {
Uri image = data.getData();
if (image != null) {
// try solution 3
InputStream inputStream = getContentResolver().openInputStream(image);
return BitmapFactory.decodeStream(inputStream);
} else {
// try solution 4
return (Bitmap) data.getExtras().get("data");
}
}
}
}
But it still get "Can't get bitmap from camera" shown. I don't known where is wrong.
I also created a working demo: https://github.com/freewind/AndroidCameraTest, you can see the full code there, and you may clone it and have a try on your own android device :)
Update
This code is working fine on android emulators, but not on my android pad.
I have seen this problem too; I removed intent.putExtra(MediaStore.EXTRA_OUTPUT,...), and it worked using the method:
stream = getContentResolver().openInputStream(data.getData());
image = BitmapFactory.decodeStream(stream);

Categories

Resources