I have a small issue with bitmaps which I want to load into a view with a picture in every entry. The application looks like this:
Application layout
I actually have two problems - the first is that when i compress the file in code by 90%, the result file gives me even higher file size, f.e. file before compressing was 500kb, after its 6MB.
The second problem is that the images are saved to internal storage of the application (/com.example.my.application/files/) but are not shown in the list itself. What you see on the picture is working when i use the pictures directly from gallery using URI of the files, although because of their size, the RAM usage gets too high and after adding 5-6 of them the application crashes.
Here is the code for getting selected picture, compressing and saving:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
File mypath=new File(new File(this.getApplicationContext().getFilesDir(),"")+"/"+data.getData().getLastPathSegment()+".jpg");
try {
FileOutputStream fos = new FileOutputStream(mypath);
Uri imageUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),imageUri);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
imageURI = data.getData().getLastPathSegment();
TextView tv = (TextView) findViewById(R.id.note_image_uri) ;
tv.setText(imageURI);
}
}
This is the adapter of a gridview:
#Override
public void onBindViewHolder(SolventViewHolders holder, int position) {
...
Uri uri = Uri.parse(context.getFilesDir()+"/files/"+itemList.get(position).getUrl());
//Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(image));
holder.countryPhoto.setImageURI(uri);
}
So basically the idea is that after an image from gallery is selected, i want to compress it, save it into /data/com.example....../ under the name specified by .getLastPathSegment(), and then load the picture using the same path with the last path segment which is unique for every object in the view. I guess Im missing something small, but Im not that good at it, so I need your help. Thanks for any help in advance!
Related
I am creating an Android app for class that will take you to the camera app if you click the "capture" button on my user interface. It then returns you to the app and displays the images thumbnail and if you click the "save" button, it will save the button in a SQLite database that I haven't created yet.
My problem is trying to figure out how to access the actual picture and its data, not information about the thumbnail.
The tutorial I was reading has information for storing the image in Android's built in Android's directories, but I can not figure out how to access the actual fullsize image data to store into the database I will be creating myself.
This is the link to the tutorial:
https://developer.android.com/training/camera/photobasics#java
This is not the complete code, just a snipet and it was created in Android Studio:
'''
ImageView pic;
public void capture(View view) {
dispatchTakePictureIntent();
}
public void save(View view) {
}
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#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");
pic.setImageBitmap(imageBitmap); // sets the imageview on the UI as the thumbnail
}
}
'''
I believe that you need to pass a URI of a storage location (file), via the takePictureIntent intent using
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, your_image_Uri);
You can then open the file and retrieve it into a byte[] and store it as a blob. The SQLiteDatase convenience, insert method makes this very easy.
e.g. assuming the byte[] is name my_picture then
ContentValues cv = new ContentValues();
cv.put(column_name_for_picture,my_picture);
long id = insert("the_table_name",null,cv);
You retrieve the stored picture from the db using the SQLiteDatabase query method and then extract the byte[] using the Cursor's getBlob method.
However
If the picture, is 2MB or larger, you will not be able to retrieve it as there is a limitation of 2MB for a CursorWindow (1MB for older versions of Android). I'd suggest that even at 1MB you may well have issues retrieving the image(s).
The recommended way is to not store the image in the database, but to store the path of a file where the image is stored in the database.
You may wish to have a look at How to use images in Android SQLite that are larger than the limitations of a CursorWindow? as this shows a work-around albeit NOT recommended.
Everything works fine except image updation! When I register a new user and when I click in the image, it opens my image gallery, I choose any image, and it back to register activity but it won't update. Also I'm unable to register because that image is not uploading successfully and we sat if imagepath == null, show that's why toast error is coming that fill all the details.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PICK_IMAGE && requestCode == RESULT_OK && data.getData() !=null){
imagePath = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagePath);
userProfilePic.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
NOTE:
I tried multiple images, same issue.
There is no error in logcat.
Default image is showing perfectly when we first time try to register that time we sat android logo which is a default.
I can't register without selecting any image because image path == null.
No problem of image size.
Guys, any solution?
I have an activity to choose and save a profile picture. There is an image view and a button that starts the gallery activity for result awiting the user to choose an image. When the gallery is closed, the following code is executed:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((resultCode == RESULT_OK) && (requestCode == SELECT_PHOTO)) {
Uri selectedImage = data.getData();
try {
Bitmap image = this.decodeAndScaleImage(selectedImage, 285);
imgInsertPicture.setImageBitmap(image);
this.imagePresent = true;
this.saveMyProfilePicture(image);
this.popImageView();
} catch (IOException e) {
e.printStackTrace();
showToast(R.string.error_saving_picture);
}
}
}
private void saveMyProfilePicture(Bitmap picture) throws IOException {
FileOutputStream outputStream = openFileOutput(Globals.MY_PICTURE_FILE_NAME, MODE_PRIVATE);
picture.compress(Globals.MY_PICTURE_FORMAT, 90, outputStream);
outputStream.close();
ByteArrayOutputStream rawOutputStream = new ByteArrayOutputStream();
picture.compress(Globals.MY_PICTURE_FORMAT, 90, rawOutputStream);
byte[] rawPictureData = rawOutputStream.toByteArray();
rawOutputStream.close();
byte[] base64PictureData = Base64.encode(rawPictureData, Base64.DEFAULT);
rawPictureData = null;
FileOutputStream base64OutputStream = openFileOutput(Globals.MY_PICTURE_B64_FILE_NAME, MODE_PRIVATE);
base64OutputStream.write(base64PictureData);
base64OutputStream.close();
}
I debugged this code and verified that:
- no exception is thrown;
- the written files contain the exact amount of data (17kB for the jpg image, 24kB for the base64 version);
- the produced bitmap is the one that I expect and is displayed correctly in the image view.
popImageView is only used to bump the image view on top of other views that were on the front before an image was chosen; and decodeAndScale method only works on bitmap data in memory and doesn't save anything.
However, when I try to reload the current picture when the activity starts, the image displayed is blank and the jpeg file conly contains 3 bytes:
#Override
public void onStart() {
super.onStart();
if (!imagePresent && pictureExists()) {
File pictureFile = new File(getFilesDir(), Globals.MY_PICTURE_FILE_NAME);
imgInsertPicture.setImageURI(Uri.fromFile(pictureFile));
popImageView();
imagePresent = true;
}
}
Here pictureExists checks that the file name is contained in the collection returned by listFiles(). pictureFile.exists() returns true, but as I said, it conly contains 3 bytes. I also tried using BitmapFactory.decodeX, but since the file is broken, it was useless.
I cannot understand why. I checked that the file was written entirely and then it disappears...
When I was debugging on my Nexus S the code worked fine, but then I switched to a Nexus 5 and it broke.
Have you tried decoding the file to a bitmap using BitmapFactory?
http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeFile(java.lang.String)
Haven't tested the following code but can you please try:
File pictureFile = new File(getFilesDir(), Globals.MY_PICTURE_FILE_NAME);
Bitmap bitmapImage = BitmapFactory.decodeFile(Uri.fromFile(pictureFile));
imgInsertPicture.setImageBitmap(bitmapImage);
popImageView();
imagePresent = true;
Try this in your onActivityResult
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(
selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
selectedImagePath =filePath;
then use selectedImagePath as file path.
Hope it helps.
i want to capture an image and save it in folder, but when i capture it, my image is not save in folder that i want, but just save in gallery, and the name of my image is not like what i want.
my image also not display in my activity, is there anyone know, why this is happen?
this is my code :
private void dialogKamera() {
String sdCard= Environment.getExternalStorageDirectory()+"/android/data/spaj/spaj_foto.png";
File file=new File(sdCard);
if(file.exists())
file.delete();
Uri outputFileUri = Uri.fromFile(file);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
image_spaj.setImageBitmap(photo);
}
i don't know where is my fault, i hope somebody can help me to solve my problem, thank you
You should make sure the output directory exists.
EDIT: removed spurious comment :-)
To ensure the directory exists:
File dir = file.getParentFile();
dir.mkdirs();
To display the image, here are several good resources:
How can I display image in Android Application,
Displaying simple bitmap on Android has a list of other resources,
And the tutorial Displaying Bitmaps in Your UI.
First make sure the directory exists, and then
try this:
Change path to
String sdCard= Environment.getExternalStorageDirectory()+"/Android/data/spaj/spaj_foto.png"
'Android' instead of 'android'.
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.