Xamarin android - take picture from camera then pass it to other activity - android

I am new to xamarin and I want to take a picture from the camera when I click on a button on my mainactivity and then, once the picture taken, display it in an imageView in an other activity.
Can you help me?
Here's what I have right now :
MainActivity :
costsButton.Click += delegate
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
};
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
var extra = data.GetByteArrayExtra("data");
Intent intent = new Intent(this, typeof(AddFrais));
intent.PutExtra("picture", extra);
StartActivity(intent);
}
AddFrais.cs :
namespace Projet_stage_2017
{
[Activity(Label = "AddFrais")]
public class AddFrais : Activity
{
ImageView picturefrais;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.AddFrais);
picturefrais = FindViewById<ImageView>(Resource.Id.ImageFrais);
var image = Intent.GetByteArrayExtra("picture") ?? null;
Bitmap bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length);
picturefrais.SetImageBitmap(bitmap);
}
}
}
I don't know what to put on the "PutExtra" in the mainActivity to be able to create a bitmap on AddFrais.cs...
Thanks for helping !

Try this:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
// It's a good idea that you check this before accessing the data
if (requestCode == 0 && resultCode == Result.Ok)
{
//get the image bitmap from the intent extras
var image = (Bitmap)data.Extras.Get("data");
// you might also like to check whether image is null or not
// if (image == null) do something
//convert bitmap into byte array
byte[] bitmapData;
using (var stream = new MemoryStream())
{
image.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
Intent intent = new Intent(this, typeof(AddFrais));
intent.PutExtra("picture", bitmapData);
StartActivity(intent);
}
// if you got here something bad happened...
}
Then in your second Activity:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.AddFrais);
picturefrais = FindViewById<ImageView>(Resource.Id.ImageFrais);
//Get image from intent as ByteArray
var image = Intent.GetByteArrayExtra("picture");
if (image != null)
{
//Convert byte array back into bitmap
Bitmap bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length);
picturefrais.SetImageBitmap(bitmap);
}
}
As you can see your second activity code is most likely the same, I just added a validation to prevent NullReferenceException if the image is not well extracted from the intent.
Hope this helps!

Related

How to set image view on the xamarin android

Does anybody know how to set the image from the temp storage to the ImageView? I need to get this done as soon as possible. Thank you. I tried many way of doing but it is not helping at all.
namespace SubUnit
{
[Activity(Label = "SubUnit", MainLauncher = true)]
public class MainActivity : Activity
{
Button mbtnCam;
const int REQUEST_TAKE_PHOTO = 0;
global::Android.Net.Uri uriPhotoTaken;
ImageView image1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
mbtnCam= FindViewById<Button>(Resource.Id.btnCamera);
mbtnCam.Click += MbtnCam_Click;
}
private void MbtnCam_Click(object sender, System.EventArgs e)
{
var intent = new Intent(MediaStore.ActionImageCapture);
if (intent.ResolveActivity(PackageManager) != null)
{
var storeImg= GetExternalFilesDir(global::Android.OS.Environment.DirectoryPictures);
var file = File.CreateTempFile("IMG_", ".bmp", storeImg);
uriPhotoTaken = global::Android.Net.Uri.FromFile(file);
intent.PutExtra(MediaStore.ExtraOutput, uriPhotoTaken);
StartActivityForResult(intent, REQUEST_TAKE_PHOTO);
}
}
}
}
It seems that you are trying to capture image from camera and display it in ImageView. You need to override OnActivityResult method to get the image data from camera intent, below code is to load a thumbnail image
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult (requestCode, resultCode, data);
if ((resultCode == Result.Ok) && (data != null)) {
Bundle extras = data.Extras;
Bitmap imageBitmap = (Bitmap) extras.Get("data");
image1.SetImageBitmap(imageBitmap);
}
}
And if you want save and load full size image then follow this tutorial

How can I handle camera and gallery output simultaneously, without using 2 times onActivityResult?

I have a dialogue, which asks you to choose if to take a picture or to upload one from gallery. The taken/chosen image I set as background on a Button. how can I handle both outputs, as I can't use 2 times onActivityResult?
Here is the method that invokes the camera:
private void invokeCamera() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
And the method that lets you choose from a gallery:
private void openGallery() {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
I handle the image received from the camera on the following way:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = (Bitmap) extras.get("data");
if (photo != null) {
findViewById(), and whose background you want to update
if (Build.VERSION.SDK_INT > 16) {
imageUploader5.setBackground(new BitmapDrawable(getResources(), photo));
}
} else {
imageUploader5.setBackgroundDrawable(new BitmapDrawable(getResources(), photo));
}
}
}
}
}
First, make a global variable
private final static int GET_PHOTO_BITMAP = 1234;
Then do the following
private void invokeCamera() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, GET_PHOTO_BITMAP);
}
private void openGallery() {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, GET_PHOTO_BITMAP);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GET_PHOTO_BITMAP && data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = (Bitmap) extras.get("data");
if (photo != null) {
findViewById(), and whose background you want to update
if (Build.VERSION.SDK_INT > 16) {
imageUploader5.setBackground(new BitmapDrawable(getResources(), photo));
}
} else {
imageUploader5.setBackgroundDrawable(new BitmapDrawable(getResources(), photo));
}
}
}
}
}
Here the key part is request code which is the second parameter of the startActivityForResult(Intent intent, int requestCode)
you can have different requestCodes for different operations and handle it this way in
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case code1:
//task1
break;
case code2:
//task2
break;
//and so on
}
}
but since your case both the callbakcs for startActivityForResult() are supposed to perform the same operation, you can pass same code for both the calls as I have done in the above solution. But make sure that you pass same code when the operations done in the callback are similar.

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

How to preview image in image view after picture taken from camera

http://www.c-sharpcorner.com/UploadFile/9e8439/how-to-make-a-custom-camera-ion-android/I have made a custom camera app and after click a picture i want to preview it in an image view but when i am previewing it in image view,image is being scaled from actual size of picture.
his 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);
}
Hope it helps!
This link completely described what you want. Here is the summary:
1- Add this to the Manifest:
< uses-feature android:name="android.hardware.camera" android:required="true" />
2- Add this line to your class:
static final int REQUEST_IMAGE_CAPTURE = 1;
3- call this method where you want to open camera:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
4- Override onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ImageView ivImage = (ImageView) findViewById(R.id.ivImage);
ivImage.setImageBitmap(imageBitmap);
}
}
I hope it help you.

android finish sometimes restarting app

I'm working on an app which allows user to choose a picture from gallery and then I start a activity to crop it.
I want to send the cropped image back to calling activity.
Both activities extend AppCompatActivity.
Calling activity:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
// start image crop activity
String dataString = data.getDataString();
Intent intent=new Intent(this, CropPhotoActivity.class);
intent.putExtra("SELECTED_PICTURE_FOR_CROP", dataString);
startActivityForResult(intent, CROP_PICTURE);
}
else if(requestCode == CROP_PICTURE) {
// get cropped bitmap
Bitmap bitmap = (Bitmap) data.getParcelableExtra("CROPPED_IMAGE");
profilePhoto.setImageBitmap(bitmap);
}
}
}
In the crop image activity, I have a button, which on click should return back to calling activity:
Button okButton = (Button)findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent returnIntent = new Intent();
returnIntent.putExtra("CROPPED_IMAGE", cropped_bitmap);
setResult(RESULT_OK, returnIntent);
finish(); // sometimes restarts app
}
});
Sometimes the bitmap gets returned correctly whereas sometimes it does not and the app gets restarted without error. Why is this happening? Does putExtra have anything to do with bitmap size or anything else?
You could try substituting
AppcompatActivity.this.finish()
(where AppcompatActivity is your class name)
for:
finish(); // sometimes restarts app
Or, create a method in the calling Activity:
public static void cropComplete(Activity activity)
{
activity.startActivity(activity, AnotherActivity.class);
activity.finish();
}
Theres's a limit for data length passed as extra in a intent. Try not passing the dataString value; instead you should save the image as a temporary file, pass the path in the intent and then load the image from your calling activity (or you can just save the dataString in a static helper class).
In the crop activity (saving bitmap code from Save bitmap to location):
// Save bitmap
String filename = "tempImage.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
FileOutputStream out = null;
try {
out = new FileOutputStream(dest);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null)out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Get image file path
String path = dest.getAbsolutePath();
// Set result with image path
Intent returnIntent = new Intent();
returnIntent.putExtra("CROPPED_IMAGE_PATH", path);
setResult(RESULT_OK, returnIntent);
finish();
In the caller activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == CROP_PICTURE) {
// Get image file path
String imagePath = data.getStringExtra("CROPPED_IMAGE_PATH");
// Load image
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
}
}

Categories

Resources