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
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.
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.
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);
}
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;
}
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);