I'm creating an image filter app in Android studio. first, the user selects an image from gallery and it will be displayed in imageview. Then the user clicks edit button and that image is displayed in imageview of next activity where we can add filters... It works fine with low resolution images but when I select any high resolution image it is shown in first imageview but when I click edit button either the app crashes or the last image I had selected is displayed.I searched for the solution but couldn't find it. If anyone knows how to solve this problem please help me
There is a limit to the size of data that can be passed through an intent. The limit is roughly 500Kb - your high resolution photographs will be larger than this.
Consider saving your image to a file location on the device, passing the URI to the receiving activity and loading it within there.
first paste crash logs.
then instead of passing image itself just pass image path.
or simply add the edit tools and mainView in one activity and make edit tools invisible! however you can use fragment too.
use with putExtra to send the Uri Path:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent .setClass(ThisActivity.this, NewActivity.class);
intent .putExtra("KEY", Uri);
startActivity(intent );
You just need to add path of image.
It's better to save the image in storage and pass the Uri of location instead of passing the image.
Save image in storage:-
public static Uri saveImageOnExternalStorage(Bitmap capturedBitmap, String imageId) {
if (null != capturedBitmap ) {
OutputStream fOutputStream;
String path = Environment.getExternalStorageDirectory().toString();
File file = new File(path + "temp", mediaId + ".png");
file.delete();
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try {
if (file.createNewFile()) {
fOutputStream = new FileOutputStream(file);
capturedBitmap.compress(COMPRESS_FORMAT, 100, fOutputStream);
fOutputStream.flush();
fOutputStream.close();
return Uri.fromFile(file); // return saved image path on external storage
}
} catch (FileNotFoundException e) {
Log.e(TAG,e.getMessage());
return null;
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG,e.getMessage());
}
}
return null;
}
Now the same Uri you can pass in the intent of next activity:-
Intent intent = new Intent(CurrentActivity.this, LaunchActivity.class);
intent .putExtra("image_key", Uri);
startActivity(intent );
Related
Activity 1:I have an imageview in which the images taken from camera and gallery are set and it works fine. In this Activity there is a right click button which will redirect you to second activity.
Activity 2: In this Activity I have four options
Save
Share
Share Via Instagram
Share Via Facebook
Activity 3: From the above four options the third activity works accordingly.
Now I don't know how to pass the image taken in first activity to the third activity.
My Effort: In first Activity image taken from camera:
Intent i=new Intent(Camera.this,SaveVia.class);
i.putExtra("image", thumbnail );
startActivity(i);
In Second Activity SaveVia:
Intent intent2 = new Intent(SaveVia.this, Save.class);
Bitmap receiptimage = (Bitmap)getIntent().getExtras().getParcelable("image")
startActivity(intent2);
In third Activity called Save:
Bitmap receiptimage = (Bitmap) getIntent().getExtras().getParcelable("imagepass");
// receipt.setImageBitmap(receiptimage);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
receiptimage.compress(Bitmap.CompressFormat.PNG, 90, bytes);
File storagePath = new File(Environment.getExternalStorageDirectory() + "/PhotoAR/");
storagePath.mkdirs();
File destination = new File(storagePath, Long.toString(System.currentTimeMillis()) + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
Toast.makeText(Save.this,"No Error",Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(Save.this,"Error Arrived",Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(Save.this,"Error Arrived again",Toast.LENGTH_LONG).show();
#AND
You don't need to pass bitmap as Parcelable from one activity.Pass file path in intent from one activity to another.
When you capture image get path in onActivityresult and save that path.
And redirect that two second activity.And from that path show your bitmap.Just Share Uri from path in share on facebook and Instagram.
I recommend using File I/O to save the bitmap to disk. Put the path of the file into your intent bundle using putExtra and recreate the bitmap in your other screens. Putting large bitmaps into a bundle with an intent can cause TransactionTooLarge exceptions.
Take a look at Getting path of captured image in android using camera intent
I am saving image bytes through my application using this simple method:
public static boolean StoreBytesToFile(byte[] messagebytes, String FilePathName)
{
try
{
FileOutputStream fos = new FileOutputStream(FilePathName);
fos.write(messagebytes);
fos.flush();
fos.close();
}
catch(java.io.FileNotFoundException fnfe)
{
return false;
}
catch(java.io.IOException ioe)
{
return false;
}
return true;
}
And then when user wants to see the stored image, I open it using gallery intent:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file://" + m_ImageFilename);
intent.setDataAndType(uri, "image/*");
startActivity(intent);
However, gallery shows only the single image file pointed by m_ImageFilename despite there are other images stored in the same folder.
Thus actual behaviour of gallery intent is this:
While expected behaviour is this:
As an important note, I must mention that after restarting phone, gallery intent shows all images in folder as expected. Also, the behaviour is same on all versions from Jelly Bean to Marshmallow.
So each time after saving image, user has to restart phone in order to see all images in folder through gallery intent.
Please can someone tell what am I missing here and how can this be fixed?
You need to add saved image to gallery ... This will help you.
I'm currently trying to save images taken from a phone to its gallery, but the code below only works if I choose the stock camera app when the chooser dialog pops up. Whenever I choose another camera app(e.g., the Google camera), the taken picture doesn't get saved any where.
To make things even stranger, sometimes the picture does show up in its designated directory in the gallery, but after 15 mins or so, the same goes for when I use the stock camera app: the picture will get saved in the default camera shots directory, but takes quite a bit to show up in its designated directory, if it shows up there at all.
// Capturing Camera Image will launch camera app request image capture
void captureImage() {
//file uri to store image.
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// Request camera app to capture image
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
getActivity().startActivityForResult(captureIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
well ,
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
does not work anymore .
you should do something like this :
call Camera Activity :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
and onActivityResult :
if (data.getData() == null) {
Bitmap bm = (Bitmap)
data.getExtras().get("data");
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss").format(new Date());
File pictureFile = new File(Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
.getAbsolutePath()
+ File.separator + "IMG_" + timeStamp);
try {
FileOutputStream fos = new FileOutputStream(
pictureFile);
bm.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
String filePath = pictureFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } else {
Uri imgUri =data.getData());
}
It turns out my code was working after all. The pictures were being saved in the new directory, but the problem was that the gallery wasn't being updated, which explains why the photos would randomly appear in the directory later on. Being new to this, it never occurred to me that I would have to update the gallery. I only came to this realization after using ES File Explorer to look through my files. To fix my problem, I just made a new method in my CameraFragment that would call on the media scanner. I called this method from onActivityResult().
Here's the new method, though there's nothing really "new" about it since I ran into the same code on other SO questions:
protected void mediaScan() {
getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse(fileUri.toString())));
}
I also don't need to call the package manager and iterate through the apps that could handle the camera intent if I'm not giving the option to use choose a picture from a gallery, so I'm going to remove all that from my question.
I am trying to invoke the default device camera from my application to take picture using intent android.provider.MediaStore.ACTION_IMAGE_CAPTURE. Everything seems to be working fine except for when i click and save a particular image it gets stored at two location
1. At the default camera location.
2. At the location which i am passing with intent.
I just want the 2nd option to happen and not the 1st one. I thought creating a .nomedia file in used defined location would make sure that the picture would not be listed as part of gallery but later i found that the pic is getting stored at both the location.
My relevant portion of code is:
In the Activity:
Intent intentCamera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try {
tempDir = Environment.getExternalStorageDirectory();
// place where to store camera taken picture
photo = createTemporaryFile("picture", ".jpg", tempDir);
photo.delete();
} catch (Exception e) {
Toast.makeText(this, "Please check SD card! Error in fetching image",
Toast.LENGTH_SHORT).show();
}
if (photo != null) {
Uri mImageUri = Uri.fromFile(photo);
Log.i(TAG, "" + mImageUri.toString());
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
}
startActivityForResult(intentCamera, CAMERA_PIC_REQUEST);
The corresponding method.
public File createTemporaryFile(String part, String ext,File tempDir) throws Exception {
tempDir = new File(tempDir.getAbsolutePath() +"/temp/");
if (!tempDir.exists()) {
tempDir.mkdir();
}
createNoMediaFile(tempDir.getAbsolutePath());
return File.createTempFile(part, ext, tempDir);
}
Is there a way i can avoid 1 i.e. saving the image to the default gallery location. Thanks.
onActivityResult returns you the Uri of Image you can retrieve the path of Image copy the image from that location and save at your desired location and after that delete that from Gallery.
What I am trying to do is to download image from web (its in GIF format, if that changes anything) and show it on screen with zoom/pan capability. I've successfully downloaded image into Bitmap instance myBitmap, but ImageView doesnt have zooming feature. So instead I'm willing to present it with default viewer which has zoom/pan features. In order to set up intent I need to provide URI to saved file.
So first I save file into internal storage (also giving access to other apps withe MODE_WORLD_READABLE):
try {
FileOutputStream out = openFileOutput("scrible",
Context.MODE_WORLD_READABLE);
myBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
Log.d(myTag, e.toString());
}
Then I successfully check its really readable:
File myFile = new File(getFilesDir(), "scrible");
if (myFile.canRead()) {
Log.d(myTag, "Its readable");
}
Then I try to set up intent (which gives me error: stopped unexpectedly):
Uri fileUri = Uri.fromFile(myFile);
startActivity(new Intent(Intent.ACTION_VIEW, fileUri));
I've tried to set up intent separately and it doesnt give error antil call to startActivity(intent);
What I am doing wrong?
The following works well for me:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(outputFileName)),"image/jpeg");
startActivity(intent);
The difference that I see is that you do not call the setDataAndType.