Are there any Android libraries to resize images and save it in place? I'm using Jetpack Compose and Kotlin in my project. My app has a feature for taking photos and choosing an image from the gallery. And I need to resize the captured or selected image and create their thumbnails. I looked into Picasso, and Glide, etc. But, it seems like they only resize the image in memory for display.
HI You can use Glide for resize,
but again you can use it to save as image too
for eg use this to store in bitmap,
Glide.with(getApplicationContext())
.load("https://i.stack.imgur.com/quwoe.jpg")
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
saveImage(resource);
}
});
//code to save the image
private void saveImage(Bitmap resource) {
String savedImagePath = null;
String imageFileName = "image" + ".jpg";
final File storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Pics");
boolean success = true;
if(!storageDir.exists()){
success = storageDir.mkdirs();
}
if(success){
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
try {
OutputStream fOut = new FileOutputStream(imageFile);
resource.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
// Add the image to the system gallery
galleryAddPic(savedImagePath);
Toast.makeText(this, "IMAGE SAVED", Toast.LENGTH_LONG).show();
}
}
// Add the image to the system gallery
private void galleryAddPic(String imagePath) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imagePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
Resize with glide
save with Glide
Related
i am building a chat application using firebase. I am using Glide to display images
Glide.with(getApplicationContext())
.load(imageUrl)
.crossFade()
.fitCenter()
.placeholder(R.drawable.loading)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
I want to save the images to a specific folder in Internal Storage just like whatsapp does and load images from there after it has been saved.Images are uploaded on Firebase Storage and its URL is saved in Firebase Database and i load them in a imageView with the url using Glide
private static final String IMAGE_DIRECTORY = "/yourfoldername/images";
//this method return your folder image path
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
// glide load image
Glide.with(this)
.load(imageUrl)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
String imagepath = saveImage(resource);
// Parse the gallery image url to uri
Uri savedImageURI = Uri.parse(imagepath);
// Display the saved image to ImageView
iv_saved.setImageURI(savedImageURI);
}
});
I have a custom listview which is working good, now i want to share the image and text from the list. I have found a step how to do it from SO but image is always null when i click on Share button.
The imageview loading images using Glide.
if (!Patterns.WEB_URL.matcher(Limage).matches()) {
viewholder.iview.setVisibility(View.GONE);
} else {
Glide.with(convertView.getContext()).load(Limage).centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL).listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
// viewholder.progress.setVisibility(View.GONE);
return false;
}
}).into(viewholder.iview);
viewholder.iview.setVisibility(View.VISIBLE);
}
I have created a Share button and inside onclick i am passing the below code.
viewholder.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Uri bmpUri = getLocalBitmapUri(viewholder.iview);
if (bmpUri != null) {
// Construct a ShareIntent with link to image
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/*");
// Launch sharing dialog for image
listdisplay.startActivity(Intent.createChooser(shareIntent, "Share Image"));
} else {
// ...sharing failed, handle error
}
}
});
To get image from Imageview i am using the below code.
private Uri getLocalBitmapUri(ImageView iview) {
Drawable drawable = iview.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable){
bmp = ((BitmapDrawable) iview.getDrawable()).getBitmap();
Log.e("Shiva","Came inside drawable");
} else {
Log.e("Shiva","drawable is null"+drawable);
return null;
}
Uri bmpUri = null;
File file = new File(listdisplay.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
// **Warning:** This will fail for API >= 24, use a FileProvider as shown below instead.
return bmpUri;
}
So, what happened now is in the if step where it is checking "drawable instanceof BitmapDrawable" is always returns null. whats wrong here?
Note: Above code are inside the adapter.
You can load image using this :
Glide.with(this)
.load("https://cdn-images-1.medium.com/max/1200/1*hcfIq_37pabmAOnw3rhvGA.png")
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
Log.d("Size ", "width :"+resource.getWidth() + " height :"+resource.getHeight());
imageView.setImageBitmap(resource);
storeImage(resource);
}
});
And store bitmap to external storage and then share it.
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
Log.d(TAG, "img dir: " + pictureFile);
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getApplicationContext().getPackageName()
+ "/Files");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
File mediaFile;
Random generator = new Random();
int n = 1000;
n = generator.nextInt(n);
String mImageName = "Image-"+ n +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
iview.getDrawable() will return null when using Glide.
You can set:
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
viewholder.iview.setDrawable(resource);
return true;
}
then iview.getDrawable() will return drawable
// Pass the Activity Context, ImageView, Image path which is located inside sdcard,And default Image you want to display to
loadImageWithGlide Method.
loadImageWithGlide(this,imageView,imagePath,R.drawable.damaged_image,R.drawable.damaged_image);
// Method to Load Image from Sdcard to ImageView With Using Glide Library
public static void loadImageWithGlide(final Context context, ImageView theImageViewToLoadImage,
String theLoadImagePath, int theDefaultImagePath, int tehErrorImagePath) {
if (context == null) return;
Glide.with(context) //passing context
.load(theLoadImagePath) //passing your url to load image.
.placeholder(theDefaultImagePath) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url.
.error(tehErrorImagePath)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is.
.diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast.
//.animate(R.anim.fade_in) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image.
.fitCenter()//this method help to fit image into center of your ImageView
.into(theImageViewToLoadImage); //pass imageView reference to appear the image.
}
// Bellow is Code to share Image
// Note: The image needed to located inside Sdcard. Pass that path inside Share Method.
public static void share(Context theCtx, String theImagePath, String theText) {
File myImageFile = new File(theImagePath);
String shareBody = theText; //"Here is the share content body " ;
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
if (myImageFile.exists()) {
sharingIntent.setType("image/jpeg");
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + myImageFile.getAbsolutePath()));
} else if (!theText.isEmpty()) {
sharingIntent.setType("text/*");
}
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, ""); //"Subject here"
sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
sharingIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
theCtx.startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
You need to create a cache in memory with your image than you can extract it, otherwise is null, may be destroyed.
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = imageView.getDrawingCache();
I had uploaded the image on Firebase Storage successfully. I have the URI and using Glide, I'm able to show the image on an ImageView. I want to save this image on my SD card but I'm getting an exception
java.io.FileNotFoundException: No content provider:
https://firebasestorage.googleapis.com/..
In here:
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), myUri);
SaveImage(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
Here is my complete code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_pic);
Intent intent = getIntent();
String str = intent.getStringExtra("pic");
Uri myUri = Uri.parse(str);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), myUri);
SaveImage(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
ImageView imageView = (ImageView)findViewById(R.id.displayPic);
Glide.with(getApplicationContext()).load(myUri)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
}
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
URI looks like this:
https://firebasestorage.googleapis.com/example.appspot.com/o/pics%2Fc8742c7e-8f59-4ba3-bf6f-12aadfdf4a.jpg?alt=media&token=9bsdf67d-f623-4bcf-95d7-5ed97ecf1a21
Using Glide Try this.
Bitmap bitmap= Glide.
with(this).
load(mDownloadUrl).
asBitmap().
into(100, 100). // Width and height
get();
SaveImage(bitmap);
where mDownloadUrl is your image URL.
Firebase Storage does not have a registered content resolver. The download Url you get is actually a plain vanilla https:// Url that you can feed into Glide.
You can also download this Url directly. Check out this question.
Just call downloadUri.toString() to get the download Url in string form.
I want to share animated gif images that are in my drawable folder.
The code works so far, but the shared gif file is not animated. You can only see the first image of the animation. Does someone know how it could work?
Bitmap icon = BitmapFactory.decodeResource(this.getResources(),
R.drawable.animated_gif);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/gif");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "temporary_file.gif");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f, true);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
share.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file:///sdcard/temporary_file.gif"));
startActivity(Intent.createChooser(share, "Share Image"));
Well, you are geting static bitmap from drawable. I recomend you to use GifDrawable in Glide library and this approach for sending animated gifs (in case you loaded your gif image into ImageView):
private Uri getLocalBitmapUri(ImageView imageView, String link) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
if (drawable instanceof GifDrawable) {
try {
// Store image to default external storage directory
String fileName = link.substring(link.lastIndexOf('/') + 1, link.length());
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "shared_gif_" + System.currentTimeMillis() + ".gif");
file.getParentFile().mkdirs();
GifDrawable gifDrawable = ((GifDrawable) imageView.getDrawable());
FileOutputStream out = new FileOutputStream(file);
out.write(gifDrawable.getData());
out.close();
return Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
...
Uri bmpUri = Utils.getLocalBitmapUri(gifImageView, post.media_content.get(0).file);
if (bmpUri != null) {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("image/gif");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text");
sharingIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} else {
// ...sharing failed, handle error
}
...
I am using ImageView in my android application here i show the images from webservice so i am using UrlImageViewHelper. i want to store this image into android Gallery files.
my images like:
String Images = dataExtra.get("images").toString();
System.out.println("image URL"+Images);
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(Images);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
i tried like this.. but its not working. Any one can help me how to store these Images into Android Gallery?
i got solution for this problem, Here my answer
private void saveImagesIntoGallery(){
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
// File sdCardDirectory = Environment.getExternalStorageDirectory();// its stores under sdcard not in a specific path
String sdCardDirectory = Environment.getExternalStorageDirectory().toString()+"/Pictures/";
String url = arrayForImages[i].toString();
String file = url.substring(url.lastIndexOf('/')+1);
System.out.println("PATH NAME"+sdCardDirectory);
File image = new File(sdCardDirectory, file);
boolean success = false;
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
/* 100 to keep full quality of the image */
outStream.flush();
outStream.close();
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(getApplicationContext(), "Image saved with success",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_LONG).show();
}
}
Are you sure that the gallery is the best place to store images of webservice?
If you wanted to save to internal storage:
public void saveBitmap(String name, Bitmap bitmap){
if(bitmap!=null && name!=null){
FileOutputStream fos;
if(bitmap!=null){
try {
fos = openFileOutput(name, Context.MODE_PRIVATE);
bitmap.compress(CompressFormat.JPEG, 90, fos);
} catch (FileNotFoundException e) {}
}
}
}
To gallery, i have not examples here. But search a little;)