I am trying to load the thumbnails for videos in a file browser but its causing me to run out of memory.
public class Filea {
private Bitmap VideoIcon;
public Bitmap getVideoIcon() {
return VideoIcon;
}
public void setVideoIcon(Bitmap videoIcon) {
VideoIcon = videoIcon;
}
This is being done for every video file that is in a folder.
Every time that I load a new folder does it keep the information from the previous folder, and if so how do i get it to delete the unwanted resources?
private List<Filea> LoadFiles(String dirPath) {
inSearch = false;
List<Filea> files = new ArrayList<Filea>();
try {
for(String F:EditedFileList(current)) {
Filea file = new Filea();
file.setVideoIcon(ThumbnailUtils.createVideoThumbnail(current + "/" + getName(F), MediaStore.Images.Thumbnails.MINI_KIND));
files.add(file);
}
} catch (NullPointerException e) {
e.getStackTrace();
} catch (NoSuchElementException e) {
Log.i("LoadFiles", "No files found");
}
return files;
}
This is how the information is obtained.
Along with the video thumbnails I am loading other bits of data E.g. File name, size, permissions, Image icons(as bitmaps) ect..
Most likely you're keeping around a bunch of unneeded references. My suggestion would be to put the images in an LRUCache and load them from there. That way you can set a reasonable maximum amount of memory to use on images.
I found the problem, i was trying to load the full image of picture instead of the thumbnails.`
file.setImageIcon(ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(current + "/" + getName(F)), 100, 100));
Thank. LukeMovement.
Related
I'm trying to save the frame of the image from the live stream video. So, I'm able to show live stream video from my android application as well as saving it in my local storage. Now, I want to use some sort of delay in my saveImage function so that images get saved after some specific time. I have used both Handler and TimerTask. The image is getting saved in my local directory after some delay but the length of the image that I get is sometimes very small, the other time normal. I want my saved image to exactly the length of the video stream that I am getting in my application.
I hope the question I asked is easy to understand. I am a beginner in both android and stack overflow.
P.S - I used mjpeg library for showing the video. The video I am getting is from an IP Camera.
Code for saving the images
public void saveImage(){
try {
photo =
new File(Environment.getExternalStorageDirectory(),
"Download/photos/photo" + Instant.now().getEpochSecond() + ".jpg");
if (photo.exists()) {
photo.delete();
}
System.out.println("Photo " + photo);
FileOutputStream fos = new FileOutputStream(photo.getPath());
System.out.println("Image_length" +image.length);
fos.write(image);
fos.close();
} catch (IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
Code where saveImage is called
final Bitmap outputImg = BitmapFactory.decodeByteArray(image, 0, image.length);
if (outputImg != null) {
if (run) {
newFrame(outputImg);
// Saving frames in internal Storage
new Timer().schedule(
new TimerTask() {
#Override
public void run() {
saveImage();
}
},5000
);
}
} else {
Log.e(tag, "Read image error");
}
My app can download an image from a raspberry. it works fine. This is the code
public void downloadFile() {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("******");
ftpClient.login("****","*****");
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
String remoteFile1;
File downloadFile1 = new File(filePath);
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
System.out.println("File #1 has been downloaded successfully.");
} else {
System.out.println("Error in downloading file !");
}
boolean logout = ftpClient.logout();
if (logout) {
System.out.println("Connection close...");
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
ftpClient.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And then I can display it so the user of my app can see it. For the image loading, Im using this code and it works too.
private void loadImage(String imagePath) {
Uri imageUri;
String fullImagePath;
Drawable image;
ImageView imageDisplay;
imageUri = Uri.parse(imagePath);
fullImagePath = imageUri.getPath();
image = Drawable.createFromPath(fullImagePath);
imageDisplay=(ImageView) findViewById(R.id.imageDisplay);
imageDisplay.setImageDrawable(image);
}
Now I want to display the image without downloading it in my gallery. But I can't figure out how to do this.
Can someone help me please.
You cannot show an image without download it. Actually when you see something "remotely", you are downloading it.
If you mean that the image is too large and you don't want to download, but want a mechanism for the user can view it. One possible solution is make a thumbnail (reduced image) in server side and show that "preview" to the user. Then if the user want to download it to the gallery you could get the original image.
If you want to display an image without downloading it, it has to be uploaded in a image hosting site or alike so you will just use the link instead of the whole FTP Client.
Basically, you are using a code that is intended for saving an image. And the one you are using for loading the images fetches data from the Drawable. So you are in the wrong path.
I am developing a module for which i want to show all the user's videos from sd card into a Gridview. I have grabbed video file paths in usual way (Checking if file or directory and save if its a file) in a arraylist and grabbed its bitmap thumbnail with following code:
Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(VideoValues.get(position).getAbsolutePath(),
Thumbnails.MINI_KIND);
Obviously this code runs in a background thread. But the only problem is that the gribview still freezes a lot while scrolling. According to me the main problem is extracting the bitmap from video, which takes a lot of time. Can anyone suggest me a different way to get bitmap from video and how it in a grid ? I have seen the smooth behavior in other apps like Facebook, etc. But I cannot figure out as to how that can be done.
please use below method for retrive video thumbnail from video
#SuppressLint("NewApi")
public static Bitmap retriveVideoFrameFromVideo(String videoPath)
throws Throwable
{
Bitmap bitmap = null;
MediaMetadataRetriever mediaMetadataRetriever = null;
try
{
mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(videoPath);
bitmap = mediaMetadataRetriever.getFrameAtTime();
}
catch (Exception e)
{
throw new Throwable(
"Exception in retriveVideoFrameFromVideo(String videoPath)"
+ e.getMessage());
}
finally
{
if (mediaMetadataRetriever != null)
{
mediaMetadataRetriever.release();
}
}
return bitmap;
}
I got this little function that allows me to load an image from a path, named name. It works, the problem is that I have to call this many times, una tantum. Let's say, a dozen of times at the load of a specific activity. It takes few seconds to load them all.
Is it optimal? Is there a lighter way to achieve the same result?
public static Bitmap loadImageFrom(File path, String name)
{
try {
File f = new File(path, name);
return BitmapFactory.decodeStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
I tried adding if(!f.exists()) return null; like this:
public static Bitmap loadImageFrom(File path, String name)
{
try {
File f = new File(path, name);
if(!f.exists()) return null;
return BitmapFactory.decodeStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
I know that is redundant, but I can't remove the Try Catch clause, cause it giving me an error if I do. However, no speed up noticed.
Any suggestion?
It's not that your code is inefficient, as far as I know, loading pictures manually on the main thread will hurt your app's performance. Especially when you have a large amount of pictures and/or using them to populate your ListView or GridView.
Have a look at Picasso or Universal Image Loader, these libraries should help load your pictures efficiently thus speeding up your app.
I need to randomly select an image from a user's photo gallery. I don't mean starting an intent as in
Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(gallery, GALLERY_PHOTO_REQUEST_CODE);
No. I need to randomly select the image myself. Is there an efficient way to do this? Or do I have to actually read in all the image files and then randomly select a file, and then from the file get the image? By read all files, I mean with something as (snippet: I have a question not an answer)
void addFiles(final File parent, Set<File> images) {
try {
for (final File file : parent.listFiles()) {
if (!file.getParent().contains("Android")) {
if (!file.isDirectory()) {
if (isImageFile(file.getName())) {
images.add(file);
}
} else {
addFiles(file, images);
}
}
}
} catch (Exception e) {
}
}
Please don't be too concerned with the code snippet. If I knew the best way, I would not be asking for help. Does anyone know an efficient way of doing this?
I don't know your code aside from the snippets. Unless you have a large number of files, you could very well read all the files into an array. Then generate a random number with 0 as lowest and arrayList.size()-1 as highest and get that index from the array.
Pseudo code:
private static Random random = new Random();
ArrayList<File> list = readFiles();
File randomFile = list.get(getRandomValue(0, list.size()-1));
...
public static int getRandomValue(int low, int high) {
return random.nextInt((high - low) + 1) + low;
}