I picked an image from gallery and decoded it. Now I just want to resize that bitmap to standard 72x72 size in order to use as an profile photo.
I searched a lot but nothing worked, some of them rotated my image for no reason, some of them makes image very low quality. Is it that hard?
EDIT
Code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
{
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode)
{
case 100: // SELECT_PHOTO
if(resultCode == RESULT_OK)
{
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream;
try
{
imageStream = getContentResolver().openInputStream(selectedImage);
}catch (Exception e){ return; }
Bitmap bm = BitmapFactory.decodeStream(imageStream);
bm = Bitmap.createScaledBitmap(bm, 72, 72, true);
UpdateAvatar(bm);
}
break;
}
}
Not useful. Check scaled 72x72 and original one:
72x72 (As you see, rotated and very bad quality)
http://imgim.com/9958incic3494599.png
original:
http://imgim.com/3847incix7666386.png
Try this-
Bitmap yourBitmap;
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
Or other way-
resized = Bitmap.createScaledBitmap(yourBitmap,(int)(yourBitmap.getWidth()*0.8), (int)(yourBitmap.getHeight()*0.8), true);
No, it's not that hard. Just use Bitmap.createScaledBitmap():
Bitmap.createScaledBitmap(bitmap, width, height, true);
This is an example of a method that would give me a maximum of 120x120 image, hope this helps you :
public static Bitmap decodeWithBounds(String srcImg) {
Bitmap image;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcImg, options);
if (options.outHeight > 120 || options.outWidth > 120) {
options.inSampleSize = Math.max(
Math.round(options.outHeight / 120),
Math.round(options.outWidth / 120));
}
options.inJustDecodeBounds = false;
image = BitmapFactory.decodeFile(srcImg, options);
return image;
}
Related
I want to send a picture I took to server with multipart/form-data.
Of course, all the process goes very well.
I get the absolute path of the picture on onActivityResult. I sent it to AsyncTask class to change it into File object. Then, I use FileInputStream to send the picture to server.
Here's my code for sending picture.
MainActivity:
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode != RESULT_OK)
return;
if(requestCode == PICK_FROM_CAMERA){
// uri of selected picture
imageUri = data.getData();
// path of selected picture
Cursor c = this.getContentResolver().query(imageUri, null, null, null, null);
c.moveToNext();
absolutePath = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
Glide.with(this).load(imageUri).into(image);
}
}
Asynctask class:
absolutePath is in params[7]
FileInputStream fileInputStream ;
wr.writeBytes("\r\n--" + boundary + "\r\n");
wr.writeBytes("Content-Disposition: form-data; name=\"file1[]\"; " +
"filename=\"image.jpg\"\r\n");
wr.writeBytes("Content-Type: application/octet-stream\r\n\r\n");
fileInputStream = new FileInputStream(params[7]);
When I send the picture, I just send it without resizing.
It takes too much time and data to finish sending.
I want to make the picture smaller when sending to server.
that is, with absolute Path, I want to make smaller picture that can be turned into File object.
Can anyone give me some hint?
You can store your imageFile as Uri variable and then resize your image according to your desired width and height to be compressed.
Bitmap b = BitmapFactory.decodeFile(String.valueOf(fileUri));
Bitmap out = Bitmap.createScaledBitmap(b, IMG_WIDTH, IMG_HEIGHT, false);
FileOutputStream fOut;
try {
fOut = new FileOutputStream(fileUri);
out.compress(Bitmap.CompressFormat.JPEG, 60, fOut);
fOut.flush();
fOut.close();
b.recycle();
out.recycle();
Log.i("Compressing file", String.valueOf(uriFile));
} catch (Exception e) {
Log.e("ErrInCompressingPicture","" + e);
}
You can compress the picture you got before you send to server!
one solution is set inSampleSize directly:
public static Bitmap getImage(String imgPath){
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2;
try {
b=BitmapFactory.decodeFile(imgPath, options);
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
the other solution is set width and height of you want:
public static Bitmap getSmallBitmap(String imgPath,int reWidth,int reHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imgPath, options);
int width = options.outWidth;
int height = options.outHeight;
int inSampleSize=0;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imgPath, options);
}
This question already has answers here:
Pick an image and resize to 72x72
(3 answers)
Closed 9 years ago.
I picked an image from gallery and decoded it. Now I just want to resize that bitmap to standard 72x72 size in order to use as an profile photo.
I searched a lot but nothing worked, some of them rotated my image for no reason, some of them makes image very low quality. Is it that hard?
Check scaled 72x72 and original one:
72x72 (As you see, rotated and very bad quality)
http://imgim.com/9958incic3494599.png
original:
http://imgim.com/3847incix7666386.png
Code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
{
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode)
{
case 100: // SELECT_PHOTO
if(resultCode == RESULT_OK)
{
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream;
try
{
imageStream = getContentResolver().openInputStream(selectedImage);
}catch (Exception e){ return; }
Bitmap bm = BitmapFactory.decodeStream(imageStream);
bm = Bitmap.createScaledBitmap(bm, 72, 72, true);
UpdateAvatar(bm);
}
break;
}
}
Try this function :
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
It helps for me.
I am implementing an android program that allows users to upload photos from their device gallery to an ImageView. saving it in the cloud. My code works fine with small photos, but bigger photos caused the application to stop. I'm getting this error:
Bitmap too large to be uploaded into a texture (4128x2322, max=4096x4096)
I tried to resize the uploaded photo before displaying it using suggestions from previous questions, but they didn't work. I am not sure what the problem with my code is.
Any help would be appreciated. Here is the code from my last attempt:
{
// omitted code segment from onCreate...
browseButton = ((Button) findViewById(R.id.browse_button));
browseButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
}
);
}
//end on create
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
if (requestCode == SELECT_PICTURE)
{
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
Bitmap bitmap = BitmapFactory.decodeFile(selectedImagePath);
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress image to lower quality scale 1 - 100
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
image = stream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
Bitmap toyImageScaled = Bitmap.createScaledBitmap(bitmap, 200, 200
* bitmap.getHeight() / bitmap.getWidth(), false);
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledToyImage = Bitmap.createBitmap(toyImageScaled, 0,
0, toyImageScaled.getWidth(), toyImageScaled.getHeight(),
matrix, true);
toyPreview.setImageBitmap(bitmap);
}
}
}
public String getPath(Uri uri)
{
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
You're still showing the big image at:
toyPreview.setImageBitmap(bitmap);
You should be showing the scaled image, toyImageScaled or rotatedScaledToyImage.
I think you should use the examples of the documentation, and use InSampleSize.
see this : http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
From DOCS:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
I want to load an image from gallery as a bitmap an show it on a custom view(not an imageview).Here is the code for loading bitmap.
private Bitmap loadBitmap(String filePath, int orientation, int width, int height) {
Bitmap bitmap = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
int scale = 1;
if ((options.outWidth > width) || (options.outHeight > height)) {
if (options.outWidth < options.outHeight) {
scale = Math.round((float) options.outWidth / width);
} else {
scale = Math.round((float) options.outHeight/ height);
}
}
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(filePath, options);
if (orientation > 0) {
// rotate the image w.r.to orientation
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0,width,height, matrix, true);
}
} catch (Exception e) {
bitmap = null;
}
return bitmap;
}
Now my problem is that the canvas does not show the bitmap completely.Only a part o it.How can i adjust the image (without losing its clarity,not stretching) with screen size?
Thanks in Advance
May be you can try the ScaleType options and use the one whihc suits you the best. Follow the link below for details:
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I have taken thumbnail image from gallery which is smaller in size and resized into 300*300 size.
By doing that the image looking so blurred.
getting image from gallery
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case 0:
if (resultCode == RESULT_OK) {
try {
flag = 1;
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex); // file
// path
// of
// selected
// image
cursor.close();
// Convert file path into bitmap image using below line.
yourSelectedImage = download.getResizedBitmap(
image.decodeImage(filePath),270,228);
// put bitmapimage in your imageview
profile_image.setImageBitmap(
yourSelectedImage);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Image resizing
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth)
{
try
{
if(bm!=null)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return resizedBitmap;
}
Images get blurred when you enlarge them (unless you are using an vector image and you are using a bitmap). Your getResizedBitmap method doesn't do anything much other than stretching the image to fit the new size. The only way you are going to solve your problem is by selecting larger images (but then eventually you will run into the aspect ratio problem, so you should really rethink your scaling algorithm).
Of course enlarging a bitmap image will be pixelated..