Android application: how to use the camera and grab the image bytes? - java

I'm trying to create a small app for Android that takes a picture using the device's camera and put's a PNG frame on top of it. This way the final saved picture will have a beach on top of it, or hats, or anything. Does anyone have any sample programs with this behavior?

Have a look at the SDK documentation on using the image capture intent here.
I start my image capture intent like this:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is a private member in my activity:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
Then get the byte array back from the camera by using the following onActivityResult handler:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
AddImage(byteArray);
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
After that you can do all the processing you want on the image.

Related

Show an image in opengl is working with pictures from gallery but from camera doesn't

I have some troubles to display images in OpenGL.
Actually I'm able to display images from gallery in opengl. The problem occurs when I try to show one from the camera.
For me, OpenGL have to display the image from the camera as it does with the gallery ones. Obviously I'm making something wrong.
Any help will be appreciated.
Intent from gallery:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent, 2);
Intent from camera:
Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePic.resolveActivity(getPackageManager()) != null) {
File imagen = controler.createPhotoFile(getExternalFilesDir(Environment.DIRECTORY_PICTURES));
if (imagen != null) {
photoUri = FileProvider.getUriForFile(this, "my.fileprovider", imagen);
takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePic, 1);
}
}
This is my onActivityResult where I send the URI to a method which convert it to a bitmap and send it.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 1:
sendImagenPanel(photoUri);
break;
case 2:
sendImagenPanel(data.getData());
break;
}
}
}
private void sendImagenPanel(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap imagen = controler.getCroppedBitmap(controler.scaledBitmap(bitmap, 256));
final CasillaOG casilla = ((GLSurfacePanel) gLViewPanel).getRendererPanel().getCuboSelected();
gLViewPanel.queueEvent(new Runnable() {
#Override
public void run() {
casilla.loadNewTexture(imagen);
casilla.setImagen(imagen);
}
});
gLViewPanel.requestRender();
}
In case someone is interested. I realize that the problem is not on the method that calls OpenGL. If I run the same code on the onActivityResult works from the gallery requestCode but not on the camera one, in my Samsung Galaxy Tab A. Why I mention my device? because if I run the app on a Huawei P9 lite, the gallery images are not display either. In both cases appears the next problem on the console:
call to opengl es api with no current context (logged once per thread)
After search that problem, I suppose that the intents of the camera and gallery use OpenGL and its originate a conflict with my own OpenGL environment.
Finally, I opted to set a bitmap field and add the texture in on the onDrawFrame. Obviously, with a boolean to make it one time.

Image and file operations on Android

I get pictures url from gallery or camera on android but I can't convert them to file. When i developing an app with Java in android, sometimes I need to get pictures from gallery and camera to my application. But when i try to do this I'm getting errors.
Isn't there a standard here? The code works at one api level and does not works another one. Or when I take the URI of some images and convert it to file, I get an error regardless of the api level. I wonder if there is a fundamental solution to this problem?
I am starting intent with this
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,IMAGE_RESULT);
And then I'm catching data with this code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == IMAGE_RESULT) {
String filePath = ImageFilePath.getPath(OwnProfileActivity.this, data.getData());
selectedFile = new File(filePath);
showProgressDialog();
Handler handler = new Handler();
handler.postDelayed(this::chaneProfileImage, 1000);
}
}
}
May I suggest something like this, but of course this is if you have a bitmap:
private fun getImageUriFromBitmap(image: Bitmap): Uri? {
val bytes = ByteArrayOutputStream()
image.compress(Bitmap.CompressFormat.PNG, 100, bytes)
val relativeLocation = Environment.DIRECTORY_PICTURES + File.pathSeparator + "NotifyMe"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "notifyMe_${System.currentTimeMillis()}")
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
}
return context?.contentResolver?.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
}
Then you can create the file with the uri
val file = File(uri.path)
source: https://gist.github.com/franciscobarrios/9f6634c87ca6e56ed70cd96807dd1dcb

Android get URI of cropped image from Intent

I'm trying to capture an image from the Android Camera/ Pick an image from the gallery and then crop it before performing other operations on it. I'm having trouble with getting back the URI of the cropped image. Any help on how to get back the URI of the image once it has been cropped would be much appreciated!
The code below pertains to my onActivityResult and my function performing the crop
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE || requestCode == REQUEST_IMAGE_CAPTURE) {
if(!IS_CAMERA_USED) {
selectedImageUri = data.getData();
}
performCrop();
}
else if(requestCode == CROP_IMAGE){
selectedImageUri = data.getData();
onSelectedImageResult();
}
}
}
public void performCrop() {
// take care of exceptions
Display display = getWindowManager().getDefaultDisplay();
try {
// call the standard crop action intent (the user device may not
// support it)
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(selectedImageUri, "image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectY", 1);
if(IS_PROFILE_PICTURE) {
cropIntent.putExtra("aspectX", 1);
}
else {
cropIntent.putExtra("aspectX", 2);
}
// indicate output X and Y
cropIntent.putExtra("outputX", display.getWidth());
cropIntent.putExtra("outputY", display.getHeight());
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}
}
The problem is in the line selectedImageUri = data.getData(), where data.getData() returns null after having done the crop. How do I get back the URI of the cropped image? I don't want to get data.getExtras.getParcelable("data") as that returns the thumbnail and ruins the image resolution.
Thanks in advance!
You can get the image bitmap with this code:
if (requestCode == CROP_IMAGE) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap selectedBitmap = extras.getParcelable("data");
//imgView.setImageBitmap(selectedBitmap);
}
}
}
URI is not possible I think, because the cropped image is not saved on the storage.
Thanks for all your answers, but I found something way simpler to incorporate and use that avoids all hassles due to the `com.android.camera.action.CROP' class, and it can be found here
I think that you should save the cropped Bitmap to your storage, and then use the URI of the cropped Bitmap to performe something over it!
I know it's not a professional work but at least it should do it

onActivityResult byte[] data returning null no matter how large the image

I am trying to pass a byte array between activities using startActivity and onActivityResult. The byte array is null when returning to onActivityResult and I cannot figure out why. This happens no matter how large the byte array is so I don't think it has to do with size. Also, I am passing a byte array of approximately the same size using intents successfully in another area. The code:
In post activity:
public void callCropperIntent() {
/* call the cropper to crop a photo from the gallery */
intent = new Intent(getApplicationContext(), Cropper.class);
startActivityForResult(intent, CROP_GALLERY_PICTURE);
}
In cropper activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
File croppedImageFile = new File(getFilesDir(), "test.jpg");
try {
if ((requestCode == REQUEST_PICTURE) && (resultCode == RESULT_OK)) {
/** When the user is done picking a picture, we'll start the CropImage Activity,
* setting the output image file and size to 640 X 640 pixels square.
*/
Uri croppedImage = Uri.fromFile(croppedImageFile);
CropImageIntentBuilder cropImage = new CropImageIntentBuilder(640, 640, croppedImage);
cropImage.setSourceImage(data.getData());
cropImage.setOutputQuality(100);
startActivityForResult(cropImage.getIntent(this), REQUEST_CROP_PICTURE);
}
else if ((requestCode == REQUEST_CROP_PICTURE) && (resultCode == RESULT_OK)) {
/* when we are done cropping, send it back to PostActivity */
//imageView.setImageBitmap(BitmapFactory.decodeFile(croppedImageFile.getAbsolutePath()));
Bitmap bmp = BitmapFactory.decodeFile(croppedImageFile.getAbsolutePath());
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
//this set bitmap works so I know the bitmap is valid
//test
//imageView.setImageBitmap(bmp);
byte[] imageData = stream.toByteArray();
//bmp.recycle();
Intent intent = getIntent();
intent.putExtra("image", imageData);
setResult(RESULT_OK, intent);
finish();
}
}
Back in post activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
byte[] croppedData;
/* check the request code */
if (requestCode == CROP_GALLERY_PICTURE) {
/* ensure the request was successful */
if (resultCode == RESULT_OK) {
/* The user picked and cropped a photo */
/* retrieve photo from cropping activity */
Intent intent = getIntent();
croppedData = data.getByteArrayExtra("image");
/* bytes ready to be sent to pg. 2 of posting process */
callPostActivityPg2Intent(croppedData);
}
}
}
I think in the cropper class,before finish() you should create a new instance of Intent class instead of obtaining one by calling getintent().
Ex: Intent intent = new Intent();
intent.putExtra ()....

Returning Image Resource ID

I'm trying to get a program to let the user to import a custom background.
Here's where I'm at:
I have the getDrawable function taking another function as an argument:
mDrawableBg = getResources().getDrawable(getImage());
getImage() is suppose to return a integer referencing the selected image, here is the code (so far) for that function:
public int getImage(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This is suppose to open the gallery and let the user select an image. I would then use mDrawableBg to set the background. I'm not sure how to return a reference ID to that selected image though. Any suggestions?
Try this:
String pathName = "selected Image path";
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
BitmapDrawable bd = new BitmapDrawable(res, bitmap);
View view = findViewById(R.id.container);
view.setBackgroundDrawable(bd);
The way you're attempting to do it is not possible, I'm afraid. One of the things you'll want to learn as a new Android developer is how the cycle between activities works. In your case, you're running an Activity that calls upon an Intent to get data from it. However, in the Android API, an Intent can only be referenced on its own time. This means you can't use your getImage() method the way you had tried.
There is hope, though!
What you first need to do is call the Intent. You will do this through the code you have now in getImage():
public void getImage() { // This has to be a void!
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This method will now start the Image Picker that you want users to select from. Next, you have to catch what is returned. This cannot be returned from your getImage() method, but instead must be collected from elsewhere.
You must implement the below method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
final int SELECT_PICTURE = 1; // Hardcoded from API
if (requestCode == SELECT_PICTURE) {
String pathToImage = data.getData().getPath(); // Get path to image, returned by the image picker Intent
mDrawableBg = Drawable.createFromPath(pathToImage); // Get a Drawable from the path
}
}
}
Lastly, instead of calling mDrawableBg = getResources().getDrawable(getImage());, just call getImage();. This will initialize the Image Picker.
Some reading:
Android Activity (notably stuff about Intents and getting a result back)
Android Drawable
Getting a Drawable from a path
More on the Image Picker Intent
Good luck!
I'm not sure, but if you mean you don't know how to receive results from that intent, you can use :
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
{
if (requestCode == 10)
{
// DoSomething
}
}
}

Categories