Picasso not loading image from file - java

I really don't know what I am doing wrong.
onPostExecute, the I loaded the ImageView with the file I just created from bitmap:
public class ComicFragment extends Fragment
{
private final static String URL1 = "http://192.168.1.143/jerson/sample_comic.jpg";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_comic, parent, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageview_comic);
Point point = getScreenSize();
new DownloadImageTask(getActivity(), imageView, point.x, point.y).execute(URL1);
//Uri uri = Uri.parse("http://192.168.1.143/jerson/sample_comic.jpg");
//simpleDraweeView.setImageURI(uri);
return view;
}
private Point getScreenSize()
{
Point point = new Point();
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
display.getSize(point);
return point;
}
private byte [] getBitmapByteArray(Bitmap bitmap)
{
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
return buffer.array();
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// From https://developer.android.com/training/displaying-bitmaps/load-bitmap.html#read-bitmap
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
private Context context;
private int viewWidth;
private int viewHeight;
private ImageView canvas;
public DownloadImageTask(Context context, ImageView view, int viewWidth, int viewHeight)
{
this.context = context;
this.viewWidth = viewWidth;
this.viewHeight = viewHeight;
canvas = view;
}
#Override
protected Bitmap doInBackground(String ... urls)
{
String url = urls[0];
Bitmap comicBitmap = null;
FileOutputStream out = null;
File root = Environment.getExternalStorageDirectory();
File directory = new File(root.getAbsolutePath() + "/DCIM/tmpimg/cached/");
directory.mkdirs();
File file = new File(directory, "tmp.png");
try
{
InputStream forGettingSizeOnly = new BufferedInputStream(new URL(url).openStream());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(forGettingSizeOnly, null, options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
options.inSampleSize = calculateInSampleSize(options, viewWidth, viewHeight);
options.inJustDecodeBounds = false;
// Make this not load another image from network the second time...
InputStream actualImage = new BufferedInputStream(new URL(url).openStream());
Bitmap decodedImage = BitmapFactory.decodeStream(actualImage);
out = new FileOutputStream(file);
comicBitmap = Bitmap.createBitmap(decodedImage, 0, 0, outWidth, 400);
comicBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
Log.i(ComicApplication.TAG, "****File saved at : " + file.getAbsolutePath() + "WxH" + outWidth + " x " + comicBitmap.getHeight());
}
catch(Exception e)
{
e.printStackTrace();
Log.i(ComicApplication.TAG, "ERROR : " + e.getMessage());
}
return comicBitmap;
}
#Override
protected void onPostExecute(Bitmap result)
{
File root = Environment.getExternalStorageDirectory();
File file = new File(root.getAbsolutePath() + "/DCIM/tmpimg/cached/tmp/tmp.png");
Picasso.with(context).load(file).into(canvas);
Log.i(ComicApplication.TAG, "FILE LOADED FROM : " + file.getAbsolutePath());
}
}
}
I am able to see the tmp.png from the phone's image viewer. I am not receiving any exceptions, error, whatsoever from Picasso's end?
Can someone help me out on why is Picasso not loading my image from file?

first, make sure that you are giving Picasso the correct file path,
then you have to add the permission of READ_EXTERNAL_STORAGE in the app Manifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
put this line in the manifest level

Related

Why can't I read files produced by phone main camera, while front camera works

I'm trying to load pictures taken with build-in camera in LG G8 phone.
Code works for front camera, but throws Null Pointer Exception if I switch it to back.
static final int DESIRED_WIDTH = 640;
static final int DESIRED_HIGH = 480;
private Bitmap retrieveBitmap(){
// Get the dimensions of the bitmap
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
//decode only size
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
//returns 0 x 0
int photoW = bitmapOptions.outWidth;
int photoH = bitmapOptions.outHeight;
// Determine how much to scale down the image
float scaleFactor = Math.min( (float) photoW/ (float) DESIRED_WIDTH,
(float) photoH/ (float) DESIRED_HIGH);
// Decode the image file into a Bitmap of given size
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inSampleSize = (int) scaleFactor;
//returns null
Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
return bitmap;
}
Camera app is invoked as in this example using "Save the full-size photo" method. Android reports NullPointerException after first call to BitmapFactory.decodeFile() as if file produced from main camera didn't exist.
E/BitmapFactory: Unable to decode stream: java.lang.NullPointerException
A while ago i too used the guide that you mentioned to be able to use the phone camera to take photos and save them.
The code below activates the phone camera on a button click and allowes both front and back camara to take a photo, then procede to save them. It also displays the photo taken in a ImageView. Hope it helps.
public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
galleryAddPic();
ImageView img = findViewById(R.id.img);
Bitmap bitm = BitmapFactory.decodeFile(mCurrentPhotoPath);
img.setImageBitmap(bitm);
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
public void cameraClick(View v){
dispatchTakePictureIntent();
}
}
Answering my own question:
turns out phone needs some time before large pictures are accessible. Adding a wait loop makes it work:
private Bitmap retrieveBitmap(){
// Get the dimensions of the bitmap
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
//decode only size
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
int i = 0;
while( bitmapOptions.outWidth == 0 && bitmapOptions.outHeight == 0){
//wait for 4 seconds for resource to be available, otherwise fail
try{
wait(1000);
}catch (Exception ex){
ex.printStackTrace();
return null;
}
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
i++;
//give up trying
if( i == 4) break;
}
//returns 0 x 0
int photoW = bitmapOptions.outWidth;
int photoH = bitmapOptions.outHeight;
// Determine how much to scale down the image
float scaleFactor = Math.min( (float) photoW/ (float) DESIRED_WIDTH,
(float) photoH/ (float) DESIRED_HIGH);
// Decode the image file into a Bitmap of given size
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inSampleSize = (int) scaleFactor;
return BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
}

getting a Bitmap from a Uri

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_image);
imageView = (ImageView) findViewById(R.id.imageView);
Intent intent = getIntent();
Uri imageUri = intent.getData();
// Picasso.with(this).load(imageUri).into(imageView);
if(imageUri == null){
Log.d(TAG, "Check");
}
//BitmapFactory.Options options = new BitmapFactory.Options();
// options.inSampleSize = 8;
// bm = MediaStore.Images.Media.getBitmap(getContentResolver(),imageUri);
Bitmap bm = null;
try{
InputStream image;
try{
image = getContentResolver().openInputStream(imageUri);
bm = BitmapFactory.decodeStream(image);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace();
}
//BitmapFactory.Options options = new BitmapFactory.Options();
// bm = BitmapFactory.decodeFile(file.getAbsolutePath(),options);
if ((bm == null)) {
prints("It doesn't work");
}
//Log.d(TAG,"Going to convert image.");
imageView.setImageBitmap(bm);
I've looked at a bunch of StackOverFlow questions, I've tried them all as you can see in the commented code. I'm trying to get a Bitmap that is unchanged when the photo is taken. The pixel position of the Bitmap is crucial for my goal. The image is high quality and maybe a larger file. My Bitmap is always null, I have made sure my Uri isn't. Any ideas?
I think the code below will help you
private void setImage(String path, CircleImageView img) {
options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.showImageOnLoading(R.drawable.user)
.showImageForEmptyUri(R.drawable.user)
.showImageOnFail(R.drawable.user)
.build();
ImageLoader.getInstance().displayImage(path, img, options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
super.onLoadingStarted(imageUri, view);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
super.onLoadingFailed(imageUri, view, failReason);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
super.onLoadingCancelled(imageUri, view);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
}
}, new ImageLoadingProgressListener() {
#Override
public void onProgressUpdate(String s, View view, int i, int i1) {
}
});
}
use universal image loader for SimpleImageLoadingListener()
The file has a too big resolution to make a bitmap out of it. There is not enough memory to construct a bitmap and hence a null is returned.
Try with a very small image file to see.
You can direct get Bitmap from URI if it is from your mobile storage from below code.
public Bitmap getBitmapFromURI(Uri uri){
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
if(cursor!=null){
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
File f_image = new File(cursor.getString(columnIndex));
cursor.close();
BitmapFactory.Options o2 = new BitmapFactory.Options();
return BitmapFactory.decodeFile(f_image.getAbsolutePath(), o2);
}
return null;
}
In case of file is too large to load.. You need to compress image and show. For that you need to use Async Task as well.
I have made one Image compressor task you can use it for large image
public class ConvertBase64Task extends AsyncTask<Void, Bitmap, Bitmap> {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private File file;
private int CompressionRatio = 80; //You can change it by what ever ratio you want. in 0 to 100.
private boolean shouldrotate = true;
private ImageCompressiorListner imageCompressiorListner;
public ConvertBase64Task(File file) {
this.file = file;
}
public void setRotation(boolean isRotate) {
shouldrotate = isRotate;
}
public void setCompressionRatio(int Ratio) {
CompressionRatio = Ratio;
}
public void setImageCompressiorListner(ImageCompressiorListner imageCompressiorListner) {
this.imageCompressiorListner = imageCompressiorListner;
}
#Override
protected void onPreExecute(){
}
#Override
protected Bitmap doInBackground(Void... params) {
try {
//***** Fatching file
//*****Code for Orientation
Matrix matrix = new Matrix();
if (shouldrotate) {
ExifInterface exif1 = new ExifInterface(file.getAbsolutePath());
int orientation = exif1.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
Log.d("EXIF", "Exif: " + orientation);
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
} else {
matrix.postRotate(0);
}
} else {
matrix.postRotate(0);
}
try {
BitmapFactory.Options option = new BitmapFactory.Options();
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), option);
int file_size = Integer.parseInt(String.valueOf(file.length() / 1024));
Log.e("ImageSize", "" + file_size);
int scale = 1;
if (file_size < 512) {
Log.e("image size is good", "image size is less");
} else if (file_size < 1024) {
Log.e("image size is 1 mb", "image size is heavy");
scale = 2;
} else if (file_size < 1536) {
Log.e("image size is 1.5 mb", "image size is heavy");
scale = 2;
} else if (file_size < 2048) {
Log.e("image size is 2 mb", "image size is heavy");
scale = 4;
} else {
Log.e("image size > 2 mb", "image size is heavy");
scale = 4;
}
Log.e("Scale", "Finaly Scaling with " + scale);
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap pickimg = BitmapFactory.decodeFile(file.getAbsolutePath(), o2);
if (pickimg.getWidth() > 1280 || pickimg.getHeight() > 1000) {
int width = pickimg.getWidth();
int height = pickimg.getHeight();
while (width > 1280 || height > 700) {
width = (width * 90) / 100;
height = (height * 90) / 100;
}
pickimg = Bitmap.createScaledBitmap(pickimg, width, height, true);
} else {
pickimg = Bitmap.createBitmap(pickimg, 0, 0, pickimg.getWidth(), pickimg.getHeight(), matrix, true); // rotating bitmap
}
pickimg.compress(Bitmap.CompressFormat.JPEG, CompressionRatio, baos);
return pickimg;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null) {
if(imageCompressiorListner!=null){
imageCompressiorListner.onImageCompressed(result);
}
} else {
if(imageCompressiorListner!=null){
imageCompressiorListner.onError();
}
}
}
public interface ImageCompressiorListner {
void onImageCompressed(Bitmap bitmap);
void onError();
}
}
You can use this as below
ConvertBase64Task task = new ConvertBase64Task(File Object of Image);
task.setImageCompressiorListner(new ConvertBase64Task.ImageCompressiorListner() {
#Override
public void onImageCompressed(Bitmap bitmap) {
}
#Override
public void onError() {
}
});
task.execute();
Hope this will help you out.

android out of memory error after multiple reloads

hey guys having a problem after reloading an activity multiple times i get an out of memory exception and crashes out of the app i am using the developer google documentation example to load multiple images from what i see i have to recycle the bitmap once i am done with it but i am a bit unsure where to do this considering i have multiple bitmaps and calling the bitmap from an external class
Here is my load bitmap class
public class bitmapHTTP{
Context ctx;
private LruCache<String, Bitmap> mMemoryCache;
int iv;
public bitmapHTTP(Context c){
ctx = c;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
#Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if(getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
public void loadBitmap(String resId, ImageView imageView) {
final String imageKey = String.valueOf(resId);
iv = imageView.getWidth();
Bitmap bitmap = getBitmapFromMemCache(imageKey);
if(bitmap != null) {
imageView.setImageBitmap(bitmap);
}else{
if(cancelPotentialWork(imageKey, imageView)){
Bitmap loading = decodeSampledBitmapFromResource(ctx.getResources(), R.drawable.whiteseetrough, imageView.getWidth(), imageView.getWidth());
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
AsyncDrawable asyncDrawable = new AsyncDrawable(ctx.getResources(), loading, task);
imageView.setImageDrawable(asyncDrawable);
task.execute(resId);
}
}
}
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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String data = null;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(String... params) {
data = params[0];
final BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap;
if(data.equals("null")){
bitmap = decodeSampledBitmapFromResource(ctx.getResources(), R.drawable.whiteseetrough, iv, iv);
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
return bitmap;
}else{
bitmap = getBitmapFromMemCache(data);
if(bitmap == null){
// Process as normal
try {
URL url = new URL(data);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
options.inSampleSize = calculateInSampleSize(options, iv, iv);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(input, null, options);
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
return bitmap;
}catch(IOException e){
e.printStackTrace();
return null;
}
}
}
return bitmap;
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
final BitmapWorkerTask bitmapWorkerTask =
getBitmapWorkerTask(imageView);
if (this == bitmapWorkerTask && imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference =
new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
public static boolean cancelPotentialWork(String data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) {
final String bitmapData = bitmapWorkerTask.data;
// If bitmapData is not yet set or it differs from the new data
if(bitmapData == null || bitmapData != data) {
// Cancel previous task
bitmapWorkerTask.cancel(true);
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
}
this is how i call the bitmap to load to an imageView
bitmapHTTP getBitmap = new bitmapHTTP(this);
getBitmap.loadBitmap(imageUrl, 1), imageView1);
getBitmap.loadBitmap(imageUrl, 1), imageView2);
getBitmap.loadBitmap(imageUrl, 1), imageView3);
Thats a lot of code. Quickly I would ask: Are you recycling your bitmaps after not needing them? Bitmaps need to be recycled and RAM released especially when loading them via loops and the like and keeping references to them.
Check your code to make sure you recycling properly. I didn't see anything of the kind (releasing the reference is not enough if you want to do a low of bitmaping).
Also, keep in mind that you need to make sure your bitmaps are loaded in properly in available memory and resized so that they don't kill the memory. I believe you are doing it somewhere in there.

Compress Image cause Error in Android

While clicking photo from smartphone, the image size is too large that it takes minute to upload so I want to reduce image size without affecting too much on its quality. So I got code from this website link. But while adding code in my existing code there are some compiler errors which are fixed.
Below errors are under compressImage(String imageUri) function
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Error is: cannot resolve mrthod 'setScale(float,float,float)'
canvas.setMatrix(scaleMatrix);
Error is: setMatrix (android.graphics.Matrix) in Canvas cannot be applied to (android.opengl.Matrix)
matrix.postRotate(90);
matrix.postRotate(180);
matrix.postRotate(270);
Error is: cannot resolve method 'postRotate(int)'
Code:
public class Camera extends AppCompatActivity implements View.OnClickListener {
public static final String UPLOAD_URL = "http://website.com/ImageUpload/upload.php";
public static final String UPLOAD_KEY = "image";
public static final String UPLOAD_NAME = "name";
public static final String UPLOAD_EMAIL = "email";
public static final String UPLOAD_PHONE= "phone";
public static final String TAG = "MY MESSAGE";
boolean b=false,z;
private int PICK_IMAGE_REQUEST = 1;
String mock;
private Button buttonChoose;
String uploadImage;
private Button buttonUpload,buttonView;
private ImageView imageView;
private Bitmap bitmap,bitmaps;
private Uri filePath;
String path;
String[] max;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
buttonChoose = (Button) findViewById(R.id.buttonChoose);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
buttonView = (Button) findViewById(R.id.buttonViewImage);
buttonUpload.setEnabled(false);
imageView = (ImageView) findViewById(R.id.imageView);
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
buttonView.setOnClickListener(this);
/* GetSet b= new GetSet();
String maths=b.getCombine();
*/
// System.out.println("Matru "+maths);
Bundle bundle = getIntent().getExtras();
//Extract the data…
String stuff = bundle.getString("combine_data");
// String sss = bundle.getString("combine_data2");
System.out.println("changa " + stuff);
max=stuff.split("~");
for(int i=0;i<max.length;i++)
System.out.println("binku " + max[i]);
}
private void selectImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
}
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(b) {
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
buttonUpload.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
else {
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmaps = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);
imageView.setImageBitmap(bitmaps);
buttonUpload.setEnabled(true);
mock= getStringImage(bitmaps);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public String getStringImage(Bitmap bmp){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
private void uploadImage(){
class UploadImage extends AsyncTask<Bitmap,Void,String>{
ProgressDialog loading;
RequestHandler rh = new RequestHandler();
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(Camera.this, "Uploading Image", "Please wait...",true,true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
imageView.setImageDrawable(null);
buttonUpload.setEnabled(false);
}
#Override
protected String doInBackground(Bitmap... params) {
Bitmap bitmap = params[0];
if(z)
uploadImage = getStringImage(bitmap);
else
uploadImage = mock;
String compress_image=compressImage(uploadImage);
HashMap<String,String> data = new HashMap<>();
data.put(UPLOAD_KEY, compress_image);
data.put(UPLOAD_NAME,max[0]);
data.put(UPLOAD_EMAIL,max[2]);
data.put(UPLOAD_PHONE,max[1]);
String result = rh.sendPostRequest(UPLOAD_URL,data);
return result;
}
}
UploadImage ui = new UploadImage();
ui.execute(bitmap);
}
public String compressImage(String imageUri) {
path = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as 816x612
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float 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 = (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;
}
}
// 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 = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(path, 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 = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
String filename = getFilename();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filename;
}
private String getRealPathFromURI(String contentURI) {
Uri contentUri = Uri.parse(contentURI);
Cursor cursor = getContentResolver().query(contentUri, null, null, null, null);
if (cursor == null) {
return contentUri.getPath();
} else {
cursor.moveToFirst();
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(index);
}
}
public 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;
}
public String getFilename() {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
return uriSting;
}
#Override
public void onClick(View v) {
if (v == buttonChoose) {
b=true;
z=true;
showFileChooser();
}
if(v == buttonUpload) {
uploadImage();
}
if(v == buttonView){
b=false;
z=false;
selectImage();
}
}
}
I think if you reduce the bitmap size then may be you can solve this-
public static Bitmap getBitmapFromByteArray(final byte data[], int maxSize) {
final int MAX_SIZE = maxSize;
if (data.length > 0) {
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length, options);
final int fullWidth = options.outWidth;
final int fullHeight = options.outHeight;
int w = 0;
int h = 0;
if (fullWidth > fullHeight) {
w = MAX_SIZE;
h = w * fullHeight / fullWidth;
} else {
h = MAX_SIZE;
w = h * fullWidth / fullHeight;
}
options.inJustDecodeBounds = false;
options.inSampleSize = fullWidth / w;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
options);
return bitmap;
} catch (final Exception e) {
}
}
return null;
}
You will send the current bitmap ByteArray data with size which you want from this bitmap. Then it will return the bitmap by resize. You can try this.
It can be done by two ways i.e degrade quality of jpeg or resizing the image .
Resizing the image
Bitmap mBitmap = Bitmap.createScaledBitmap(bitmap, 480, 300, true);
Reduce quality of jpeg
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outFile);

In Android ListView what is this the proper way to load rounded images along with text?

I am trying to create a ListView which contains a simple rounded image and textView along with it ,to achive rounded image i have created a function to make it round and since i get the image url from json object as httpurl i have used another function to get bitmap from it.. but looks something is seriously wrong because the ListView is taking too long to load and its even freezing when i scroll.
public class MyImageListAdapter extends ArrayAdapter {
private final Context context;
private final ArrayList<UserInfo> values;
String mother_name;
String mother_image;
public MyImageListAdapter(Activity atvt, Context context,
ArrayList<UserInfo> values) {
super(context, R.layout.my_list, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.image_name_fragment, parent,
false);
TextView textView = (TextView) rowView.findViewById(R.id.firstLine);
ImageView imageView = (ImageView) rowView
.findViewById(R.id.profileImage);
textView.setText(((UserInfo) values.get(position)).getUserName());
String motherImageURl = ((UserInfo) values.get(position))
.getPrifileImageUr();
mother_name = ((UserInfo) values.get(position)).getUserName();
mother_image = motherImageURl;
Bitmap bm = getBitmapFromHttpURL(motherImageURl);
Bitmap bm1 = getRoundedCornerBitmapWithBorderSmall(bm, 2);
imageView.setImageBitmap(bm1);
rowView.setPadding(5, 10, 5, 10);
return rowView;
}
public static Bitmap getBitmapFromHttpURL(String src) {
Bitmap bitmap = null;
AsyncTask<String, Void, Bitmap> ac = new AsyncTask<String, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
myBitmap = Bitmap.createScaledBitmap(myBitmap, 200, 200,
true);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
try {
bitmap = ac.execute(src).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// bitmap = Bitmap.createScaledBitmap(bitmap,200,200, true);
return bitmap;
}
public static Bitmap getRoundedCornerBitmapWithBorderSmall(Bitmap bitmap,
int border) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// if(w>50 || h>50){w=50;h=50;}
int a, b;
System.out.println("-------" + bitmap.getByteCount() + "--" + h + "---"
+ w);
int radius = Math.min(h / 2, w / 2);
a = Math.max(w, h);
Bitmap output = Bitmap.createBitmap(a, a, Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
p.setStyle(Style.FILL);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
c.drawBitmap(bitmap, 4, 4, p);
p.setXfermode(null);
p.setStyle(Style.STROKE);
p.setColor(Color.parseColor("#61445C"));
p.setStrokeWidth(border);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
// output = Bitmap.createScaledBitmap(output, 200, 200, true);
// output=getResizedBitmap(output, 200,200) ;
// Bitmap yourBitmap;
output = Bitmap.createScaledBitmap(output, 100, 100, true);
return output;
}
}
You can use Picasso library for loading images directly from URL with single line of code.
For making image rounded corner you can refer my answer How to create round corner image using volley library android
And also one suggestion for your networking, use Volley library for it . It is for faster and better networking.

Categories