I have searched but for some answers but may be my fault couldn't find my desired answer.Now below what i am trying:
I am trying to upload an image like of a status or a post or any profile pic.Profile pic will be small and status or any post image will be big. Now what i want to do:
1. I am converting the image to string text and uploading it to datastore and it's limit is 1Mbyte.So i want to check while uploading image that it doesn't cross limit.
2. I want to check that the image is of png format.If it is not then won't upload.Show a Toast.Can i convert image there?? :(
3. If user is uploading image of suppose 700kbyte but the profile pic is small i.e 100kbyte will be enough for profile pic then i can compress the pic to my defined size and then upload it to datastore.It may remain 700kbyte if it is for status image.
I am converting image to string and uploading it to datastore and again converting back to image while showing it in my app.My code:
public static String imageToStringConverter(Bitmap image){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
String imageToString = Base64.encodeToString(byteArray, Base64.NO_WRAP);
return imageToString;
}
public static Bitmap stringToimageConverter(String imageString){
byte[] stringTobyte = Base64.decode(imageString, Base64.NO_WRAP);
Bitmap bmp = BitmapFactory.decodeByteArray(stringTobyte, 0, stringTobyte.length);
return bmp;
}
Now the problem i am facing
:
1.When i am uploading the image it is taking time.So should i use asynctask while uploading after converting the image to my desired size??
2.When i first enter into my app ,i have shown profile pic i.e if i log into my account it will fetch an image for profile from datastore.But it is taking much time and my log in seems to be lengthy.
I have solved my problem by reducing the image.
Here is my code:
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case SELECT_PHOTO:
Uri imageUri;
try {
imageUri = imageReturnedIntent.getData();
}catch(Exception e){
Toast.makeText(getActivity(),"Image Not Found",Toast.LENGTH_SHORT).show();
return;
}
//final InputStream imageStream = getActivity().getContentResolver().openInputStream(imageUri);
//final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
ShrinkBitmapConverter sh = new ShrinkBitmapConverter(getActivity());
Bitmap selectedImage = null;
try {
selectedImage = sh.shrinkBitmap(imageUri,450,350);
} catch (Exception e) {
Toast.makeText(getActivity(),"Image Not Found",Toast.LENGTH_SHORT).show();
}
statusImage = ImageConverter.imageToStringConverter(selectedImage);
if(statusImage.length()>512000){
Toast.makeText(getActivity(),"Image is too big",Toast.LENGTH_LONG).show();
}else {
postImage.setImageBitmap(selectedImage);
}
}
}
ImageConverter.java:
public class ImageConverter {
public static String imageToStringConverter(Bitmap image){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
String imageToString = Base64.encodeToString(byteArray, Base64.NO_WRAP);
return imageToString;
}
public static Bitmap stringToimageConverter(String imageString){
byte[] stringTobyte = Base64.decode(imageString, Base64.NO_WRAP);
Bitmap bmp = BitmapFactory.decodeByteArray(stringTobyte, 0, stringTobyte.length);
return bmp;
}
}
ShrinkBitmapConverter.java:
public class ShrinkBitmapConverter {
Context context;
public ShrinkBitmapConverter(Context c){
context=c;
}
public Bitmap shrinkBitmap(Uri uri,int width,int height) throws FileNotFoundException {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = null;;
try {
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpFactoryOptions);
} catch (Exception e) {
Toast.makeText(context,"Image Not Found",Toast.LENGTH_SHORT).show();
}
return bitmap;
}
}
Related
I have this code that can compress a selected image in the gallery which is very useful when you want to allow the user to add a profile picture. this code works fine but I would like the compressed image to be saved in the shared preferences in order to be persistent.
public void chooseImage(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
public void compressImage(View view) {
if (actualImage == null) {
showError("Please choose an image!");
} else {
// Compress image in main thread using custom Compressor
try {
compressedImage = new Compressor(this)
.setMaxWidth(640)
.setMaxHeight(480)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.setDestinationDirectoryPath(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath())
.compressToFile(actualImage);
setCompressedImage();
} catch (IOException e) {
e.printStackTrace();
showError(e.getMessage());
}
}
}
private void setCompressedImage() {
compressedImageView.setImageBitmap(BitmapFactory.decodeFile(compressedImage.getAbsolutePath()));
compressedSizeTextView.setText(String.format("Size : %s", getReadableFileSize(compressedImage.length())));
Toast.makeText(this, "Compressed image save in " + compressedImage.getPath(), Toast.LENGTH_LONG).show();
Log.d("Compressor", "Compressed image save in " + compressedImage.getPath());
}
private void clearImage() {
actualImageView.setBackgroundColor(getRandomColor());
compressedImageView.setImageDrawable(null);
compressedImageView.setBackgroundColor(getRandomColor());
compressedSizeTextView.setText("Size : -");
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK) {
if (data == null) {
showError("Failed to open picture!");
return;
}
try {
actualImage = FileUtil.from(this, data.getData());
actualImageView.setImageBitmap(BitmapFactory.decodeFile(actualImage.getAbsolutePath()));
actualSizeTextView.setText(String.format("Size : %s", getReadableFileSize(actualImage.length())));
clearImage();
} catch (IOException e) {
showError("Failed to read picture data!");
e.printStackTrace();
}
}
}
public void showError(String errorMessage) {
Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show();
}
private int getRandomColor() {
Random rand = new Random();
return Color.argb(100, rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
}
public String getReadableFileSize(long size) {
if (size <= 0) {
return "0";
}
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
I have looked at all these answers but none deals specifically with the question Que1 Que2 Que3 Que4 Que5
help me how do i record a compressed image
I would not recommend you to do this at all, since you can just save an image to the storage of your phone. However if you really want to do this...
You can convert your image to a byte[] byte array. Then convert it to a Base64 string.
String encodedImg = Base64.encodeToString(bytes, Base64.DEFAULT);
Then store it using:
SharedPreferences.Editor editor = preferences.edit();
editor.putString("image", encodedImg);
Then you can use preferences.getString("image", ""); to get the image back. Do a Base64.decode and convert it back to the image.
However, I would recommend you to think about the architecture of your application. Doing this sounds just so wrong.
Maybe this is a better option for you: https://stackoverflow.com/a/17674787/5457878
Method to encode your bitmap into string base64-
public static String encodeTobase64(Bitmap image) {
Bitmap immage = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
immage.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
Log.d("Image Log:", imageEncoded);
return imageEncoded;
}
bitmap inside this method like something in your preference:
SharedPreferences.Editor editor = myPrefrence.edit();
editor.putString("namePreferance", itemNAme);
editor.putString("imagePreferance", encodeTobase64(yourbitmap));
editor.commit();
**display your image just anywhere, convert it into a bitmap again **
public static Bitmap decodeBase64(String input) {
byte[] decodedByte = Base64.decode(input, 0);
return BitmapFactory
.decodeByteArray(decodedByte, 0, decodedByte.length);
}
i upload image to server with help of volley and bitmap and i successfully pass the data, but when i take the image using camera the image quality become so poor and also when i pass an image of size above 500kb the app become crash. Why this happen??
can anyone help me,
this is how my camera intent perform
private void onCaptureImageResult(Intent data) {
thumbnail = (Bitmap) data.getExtras().get("data");
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
//fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (thumbnail!=null){
addImageNew.setImageBitmap(thumbnail);
}
}
this is how my gallery intent perform
private void onSelectFromGalleryResult(Intent data) {
thumbnail=null;
if (data != null) {
try {
thumbnail = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
if (thumbnail!=null){
addImageNew.setImageBitmap(thumbnail);
}
}
this how i convert Bitmap to string
public String getStringImage(Bitmap bmp){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 90, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
NOTE: i have only problem in image quality and high size image passing
You can try to use below link solution. It may be work for you.
200kb image to base64 cannot send to web service
I didn't find where getStringImage(Bitmap bmp) is called, but you can try to do something like that:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
getStringImage(bitmap);
Or maybe you can change the compress to 100, for high quality:
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
Can anyone tell me how to convert imageview to bitmap? In my app, i'm accessing the gallery and getting a bitmap of a picture into an imageview, then using picasso, i'm resizing the images that are too big to directly uploaded to parse. I can resize the image in the image view using picasso but how do i get the bitmap from the image view to upload to parse? this is my code..
public static final int IMAGE_GALLERY_REQUEST = 20;
private ImageView imgPicture;
public Bitmap image;
public void openGallery(View view){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);//
startActivityForResult(Intent.createChooser(intent, "Select Picture"),IMAGE_GALLERY_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
// if we are here, everything processed successfully.
if (requestCode == IMAGE_GALLERY_REQUEST) {
Uri imageUri = data.getData();
InputStream inputStream;
try {
inputStream = getContentResolver().openInputStream(imageUri);
image = BitmapFactory.decodeStream(inputStream);
height= image.getHeight();
h= String.valueOf(height);
width= image.getWidth();
w= String.valueOf(width);
if (width>800 || height>600)
{
Picasso.with(this)
.load(imageUri)
.resize(800,600)
.centerCrop()
.into(imgPicture);
// imgPicture.setImageBitmap(image);
//what should i write here to convert this imageview to bitmap? and then later use that bitmap to upload the image to parse?
}
else
{
//do nothing
imgPicture.setImageBitmap(image);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
// show a message to the user indictating that the image is unavailable.
Toast.makeText(this, "Unable to open image", Toast.LENGTH_LONG).show();
}
}
}
}
You only can generate the bitmap from imageview but not in real image size, this generate the bitmap with imageview size
Bitmap bitmap;
try {
bitmap = Bitmap.createBitmap(YOUR_VIEW.getWidth(), YOUR_VIEW.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
YOUR_VIEW.draw(canvas);
File root = Environment.getExternalStoragePublicDirectory(Environment.PICTURES);
String fname = "NAME_OF_FILE.jpg";
file = new File(root, fname);
try {
if (!root.exists()) {
root.mkdir();
}
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
YOUR_VIEW.destroyDrawingCache();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
If you don't wanna save to a file, use this code:
public static Bitmap getScreenViewBitmap(View v) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
Hi guys I wanted to ask you one thing, I have a chat that transfers strings and I can even attach of JPEG images before sending them to convert it into a string and then decode in BITMAP just that when I decode it crashes the app. I wanted to know if it is the right code to decode it.
NOME = (TextView) row.findViewById(R.id.comment);
NOME.setText(coment.comment);
String a = NOME.getText().toString();
if(a.length() > 1024 )
{
byte[] image = Base64.decode(a, 0);
int lung = a.length();
Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, lung);
Image = (ImageView) row.findViewById(R.id.image);
Image.setImageBitmap(bitmap);
}
The code looks fine, if I had to guess I would say you're getting the Out of Memory error, which is very common when loading images. Check out
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
for some best practices when loading images.
The method for Encoding an Image to String Base64 :
public static String encodeToString() {
String imageString = null;
try {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
imageString = Base64.encodeToString(b, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return imageString;
}
The method for Decoding String Base64 to Image :
public static void decodeToImage(String imageString) {
try {
byte[] imageByte = Base64.decode(imageString, Base64.DEFAULT);
Bitmap bm = BitmapFactory.decodeByteArray(imageByte, 0, imageByte.length);
image_view.setImageBitmap(bm);
} catch (Exception e) {
e.printStackTrace();
}
}
in android I took a picture by the cam and returnded it to my activity:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Constatnts.ANSWER_TO_LIFE_UNIVERSE_AND_EVERYTHING && data != null && data.getExtras() != null && data.getExtras().get("data") != null) {
Bitmap snapshot = (Bitmap) data.getExtras().get("data");
String convert = InputOutput.bitmapToString(this, snapshot);
Bitmap back = InputOutput.stringToBitmap(convert);
}
}
When I assign the Bitmap 'snapshot' to an imageview it loosk pretty good an works well. But when I assign the Bitmap 'back" to an imageview it does not change its view. So there must be something wrong in transformation. Here is my code for the tranformation:
public static Bitmap stringToBitmap(String bitmapString) {
byte[] bytes = Base64.decode(bitmapString, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
return bitmap;
}
public static String bitmapToString(Context context, Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
bitmap.recycle();
byte[] byteArray = stream.toByteArray();
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
stream.write(byteArray, 0, byteArray.length);
stream = null;
String strBase64 = Base64.encodeToString(byteArray, Base64.URL_SAFE);
return strBase64;
}
Any suggestions what goes wrong here? Thanks!
Here's a code I used once to try this conversion, it should work:
public final static String bitmapToString(Bitmap in){
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
in.compress(Bitmap.CompressFormat.PNG, 100, bytes);
return Base64.encodeToString(bytes.toByteArray(),Base64.DEFAULT);
}
public final static Bitmap stringToBitmap(String in){
byte[] bytes = Base64.decode(in, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
You might want to add some close() calls to the streams though.