I am using this code to save pic in Imageview but the image is stretched when dsave in imageview. Camera preview is prefect and click right image but when i set that image in imageview the image is stetched.
public void onPicTaken(byte[] data) {
if (data != null) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
bm=scaled;
}
ivCaptureImagePreview.setImageBitmap(bm);
ivCaptureImagePreview.setVisibility(View.VISIBLE);
}
}
Use following class for creating scaled bitmap
public class ScalingUtilities
{
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
and use this class in your function as below
public void onPicTaken(byte[] data) {
if (data != null) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = ScalingUtilities.createScaledBitmap(bm, screenHeight, screenWidth, ScalingLogic.FIT);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = ScalingUtilities.createScaledBitmap(bm, screenHeight, screenWidth, ScalingLogic.FIT);
bm=scaled;
}
ivCaptureImagePreview.setImageBitmap(bm);
ivCaptureImagePreview.setVisibility(View.VISIBLE);
}
}
I use this function in my one of project please check if it is useful for you.
public static Bitmap Preview(String path) {
//SCALE IMAGE
int SCALE = 4;
try {
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = SCALE;
Bitmap bitmap = BitmapFactory.decodeFile(path, o2);
OutputStream os = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
File file = new File(path);
while (file.length() > 800000) {
SCALE += 2;
o2.inSampleSize = SCALE;
bitmap = BitmapFactory.decodeFile(path, o2);
os = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
file = new File(path);
}
bitmap = BitmapFactory.decodeFile(path, o2);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
UIImageView Settings
<ImageView
android:id="#id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
My Test Application for this Problem
For Getting the Picture From the Camera, I use the following methods:
private void pickImageIntent()
{
Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
getCurrentActivity().startActivityForResult(pickPhoto, REQUEST_PICK_IMAGE);
}
private void takeImageIntent()
{
try
{
File outputDir = getCurrentActivity().getExternalCacheDir();
File outputFile = File.createTempFile("prefix", "extension", outputDir);
selectedImageUri = Uri.fromFile(outputFile);
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePicture.putExtra(MediaStore.EXTRA_OUTPUT, selectedImageUri);
getCurrentActivity().startActivityForResult(takePicture, REQUEST_TAKE_IMAGE);
}
catch (IOException e)
{
e.printStackTrace();
}
}
For Getting the Result From the Camera or Image Picker, and show it in the imageView. Here this.myInterfaceImage:
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch(requestCode)
{
case REQUEST_PICK_IMAGE:
if(resultCode == Activity.RESULT_OK)
{
selectedImageUri = data.getData();
initImage(selectedImageUri);
}
break;
case REQUEST_TAKE_IMAGE:
if(resultCode == Activity.RESULT_OK)
{
initImage(selectedImageUri);
}
break;
}
}
protected void initImage(Uri selectedImageUri_) {
try {
ParcelFileDescriptor parcelFileDescriptor = getContext().getContentResolver().openFileDescriptor(selectedImageUri_, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap source = BitmapFactory.decodeFileDescriptor(fileDescriptor);
float ratio = (float)source.getWidth() / (float)source.getHeight();
// here perhaps limit the size of the image
int height = Math.min(getContext().getResources().getDisplayMetrics().heightPixels, source.getHeight());
int width = (int)(ratio*height);
Bitmap result = Bitmap.createScaledBitmap(source, width, height, false);
this.interfaceImage.setImageBitmap(result);
if (result != source) {
source.recycle();
}
} catch (Exception ex) {
System.out.println("File not found");
}
}
This is how I used this in My Test Application, and it works I don't have any orientation issues. I tested in Portrait mode with Portrait and Landscape Picture, and in Landscape mode with Portrait and Landscape Picture. And with both where I changed the orientation after before getting the Image.
If your are using Custom Camera and the orientation is wrong with the Code Above, just add this
There are two things needed:
Camera preview need the same as your rotation. Set this by
camera.setDisplayOrientation(result);
Save the picture captured as your camera preview. Do this via Camera.Parameters.
int mRotation = getCameraDisplayOrientation();
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(mRotation); //set rotation to save the picture
camera.setDisplayOrientation(result); //set the rotation for preview camera
camera.setParameters(parameters);
Then you can use your function without the orientation stuff
public void onPicTaken(byte[] data) {
if (data != null) {
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
int screenWidth = getResources().getDisplayMetrics().widthPixels;
float ratio = (float)bm.getWidth() / (float)bm.getHeight();
int screenHeight = (int)(ratio*screenWidth)
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
if (scaled != bm) {
source.recycle();
}
ivCaptureImagePreview.setImageBitmap(scaled);
ivCaptureImagePreview.setVisibility(View.VISIBLE);
}
}
Hope that helps.
Use this it will prevent image from stretching and maintaining the aspect ratio of image
android:scaleType="fitXY" // or desired scale type
android:adjustViewBounds="true"
Scaling your bitmap with Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); won't maintain aspect ratio because this will stretch the width and height of the bitmap to match the target.
An option would be to calculate the target height manually so no cropping occurs:
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
int targetHeight = (int) (screenWidth * aspectRatio);
And then use targetHeight instead of screenHeight as height argument in createScaledBitmap().
In addition, make sure the imageview you load your bitmap into has the appropriate scale type (e.g. FIT_CENTER or CENTER_CROP).
As you can see in documentation enter link description here;
you have to resize and rescale your bitmap before rendering so you can use code below for your BitmapFactory.Options :
mBitmapOptions.inScaled = true;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeResources(getResources(),
mImageIDs, mBitmapOptions);
use this putExtra in your intent call for camera
intent.putExtra("outputX", 80);
intent.putExtra("outputY", 80);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 20);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, Utility.REQUEST_FOR_CAMERA);
Related
I'm trying to enable user to take picture from his camera and store it internally in memory and it's working. Problem is when I try to resize that image i created a method and find a way to achieve that but problem is onActivity only return null on data so I can't access it
public void takePicture() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "App");
imagesFolder.mkdirs();
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File image = new File(imagesFolder, "QR_" + timeStamp + ".jpg");
Uri uriSavedImage = Uri.fromFile(image);
uriString=uriSavedImage.toString();
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){
Uri uri =data.getData();
changeImageSize(uri,500,500);
}
}
private Bitmap changeImageSize(Uri fileUri, int width, int height) {
Bitmap bitmap = null;
File imgFile = new File(getRealPathFromURI(getApplicationContext(),fileUri));
if (imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
}
if (bitmap != null) {
return bitmap = (Bitmap.createScaledBitmap(bitmap, width, height, false));
}
return null;
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = getActivity().getContentResolver().query(contentUri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":")+1);
cursor.close();
cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null
, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
I tried to add few solutions posted bellow and now I'm getting error from my getRealPathFromURI method stating this:
Logcat
Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=null, request=65636, result=-1, data=null} to activity {com.app/com.app.MainPostLogin}: java.lang.NullPointerException:
Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
When you pass a Uri to camera it doesn't return any data. Store this File in a local variable File image = new File(imagesFolder, "QR_" + timeStamp + ".jpg"); and try
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK){
changeImageSize(Uri.fromFile(image),500,500);
}
}
This is the working code which i using in my project to resize image.
Create this method (Just copy paste):
private String decodeFile(String path, int DESIREDWIDTH, int DESIREDHEIGHT) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
// Part 2: Scale image
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
} else {
unscaledBitmap.recycle();
return path;
}
// Store to tmp file
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr + "/TMMFOLDER");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = "tmp.png";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
scaledBitmap.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
Create this class(Just copy paste):
package com.katariya.pomoc.utils;
/**
* Created by Danish.sharma on 5/31/2016.
*/
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
/**
* Class containing static utility methods for bitmap decoding and scaling
*
* #author
*/
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
This is the main line to resize the image
Bitmap bmp = BitmapFactory.decodeFile(decodeFile(file.toString(), 600, 600));
imageView.setImageBitmap(bmp);
See my onActivityResult how and where i'm using these lines:
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST) {
new Thread(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory() + "/Guesp");
if (!destination.exists()) {
File f = new File("/sdcard/POMOC/");
f.mkdir();
}
File file = new File(new File("/sdcard/POMOC/"), System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
file.createNewFile();
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.close();
picturePath = file.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bmp = BitmapFactory.decodeFile(decodeFile(file.toString(), 600, 600));
img_profilePhoto.setImageBitmap(bmp);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}).start();
}
}
Thats it.
I am trying to do Capture Image, compress to a file & upload it to my server. But, when I am doing that, my memory size suddenly increases by 60 MB.
I am doing the following approach to get compress image file path. During this process only,memory size increases suddenly & sometimes I am getting out of memory issue also.
public String getScaledPic(String path)
{
Bitmap img;
try {
String filePath =path;;
String folderName = filePath.substring(0, filePath.lastIndexOf("/")+1);
String tmpFileName = (filePath.substring(filePath.lastIndexOf("/")+1)).split("\\.")[0]+"_tmp.jpg";
File from = new File(filePath);
folderName=getActivity().getFilesDir()+"/";
File to = new File(folderName+tmpFileName);
try {
copy(from, to);
compress(folderName+tmpFileName);
} catch (IOException io){
return path;
}
return folderName+tmpFileName;
}
catch(Exception e)
{
return path;
}
}
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public void compress(String comp) {
try {
String path = comp;
BitmapFactory.Options buffer = new BitmapFactory.Options();
Bitmap bmp = BitmapFactory.decodeFile(path, buffer);
if (bmp.getWidth() > 768 && bmp.getHeight() > 768){
float widthCompression = 768.0f/bmp.getWidth();
float heightCompression = 768.0f/bmp.getHeight();
if (widthCompression>=heightCompression)
{
Bitmap resized = Bitmap.createScaledBitmap(bmp,(int)(bmp.getWidth()*widthCompression), (int)(bmp.getHeight()*widthCompression), true);
bmp.recycle();
FileOutputStream out = new FileOutputStream(path);
resized.compress(CompressFormat.JPEG, 100, out);
resized.recycle();
out.flush();
out.close();
}
else
{
Bitmap resized = Bitmap.createScaledBitmap(bmp,(int)(bmp.getWidth()*heightCompression), (int)(bmp.getHeight()*heightCompression), true);
bmp.recycle();
FileOutputStream out = new FileOutputStream(path);
resized.compress(CompressFormat.JPEG, 100, out);
resized.recycle();
out.flush();
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Is there any mistake my approach? Also, from the image, how to handle the memory leaks or heavy memory usage caused by the bitmaps?
Hey I use the following code to reduce the file size.
===================== Add this class ================================
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
============= use this method to resize the image ==================
private String decodeFile(String path, int DESIREDWIDTH, int DESIREDHEIGHT) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
// Part 2: Scale image
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
} else {
unscaledBitmap.recycle();
return path;
}
// Store to tmp file
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr + "/TMMFOLDER");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = "tmp.png";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
scaledBitmap.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
I get capture image from android camera. Then save in sd card folder which is name Test_Folder. Then i do try to convert Image into Encode String via Base64. Then i get string. When getting encoded codes Base 64 Encoder / Decoder website. Get i download image from this website. Finally I get black image always.
My codes below step by step: such as
MainActivity.java
public class MainActivity extends Activity {
public String imageName, imagePath;
public static final String TAG = "MainActivity";
protected static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 0;
public File dir;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dir = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/" + "Test_Folder");
if (dir.exists()) {
Log.i(TAG, "folder already exist");
} else {
if (dir.mkdirs()) {
Log.i(TAG, "folder make now");
}
}
SecureRandom random = new SecureRandom();
String randomName = new BigInteger(10, random).toString(4);
imageName = "myImage" + "" + randomName + ".PNG";
File file = new File(dir, imageName);
imagePath = file.getAbsolutePath();
Uri outputFileUri = Uri.fromFile(file);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(i, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
File file = new File(dir, imageName);
String imageRowData = imageToBinary(file);
Log.i(TAG, "::image::" + imageRowData);
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
if (bitmap.getWidth() > bitmap.getHeight()) {
// force to resize given values
// getScaledBitMap(imagePath, 2048, 1536);
// Toast.makeText(getApplicationContext(), "Landscape",
// Toast.LENGTH_LONG).show();
} else {
// force to resize given values
// getScaledBitMap(imagePath, 1536, 2048);
// Toast.makeText(getApplicationContext(), "portrait",
// Toast.LENGTH_LONG).show();
}
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
} else {
//
}
}
public String imageToBinary(File imgFile) {
// image-> bitmap
BitmapFactory.Options option = new BitmapFactory.Options();
option.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bm = BitmapFactory.decodeFile(imgFile.getPath(), option);
// bitmap-> bytearrayoutputstream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Log.i("DDDDDDDDDDDDDDD", "DDDDDDDDDDDDDDDDDDDDDD");
bm.compress(Bitmap.CompressFormat.PNG, 90, baos);
Log.i("FFFFFFFFFFFFFFFFFff", "FFFFFFFFFFFFFFF");
// bytearrayoutputstream-> byte[]
byte[] ba = baos.toByteArray();
// byte[]-> string
String imageBinary = Base64.encodeBytes(ba);
return imageBinary;
}
// ----------------------------Start of resizing image
// codes------------------------
private Bitmap getScaledBitMap(String filePath, int reqWidth, int reqHeight) {
if (filePath != null && filePath.contains("file")) {
filePath = filePath.replace("file://", "");
}
Log.i(TAG, ":test:0");
Bitmap unscaledBitmap = ScalingUtilities.decodeBitmap(getResources(),
filePath, reqWidth, reqHeight, ScalingLogic.CROP);
// Part 2: Scale image
Bitmap scaledBitmap = ScalingUtilities.createScaledBitmap(
unscaledBitmap, reqWidth, reqHeight, ScalingLogic.CROP);
Log.i(TAG, ":test:1");
unscaledBitmap.recycle();
Log.i(TAG, ":test:2");
// convert and save sd card folder
try {
Log.i(TAG, ":test:try");
OutputStream fOut = null;
File file = new File(dir, imageName);
fOut = new FileOutputStream(file);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
fOut = null;
MediaStore.Images.Media.insertImage(getContentResolver(),
file.getAbsolutePath(), file.getName(), file.getName());
String imageRowData = imageToBinary(file);
Log.i(TAG, ":imageRowData:" + imageRowData);
} catch (FileNotFoundException e) {
Log.i(TAG, ":test:FileNotFoundException:" + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.i(TAG, ":test:IOException:" + e.toString());
e.printStackTrace();
}
return scaledBitmap;
}
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
public static class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap
* will be optimized for further scaling to the requested destination
* dimensions and scaling logic.
*
* #param res
* The resources object containing the image data
* #param resId
* The resource id of the image data
* #param dstWidth
* Width of destination area
* #param dstHeight
* Height of destination area
* #param scalingLogic
* Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeBitmap(Resources res, String pathName,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth,
options.outHeight, dstWidth, dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(pathName, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap
* Bitmap to scale
* #param dstWidth
* Wanted width of destination bitmap
* #param dstHeight
* Wanted height of destination bitmap
* #param scalingLogic
* Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(),
unscaledBitmap.getHeight(), dstWidth, dstHeight,
scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(),
unscaledBitmap.getHeight(), dstWidth, dstHeight,
scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(),
dstRect.height(), Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(
Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at
* least one of the two dimensions fit inside the requested destination
* area. Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a
* source image, the dimensions of a destination area and a scaling
* logic.
*
* #param srcWidth
* Width of source image
* #param srcHeight
* Height of source image
* #param dstWidth
* Width of destination area
* #param dstHeight
* Height of destination area
* #param scalingLogic
* Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth
* Width of source image
* #param srcHeight
* Height of source image
* #param dstWidth
* Width of destination area
* #param dstHeight
* Height of destination area
* #param scalingLogic
* Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int) (srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth,
srcHeight);
} else {
final int srcRectHeight = (int) (srcWidth / dstAspect);
final int scrRectTop = (int) (srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop
+ srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth
* Width of source image
* #param srcHeight
* Height of source image
* #param dstWidth
* Width of destination area
* #param dstHeight
* Height of destination area
* #param scalingLogic
* Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth,
(int) (dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int) (dstHeight * srcAspect),
dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
// ---------end of resizing image codes------------------------
}
My Base64.java
Base64.java
also i add permission in AndroidMenifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
can you anybody help me getting original image giving modification or helpful links of example or tutorial or others?
You can try like this. Such as:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bm = BitmapFactory.decodeFile(imagePath);
bm.compress(Bitmap.CompressFormat.JPEG, 90, baos);
byte[] byteImage_photo = baos.toByteArray();
Log.i("BM Size:", " Byte Count: " + bm.getByteCount());
Log.i("baos Size:", " Size: " + baos.size());
Log.i("Byte Image photo:", " Image photo Size: "
+ byteImage_photo.length);
String imageRowData = Base64.encodeToString(byteImage_photo,
Base64.DEFAULT);
File file = new File(dir, "/filename.txt");
if (!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(imageRowData);
bw.close();
I expect it to be helpful, Hopefully
I am new in android development. I want take an image from android camera tool then save as thumbnail and also save as Full-size (Resize & crop user defined).
I actually want thumbnail image show in GridView from one folder of SD Card then click one image then show full-size(1536 X 2048) image in one window from another folder of SD Card.
I search in google but not get absolute example or tutorial which is match two conditions.
For example
developer.android.com/training/camera/photobasics.html#TaskPath
taking pictures with camera android programmatically
Capture Image from Camera and Display in Activity
Please anybody help me, how to possible this. If my concept mismatch then modify to update my question. Please anybody help me.
Follow bellow Steps:-
1:-
private Bitmap getScaledBitMap(String filePath, int reqWidth, int reqHeight) {
if (filePath != null && filePath.contains("file")) {
filePath = filePath.replace("file://", "");
}
Bitmap unscaledBitmap = ScalingUtilities.decodeBitmap(getResources(), filePath, reqWidth, reqHeight, ScalingLogic.CROP);
// Part 2: Scale image
Bitmap scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, reqWidth,reqHeight, ScalingLogic.CROP);
unscaledBitmap.recycle();
return scaledBitmap;
}
2:-
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeBitmap(Resources res, String pathName, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(pathName, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
save this bitmap into required folder.
Create a File
private final int CAMERA_PIC_REQUEST=0;
private String createNewFile()
{
String dirctory = Environment.getExternalStorageDirectory()+"/"+"test";
File f = new File(dirctory);
boolean isdirectory;
if(!f.isDirectory())
{
isdirectory = f.mkdir();
}else
{
isdirectory = true;
}
if(isdirectory)
{
dirctory = dirctory +"/"+Calendar.getInstance().getTimeInMillis()+"captureImage.jpg";
f = new File(dirctory);
if(f.isFile())
f.delete();
try {
f.createNewFile();
return dirctory;
} catch (Exception e) {
Utility.Toast(mActivity, "Unable to create File");
e.printStackTrace();
}
}else
{
Utiity.Toast(AgentSignUp.this, "Unable to create Directory");
}
return dirctory;
}
Step 2: fire intent:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
file_image = createNewFile();
if(file_image!=null)
{
File file = new File(file_image);
Uri outputFileUri = Uri.fromFile( file );
cameraIntent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );
}
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
step 3: recieve in onActivity Result (check for sucess and failure)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode==RESULT_OK)
{
if(requestCode==CAMERA_PIC_REQUEST)
{
File file = new File(file_image);
Uri outputFileUri = Uri.fromFile( file );
doCrop(outputFileUri);// send to cropper or you can use this uri for upper code to get two size of images
}
}
super.onActivityResult(requestCode, resultCode, data);
}
I want to capture image in low resolution using android camera api but when I captured image it will take default resolution of device camera.So I want to capture image in low resolution or small size at time of capture or how can I compress big image into small size in android?
You can create bitmap with captured image as below:
Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);
Here you can specify width and height of the bitmap that you want to set to your ImageView. The height and width you can set according to the screen dpi of the device also, by reading the screen dpi of different devices programmatically.
Use Compressor (Image compression library).
Visit zetbaitsu/Compressor for code and documentation.
add dependency in gradle (app level)
dependencies {
implementation 'id.zelory:compressor:3.0.0'
}
To Compress Image use one of these approaches:
Compress Image File:
val compressedImageFile = Compressor.compress(context, actualImageFile)
Compress Image File to Bitmap:
val compressedImageFile = Compressor.compress(context, actualImageFile)
val bitmap = BitmapFactory.decodeFile(compressedImageFile.path)
Try this is working great with me.
private String decodeFile(String path) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
if (!(unscaledBitmap.getWidth() <= 800 && unscaledBitmap.getHeight() <= 800)) {
// Part 2: Scale image
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
} else {
unscaledBitmap.recycle();
return path;
}
// Store to tmp file
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr + "/myTmpDir");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = "tmp.png";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
scaledBitmap.compress(Bitmap.CompressFormat.PNG, 70, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
scaledBitmap.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
Utility Class
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
You can compress image bitmap like this way.
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
Here 100 is quality of image and you can change format of image to get low resolution image.
I think you are asking about Shrinking image size:
public Bitmap ShrinkBitmap(String file, int width, int height)
{
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, 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.decodeFile(file, bmpFactoryOptions);
return bitmap;
}
please have look at compressImage method i have used for compressing image.
public static String compressImage(String imageUri, Activity activity) {
String filename = "";
try {
String filePath = getRealPathFromURI(imageUri, activity);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(filePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas;
if (scaledBitmap != null) {
canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
}
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
if (scaledBitmap != null) {
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
}
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out;
filename = getFilename(activity);
try {
out = new FileOutputStream(filename);
if (scaledBitmap != null) {
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
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;
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
private static String getRealPathFromURI(String contentURI, Activity activity) {
Uri contentUri = Uri.parse(contentURI);
Cursor cursor = activity.getContentResolver().query(contentUri, null, null, null, null);
if (cursor == null) {
return contentUri.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
You can use this awesome library to compress.
Add dependency in app-level gradel:
dependencies {
implementation 'id.zelory:compressor:3.0.0'
}
And then just compress the actual image file like this:
val compressedImageFile = Compressor.compress(context, actualImageFile)
You should use Googles native image format WebP, it will shrink the image without losing quality. You can compress 80% of the picture without losing quality.
You can use CompressFormat.WEBP to encode any bitmap in WEBP format.
Example from file:
const int quality = 100;
FileOutputStream out = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.WEBP, quality, out);
out.close();
Try this one:
byte[] data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
data = baos.toByteArray();
i resolve this problem in this way, later i will improve the code
protected Void doInBackground(byte[]... data) {
FileOutputStream outStream = null;
// Write to Internal Storage
try {
File dir = new File (context.getFilesDir());
dir.mkdirs();
String fileName ="image.jpg";
File outFile = new File(dir, fileName);
outFile.setExecutable(true, false);
outFile.setWritable(true, false);
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
outStream.flush();
outStream.close();
InputStream in = new FileInputStream(context.getFilesDir()+"image.jpg");
Bitmap bm2 = BitmapFactory.decodeStream(in);
OutputStream stream = new FileOutputStream(String.valueOf(context.getFilesDir()+pathImage+"/"+idPicture+".jpg"));
bm2.compress(Bitmap.CompressFormat.JPEG, 50, stream);
stream.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
use this class to compress image
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.net.Uri
import android.os.Environment
import java.io.*
class ImageFile(val uri: Uri, name: String) {
val filename: String
init {
val file = File(Environment.getExternalStorageDirectory().toString() + "/Documents")
if (!file.exists()) {
file.mkdirs()
}
val fileNoMedia = File(file.absolutePath + "/.nomedia")
if (!fileNoMedia.exists())
fileNoMedia.createNewFile()
if (name.toLowerCase().endsWith(".pdf")) {
filename = file.absolutePath + "/" + System.currentTimeMillis() + ".pdf"
} else {
filename = file.absolutePath + "/" + System.currentTimeMillis() + ".jpg"
}
}
#Throws(IOException::class)
fun copyFileStream(context: Context, uri: Uri): String {
if (filename.endsWith(".pdf") || filename.endsWith(".PDF")) {
var ins: InputStream? = null
var os: OutputStream? = null
try {
ins = context.getContentResolver().openInputStream(uri)
os = FileOutputStream(filename)
val buffer = ByteArray(1024)
var length: Int = ins.read(buffer)
while (length > 0) {
os.write(buffer, 0, length);
length = ins.read(buffer)
}
} catch (e: Exception) {
e.printStackTrace();
} finally {
ins?.close()
os?.close()
}
} else {
var ins: InputStream? = null
var os: OutputStream? = null
try {
ins = context.getContentResolver().openInputStream(uri)
var scaledBitmap: Bitmap? = null
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
var bmp = BitmapFactory.decodeStream(ins, null, options)
var actualHeight = options.outHeight
var actualWidth = options.outWidth
// max Height and width values of the compressed image is taken as 816x612
val maxHeight = 816.0f
val maxWidth = 612.0f
var imgRatio = (actualWidth / actualHeight).toFloat()
val maxRatio = maxWidth / maxHeight
// width and height values are set maintaining the aspect ratio of the image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight
actualWidth = (imgRatio * actualWidth).toInt()
actualHeight = maxHeight.toInt()
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth
actualHeight = (imgRatio * actualHeight).toInt()
actualWidth = maxWidth.toInt()
} else {
actualHeight = maxHeight.toInt()
actualWidth = maxWidth.toInt()
}
}
// setting inSampleSize value allows to load a scaled down version of the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight)
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false
// this options allow android to claim the bitmap memory if it runs low on memory
options.inPurgeable = true
options.inInputShareable = true
options.inTempStorage = ByteArray(16 * 1024)
try {
// load the bitmap from its path
ins.close()
ins = context.getContentResolver().openInputStream(uri)
bmp = BitmapFactory.decodeStream(ins, null, options)
} catch (exception: OutOfMemoryError) {
exception.printStackTrace()
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888)
} catch (exception: OutOfMemoryError) {
exception.printStackTrace()
}
val ratioX = actualWidth / options.outWidth.toFloat()
val ratioY = actualHeight / options.outHeight.toFloat()
val middleX = actualWidth / 2.0f
val middleY = actualHeight / 2.0f
val scaleMatrix = Matrix()
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)
val canvas = Canvas(scaledBitmap!!)
canvas.matrix = scaleMatrix
canvas.drawBitmap(bmp, middleX - bmp.width / 2, middleY - bmp.height / 2, Paint(Paint.FILTER_BITMAP_FLAG))
os = FileOutputStream(filename)
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, os)
val buffer = ByteArray(1024)
var length: Int = ins.read(buffer)
while (length > 0) {
os.write(buffer, 0, length);
length = ins.read(buffer)
}
} catch (e: Exception) {
e.printStackTrace();
} finally {
ins?.close()
os?.close()
}
}
return filename
}
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
}
val totalPixels = (width * height).toFloat()
val totalReqPixelsCap = (reqWidth * reqHeight * 2).toFloat()
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++
}
return inSampleSize
}
}
https://lalitjadav007.blogspot.in/2017/08/compress-image-in-android.html
You can try this code
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* #param res The resources object containing the image data
* #param resId The resource id of the image data
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* #param unscaledBitmap Bitmap to scale
* #param dstWidth Wanted width of destination bitmap
* #param dstHeight Wanted height of destination bitmap
* #param scalingLogic Logic to use to avoid image stretching
* #return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* #param srcWidth Width of source image
* #param srcHeight Height of source image
* #param dstWidth Width of destination area
* #param dstHeight Height of destination area
* #param scalingLogic Logic to use to avoid image stretching
* #return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
public static String decodeFile(String path,int DESIREDWIDTH, int DESIREDHEIGHT, int type) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
Bitmap rotated = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
// if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
// // Part 2: Scale image
// scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
// } else {
// unscaledBitmap.recycle();
// return path;
// }
// Store to tmp file
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr + com.vt.vsmart.utils.Config.SD_PATH+"/image");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = type+"temp.jpg";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 95, fos);
// quay anh 90 do
Matrix matrix = new Matrix();
matrix.postRotate(90);
rotated = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
rotated.compress(Bitmap.CompressFormat.JPEG, 95, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// scaledBitmap.recycle();
rotated.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
// check anh bi quay
public int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
// Log.i("RotateImage", "Exif orientation: " + orientation);
// Log.i("RotateImage", "Rotate value: " + rotate);
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
}
It work for me. I hope it can hepl you!
Try this Method,this will convert your Image file to compressed format,and you can customized the compress level by varrying the value of x & y in the code(Indicated in comment line)
File mImageFile = saveBitmapToFile(ImageFile);
public File saveBitmapToFile(File file){
try {
// BitmapFactory options to downsize the image
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inSampleSize = 6;
// factor of downsizing the image
FileInputStream inputStream = new FileInputStream(file);
//Bitmap selectedBitmap = null;
BitmapFactory.decodeStream(inputStream, null, o);
inputStream.close();
// The new size we want to scale to
final int REQUIRED_SIZE=200; // x............
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
inputStream = new FileInputStream(file);
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
// here i override the original image file
File outPutFile = File.createTempFile("abc","image");
FileOutputStream outputStream = new FileOutputStream(outPutFile);
// y.......
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 95 , outputStream);
return outPutFile;
} catch (Exception e) {
return null;
}
}
Thanks