I am using volley library and displaying image successfully. I want to get same downloaded image from cache . This is my code :
private Bitmap getBitmapFromUrl(String url){
String str = "" ;
Bitmap bitmap = null ;
byte[] bytes = null ;
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Entry entry = cache.get(url);
try {
str = new String(entry.data, "UTF-8");
bytes = str.getBytes("UTF_8") ;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeByteArray( bytes, 0,bytes.length,options);
Log.i(PostItemAdapter.class.getSimpleName(), bitmap+"");
return bitmap ;
}
My issue is that the bitmap object is null .
Can any one tell me why ? thanks in advance .
My problem solved using the aid of this great link where I copied the three files in their images package :
DiskLruImageCache
ImageCacheManager
BitmapLruImageCache
Also I copied RequestManager file. Also there was an issue faced me in the DiskLruImageCache when creating the key from the URL, and I solved this by replacing few lines in this file.
The solution
-old code:
First
#Override
public Bitmap getBitmap( String key ) {
Bitmap bitmap = null;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get( key );
....... etc
Second
#Override
public void putBitmap( String key, Bitmap data ) {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit( key );
......etc
-new code:
First
#Override
public Bitmap getBitmap( String key ) {
Bitmap bitmap = null;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get( ImageCacheManager.getInstance().createKey(key) );
....etc
Second
#Override
public void putBitmap( String key, Bitmap data ) {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit( ImageCacheManager.getInstance().createKey(key) );
.....etc
Note : All this modification in DiskLruImageCache , Beside the caching you can save images to SD Card by this function :
private void saveImageToSD(Bitmap bmp) {
bytes = new ByteArrayOutputStream();
bmp.compress(mCompressFormat, 90, bytes);
file = new File(Environment.getExternalStorageDirectory()+File.separator+"myImage"+(++i)+".jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
/*--- create a new FileOutputStream and write bytes to file ---*/
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bytes.toByteArray());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
And calling to this function be inside the getBitmap(String URL) function witch inside the DiskLruImageCache file .
Related
I am new to android. I am getting one issue as passing my image as binary in api using retrofit but while getting same binary string of image in response not able to convert binary string to Bitmap again. Below i am passing the binary string getting in response. Its a great help if anyone can help me.
"????\u0000\u0010JFIF\u0000\u0001\u0001\u0000\u0000H\u0000H\u0000\u0000??\u0000\u0011\b\u0002X\u0002?\u0003\u0001\"\u0000\u0002\u0011\u0001\u0003\u0011\u0001??\u0000\u001f\u0000\u0000\u0001\u0005\u0001\u0001\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b??\u0000?\u0010\u0000\u0002\u0001\u0003\u0003\u0002\u0004\u0003\u0005\u0005\u0004\u0004\u0000\u0000\u0001}\u0001\u0002\u0003\u0000\u0004\u0011\u0005\u0012!1A\u0006\u0013Qa\u0007\"q\u00142???\b#B??\u0015R??$3br?\t\n\u0016\u0017\u0018\u0019\u001a%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz???????????????????????????????????????????????????????????????????????????\u0000\u001f\u0001\u0000\u0003\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b??\u0000?\u0011\u0000\u0002\u0001\u0002\u0004\u0004\u0003\u0004\u0007\u0005\u0004\u0004\u0000\u0001\u0002w\u0000\u0001\u0002\u0003\u0011\u0004\u0005!1\u0006\u0012AQ\u0007aq\u0013\"2?\b\u0014B????\t#3R?\u0015br?\n\u0016$4?%?\u0017\u0018\u0019\u001a&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
use this code,
String dataValue="";
byte[] bytes = dataValue.getBytes();
Bitmap bmp= BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Try with this.
You can write the byte array directly to file and do whatever you want with the file:
public void writeToFile(byte[] data, String fileName) throws IOException{
FileOutputStream out = new FileOutputStream(fileName);
out.write(data);
out.close();
}
Also if you have binary stream instance, you can create a bitmap instance directly from the stream, you can use BitmapFactory and convert to bitmap:
Bitmap image = BitmapFactory.decodeStream(stream);
You can download the image file using the following function, where body is retrofit2.0 responsebody instance:
private void DownloadImage(ResponseBody body) {
try {
InputStream in = null;
FileOutputStream out = null;
try {
in = body.byteStream();
out = new FileOutputStream("/sdcardpath" + "imagefilename.jpg");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
My Objective is:
Need to get image path from api call in url string like: "http://serverpath.com/projectname/images/imagename.png"
Need to send image path to api call in file object.
So I am taking ArrayList only.
I should show image path in imageview when its converted into file object.
I am trying with some solutions with different file object are:
File f=null;
URL url = new URL(info4Model.getExternal_photos().get(position).getImage_path());
try {
// f = new File(url.toURI());//java.lang.IllegalArgumentException: Expected file scheme in URI:
//f = new File(url.getPath());// not showing file object in imageview
//f = new File(url.getFile());// not showing file object in imageview
f = getFileFromBitmap(info4Model.getExternal_photos().get(position).getImage_path());
//android.os.NetworkOnMainThreadException , AsyncTask option left only?
} catch (Exception e) {
}
///////////////////////////////////
public static Bitmap getBitmapFromURL(String url) {
try {
URL url1 = new URL(url);
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmapFrmUrl = BitmapFactory.decodeStream(input);
return bitmapFrmUrl;
} catch (IOException e) {
e.printStackTrace();
return null;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
File getFileFromBitmap(String url) {
Bitmap bmp = getBitmapFromURL(url);
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("MMddhhmmss");
String dateAsString = simpleDateFormat.format(new Date());
File filesDir = getActivity().getFilesDir();
File imageFile = new File(filesDir, dateAsString + ".png");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
return imageFile;
}
Here all the file objects are showing failure results in comments after the statement.
If u get the image url..from api...
Then,
Uae picasso for loading ur image into imageview like..
Picasso.with(acticityname.this)
.load("YOUR IMAGE URL HERE")
.into(imageView);
And
For api to load your image path..
You have to use multipart..
For that..
File file= new File(ur image path);
FileBody a1=new FileBody(file);
MultipartEntity mpEntity = new MultipartEntity(); mpEntity.addPart("param name", a1);
Hope,you may get help with this.
public class FileModel {
File Url;
File path;
File file;
File bitMap;
public File getUrl() {
return Url;
}
public void setUrl(File url) {
Url = url;
}
public File getPath() {
return path;
}
public void setPath(File path) {
this.path = path;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public File getBitMap() {
return bitMap;
}
public void setBitMap(File bitMap) {
this.bitMap = bitMap;
}
}
ArrayList<FileModel> fileArrayList = new ArrayList<>();
FileModel fileModel = new FileModel();
File f=null;
URL url = new URL(info4Model.getExternal_photos().get(position).getImage_path());
try {
f = new File(url.toURI());//java.lang.IllegalArgumentException: Expected file scheme in URI:
fileModel.setUrl(f);
f = new File(url.getPath());// not showing file object in imageview
fileModel.setPath(f);
f = new File(url.getFile());// not showing file object in imageview
fileModel.setFile(f);
f = getFileFromBitmap(info4Model.getExternal_photos().get(position).getImage_path());
fileModel.setBitMap(f);
//android.os.NetworkOnMainThreadException , AsyncTask option left only?
} catch (Exception e) {
e.printStackTrace();
}
fileArrayList.add(fileModel);
finally File arraylist is ready to use.
I hope it's helpful for you ,,,!
How to load image from URL and save that on memory of device in android? Dont say me use Picasso or oser laibrary.
I need to:
If device get internet conection I load image to ImageView from url and save it on memory of device, else I need to load one of save image to imageView. Thank`s for helps
P.S. Sorry me, I can make some mistakes in question because I don`t very good know English.
This my class:
public class ImageManager {
String file_path;
Bitmap bitmap = null;
public Bitmap donwoaledImageFromSD() {
File image = new File(Environment.getExternalStorageDirectory().getPath(),file_path);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(),bmOptions);
return bitmap;
}
private void savebitmap() {
File file = new File("first");
file_path = file.getAbsolutePath();
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90,fileOutputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public void fetchImage(final String url, final ImageView iView) {
new AsyncTask<String, Void, Bitmap>() {
protected Bitmap doInBackground(String... iUrl) {
try {
InputStream in = new URL(url).openStream();
bitmap = BitmapFactory.decodeStream(in);
savebitmap();
} catch (Exception e) {
donwoaledImageFromSD();
}
return bitmap;
}
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (iView != null) {
iView.setImageBitmap(result);
}
}
}.execute(url);
}
}
Try to use this code:
Method for loading image from imageUrl
public Bitmap getBitmapFromURL(String imageUrl) {
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
Bitmap imageBitmap = BitmapFactory.decodeStream(inputStream);
return imageBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
And You should use it in a separate thread, like that:
new Thread(new Runnable() {
#Override
public void run() {
try {
Bitmap bitmap = getBitmapFromURL(<URL of your image>);
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
}
}).start();
But using Picasso - indeed a better way.
Update:
For saving Bitmap to file on external storage (SD card) You can use method like this:
public static void writeBitmapToSD(String aFileName, Bitmap aBitmap) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return;
}
File sdPath = Environment.getExternalStorageDirectory();
File sdFile = new File(sdPath, aFileName);
if (sdFile.exists()) {
sdFile.delete ();
}
try {
FileOutputStream out = new FileOutputStream(sdFile);
aBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
}
}
Remember that You need
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
for it.
And for loading `Bitmap` from file on external storage You can use method like that:
public static Bitmap loadImageFromSD(String aFileName) {
Bitmap result = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
try {
FileInputStream fis = new FileInputStream(new File(Environment.getExternalStorageDirectory(), aFileName));
result = BitmapFactory.decodeStream(fis);
fis.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "loadImageFromSD: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
You need
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
to do this.
Update 2
Method getBitmapFromURL(), but ImageView should be updated from UI thread, so You should call getBitmapFromURL(), for example, this way:
new Thread(new Runnable() {
#Override
public void run() {
try {
final Bitmap bitmap = getBitmapFromURL("<your_image_URL>");
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
}
}).start();
I had this same issue and I hope this helps. First, To download Image from URL into your app, use the code below:
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
In order for the image to be displayed inside the app, use the method below in your onCreate method:
new DownloadImageTask((ImageView) -your imageview id-)
.execute(-your URL-);
In order for the image to be saved INTERNALLY inside the app/phone, use the code below:
#SuppressLint("WrongThread")
protected void onPostExecute(Bitmap result) {
if (result != null) {
File dir = new File(peekAvailableContext().getFilesDir(), "MyImages");
if(!dir.exists()){
dir.mkdir();
}
File destination = new File(dir, "image.jpg");
try {
destination.createNewFile();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.PNG, 0, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(destination);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
bmImage.setImageBitmap(result);
}
}
To load the image from the internal storage, use the code below:
private void loadImageFromStorage(String path)
{
try {
File f=new File(path, "image.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
ImageView img=(ImageView)findViewById(R.id.businessCard_iv);
img.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
Things to note: 1. path is the a string containing the path of the file. 2. "image.jpg" is the file name so ensure that matches with yours. 3. "MyImages" is a folder in your path which contains the actual saved image.
i am using this method to get images from url and i am downloading more than one image the varable below called "name" is an array of names of the images .i want to be able to store all images whos name is in the array thats why i kept the url like that.it seems to work well but i have having problem selecting only one picture out or them.
this is the code to save images
String fileName="code";
try {
URL url = new URL("http://10.0.2.2/picure/"+name+".jpg");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
Bitmap bm = BitmapFactory.decodeStream(is);
FileOutputStream fos = getActivity().openFileOutput(fileName, Context.MODE_PRIVATE);
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, outstream);
byte[] byteArray = outstream.toByteArray();
fos.write(byteArray);
fos.close();
Toast.makeText(getActivity()," connected", Toast.LENGTH_LONG).show();
} catch(Exception e) {
}
this is the code to collect images
String path = mContext.getFilesDir().toString();
String fileName = "code";
if (fileName != null && !fileName.equals("")) {
Bitmap bMap = BitmapFactory.decodeFile(path + "/" + fileName);
if (bMap != null) {
category_logo.setImageBitmap(bMap);
}
}
i know the names of the images i saved so how do i select that one specifically
For get all images use a Asynctask, this code can download images in cache directory of the app:
class ImageDownloader extends AsyncTask<String, Void, File> {
String imageurl;
String name;
Context ctx;
public ImageDownloader(Context context, String url, String fileName) {
this.imageurl = url;
this.name = fileName;
this.ctx = context;
}
#Override
protected File doInBackground(String... urls) {
Bitmap mIcon;
File cacheDir = ctx.getCacheDir();
File f = new File(cacheDir, name);
try {
InputStream in = new java.net.URL(imageurl).openStream();
mIcon = BitmapFactory.decodeStream(in);
try {
FileOutputStream out = new FileOutputStream(
f);
mIcon.compress(
Bitmap.CompressFormat.JPEG,
100, out);
out.flush();
out.close();
return f;
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
return null;
}
} catch (Exception e) {
return null;
}
}
#Override
protected void onPostExecute(File result) {
super.onPostExecute(result);
Toast.makeText(ctx," connected " + name, Toast.LENGTH_LONG).show();
}
}
}
For call the asynctask, you need use a FOR for get all names and url of the image:
new ImageDownloader(getBaseContext(),url[i],name[i]).execute();
You can edit the doInBackground with your code, but the HTTPConnection that you use is deprecated in API 22, please use the example above, you can change the directory.
And sorry for the code, you can reformat later.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CODE_MULTIPLE_IMG_GALLERY && resultCode==RESULT_OK){
ClipData clipData = data.getClipData();
if (clipData!=null){
File folderPath = new File(getIntent().getStringExtra("folderpath"));
for (int i = 0;i< clipData.getItemCount();i++){
ClipData.Item item = clipData.getItemAt(i);
Uri uri = item.getUri();
Bitmap selectedImage = loadFromUri(uri);
File imagePath = new File(folderPath,System.currentTimeMillis()+".jpg");
try {
outputStream = new FileOutputStream(imagePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
selectedImage.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
Log.d("uri",uri.toString());
imageModelList.add(new ImageModel(uri.toString()));
}
imagesAdapter.notifyDataSetChanged();
Toast.makeText(ImageDetailActivity.this, "Added Successfully!", Toast.LENGTH_SHORT).show();
}
}
}
public Bitmap loadFromUri(Uri photoUri) {
Bitmap image = null;
try {
// check version of Android on device
if(Build.VERSION.SDK_INT > 27){
// on newer versions of Android, use the new decodeBitmap method
ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), photoUri);
image = ImageDecoder.decodeBitmap(source);
} else {
// support older versions of Android by using getBitmap
image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoUri);
}
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
I am new in Android.
I am downloading images from the internet in the ListView .I getting the url in the file object but when I send it into the Bitmap object the bitmap object is return null means image is not loaded into the bitmap object.please reply me. the code is here:
private Bitmap getBitmap(String url) {
String filename = String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
// here in f i getting image url
// here in bitmap the url is not loaded & get null
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null) return bitmap;
// Nope, have to download it
try {
bitmap =
BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream());
// save bitmap to cache for later
writeFile(bitmap, f);
return bitmap;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
I do not think you are downloading properly the bitmap.
CODE
This is a function I created that will take a url from you and it will return a drawable!
It will save it to a file and get it if it exists
If not, it will download it and return the drawable.
You can easily edit it to save file to your folder instead.
/**
* Pass in an image url to get a drawable object
*
* #return a drawable object
*/
private static Drawable getDrawableFromUrl(final String url) {
String filename = url;
filename = filename.replace("/", "+");
filename = filename.replace(":", "+");
filename = filename.replace("~", "s");
final File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + filename);
boolean exists = file.exists();
if (!exists) {
try {
URL myFileUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
final Bitmap result = BitmapFactory.decodeStream(is);
is.close();
new Thread() {
public void run() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
try {
if (file.createNewFile()){
//
}
else{
//
}
FileOutputStream fo;
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
BitmapDrawable returnResult = new BitmapDrawable(result);
return returnResult;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
else {
return new BitmapDrawable(BitmapFactory.decodeFile(file.toString()));
}
}
Only thing I can think of here is that you're missing INTERNET permission in your manifest.
Try adding <uses-permission android:name="android.permission.INTERNET" /> in your AndroidManifest.xml if it's not there yet