How to load thumbnails of Pic Clicked via Camera Intent - android

My application takes pictures via camera intent. How should I display their small size version in a grid view for viewing purpose. Should I create their thumbnails and store them in cache or external storage Or should I use the thumbnails created by Default Gallery application. My pictures are stored in external storage so I am expecting that Default Gallery Application would make their thumbnails automatically. If yes, then how should I map each image with the thumbnail created by Default Gallery Application.

Well, I have found that Async class could handle the memory usage scenario.
The relevant link is: http://developer.android.com/intl/es/reference/android/os/AsyncTask.html

Well, I have got an answer
public Bitmap getbitpam(String path) {
Bitmap imgthumBitmap = null;
try {
final int THUMBNAIL_SIZE =300 ;
FileInputStream fis = new FileInputStream(path);
imgthumBitmap = BitmapFactory.decodeStream(fis);
imgthumBitmap = Bitmap.createScaledBitmap(imgthumBitmap,
THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
ByteArrayOutputStream bytearroutstream = new ByteArrayOutputStream();
imgthumBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytearroutstream);
} catch (Exception ex) {
}
return imgthumBitmap;
}
However, this is taking a lot of RAM. I Have also found a strange behavior. That as I am scrolling in grid view, it is taking more RAM. The growth in memory used is cumulative and finally the app is crashing due to Memory_Low exception. Any workaround for it??
Got answer for second problem too:-- Async class.

Related

Save multimple image in storage with some empty image

I have few questions about Images, bitmap particularly.
In my app that I currently develop, I have like 15 icons that each has on click function to open the camera and shows the result on those icons (like thumbnails).
On resultCode RESULT_OK, I get the bitmap data that from getExtras.get("data")
Then store it inside bitmap variable. Like below
bitmap1 = (Bitmap) data.getExtras().get("data");
I have another 14 bitmaps variable.
Now what I'm trying to do is saving those bitmaps to internal storage by a save button click. But first I place them into an array to make it easier.
Bitmap[] bitmapArr = {bitmap1,bitmap2,bitmap3,bitmap4,bitmap5,bitmap6,bitmap7,bitmap8,bitmap9,bitmap10,
bitmap11,bitmap12,bitmap13,bitmap14,bitmap15};
Then read each data to format it to PNG and save it to the internal storage.
for(int i=0; i<filename.length; i++){
FileOutputStream outputStream = new FileOutputStream(String.valueOf(filename[i]));
bitmapArr[i].compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
MediaStore.Images.Media.insertImage(getContentResolver(), filename[i].getAbsolutePath(), filename[i].getName(), filename[i].getName());
DBHandler db = new DBHandler(this);
db.addData(new Foto(fDate,siteid,filename[i].getName(),filename[i].getAbsolutePath()));
}
I successfully save it into the internal storage only if I capture all the 15 images. If I capture less than that...The app will immediately stop and not save the images.
I tried to handle it with declare the 15 bitmaps as null in oncreate method. But that doesn't seem to solve the issues.
There is probably something that I've been missing here.

Android | give image with intent

I want to pass my image from one Activity to another. At first I tried to do this with a base64 String of my image. But this only works for small pictures. It worked with 400 kb but not with 600 kb. Is there a better way to do this? By the way, I don't save the image locally, I get the image from a server, so I don't have a real Drawable.
If you only have the remote URL, then you can directly share it, otherwise you can save the image in the local media store and then share its local URL. Something like:
Bitmap bitmap = ...
String path = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Image Description", null);
Uri uri = Uri.parse(path);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, "Share Image"));
Even though it is a bit discouraged to pass large "blocks" of data through intents in android (use a singleton or store the image on the internal memory, etc), you can achieve it by doing :
1 - On your Sender Activity
Intent yourIntent = new Intent(YourActivity.this, DestinationActivity.class);
Bitmap bmp; // store the image in your bitmap
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 50, baos);
yourIntent.putExtra("yourImage", baos.toByteArray());
startActivity(yourIntent);
2 - On your Receiver Activity
// parse the intent onCreate()
if(getIntent().hasExtra("yourImage")) {
ImageView iv = new ImageView(this);
Bitmap bmp = BitmapFactory.decodeByteArray(getIntent().getByteArrayExtra("yourImage"), 0, getIntent().getByteArrayExtra("yourImage").length);
iv.setImageBitmap(bmp);
}
It is strongly discouraged that you do it this way because :
1 - There is a memory limit to the passing of data through an intent.
The maximum amount of data you can transfer using an Intent is 500KB (tested on API 10, 16, 19 and 23). check this external reference
Sometimes, the bitmap might be too large for processing, thus leading to OOM (I have experienced this in the past) or cause a bad UI experience.
2 - If your activity crashes by any reason, thus leading to a crash on the application, you will lose the image because it is stored in temporary memory. If you save it internally, you can persist the image even if the application crashes.
General the best practice is to process the image when you need it, store it on a device folder (can be internal or external memory) and later when you need it retrieve it again for more processing. This way you avoid unnecessary memory allocation throughout the application.
Also, you can use third-party libraries like Picasso or Glide. I personally like Glide as it is better in performance than any other.

Android : Bitmap causing out of memory error

I have been going crazy with this android error and from browsing the previous posts about this error none of the solutions that were given helped me.
I am of course talking about the all powerful killer known as the 'android Out of memory on a (NUMBER)-byte allocation.' I am trying to create a photo uploader and after the 3rd maybe 4th image my app crashes. I know to stop the crash to use a catch exception however that is not my problem. I am here to ask the community is there any solution to fixing this byte allocation error ?
Here is a snippet of my code involving the bit map .
String post = editTextPost.getText().toString().trim();
// get the photo :
Bitmap image = ((BitmapDrawable)postImage.getDrawable()).getBitmap();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// compress the image to jpg format :
image.compress(Bitmap.CompressFormat.JPEG, 45, byteArrayOutputStream);
byte[] imageBytes = byteArrayOutputStream.toByteArray();
String encodeImage = Base64.encodeToString(imageBytes,Base64.DEFAULT);
// Recycle bitmap :
image.recycle();
image=null;
// send data :
sendPost p = new sendPost(this);
p.execute(post, encodeImage);
imageBytes=null;
Im not using any libraries and would like to keep it that way however if using a library is the only option I will use one. Hopefully someone can help.
Bitmaps won't completely recycle if they are attached to a View, for example to a ImageView, if you do imageView.setImageBitmap(bitmap), you need to clear it before doing imageView.setImageBitmap(null) and clearing any other reference to any view.
After you finish uplloading the image release the memory occupied by the "postImage" -
postImage.setImageDrawable(null);
This will release any memory occupied by the bitmap associated with postImage
General Answer:
When you upload files you need to open a stream to your server and to
your file at same time. read and write chunk by chunk of 1 MB for
example. this way you will not get an out of memory exception.

Get scaled Image from URL

I am using the following method to get an image from a given URL.
protected Bitmap doInBackground(String... urls) {
String urlDisplay = urls[0];
Bitmap scaledImage = null;
try {
InputStream in = new java.net.URL(urlDisplay).openStream();
scaledImage = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(in), 380, 250, false);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return scaledImage;
}
Is there anyway to get a scaled image without having to download the full sized image first? It would greatly increase load times.
Sadly, server side manipulations can't be done and before downloading, there's no way to scale it. However, if you still want to save the load time on consecutive refreshes, then you probably can go ahead with saving the bitmap received in a shared preference. This way if the image is already stored in the shared preference, you don't need to download it again and apply scaling to it.
CAUTION: In case the image you are downloading is changing after a while, you can put a check to download it after every "n" (say 7) days and replace the existing stored image with this one.
NOTE: Though there are many answers already available which tells you how to store the image bitmap in Shared Preference / local storage, let me know in case you need that info/ code-snippet too.
You can not perform bitmap operations on a remote image without downloading it first. Therefore there is no way to do what you want to do unless the server you are getting the image from supports different image sizes or a parameter to resize it on the server side.

Android app how to properly load image thumbnails from web

So i am trying to load a bunch of thumbnails (possibly up to 100+) from the web, and I seem to be running out of memory around 30 on the emulator, and around 80-85 on the phone itself.
This is not going to work but there has to be a way-
I even tried saving the images to cache memory and loading from there, but it still runs out of memory.
What is the correct way to load a lot of web thumbnail images?
each image is about 50 kb, im basically adding the imageViews dynamically through a method i made called CreateImage. This pretty much loads each thumbnail based on the URL and image name, and sets it in a dynamic imageView in a horizontalScollView.
private void createImages(String URL, String imageName){
ImageView ImageThumbnails = new ImageView(this);
ImageThumbnails.setId(ImageThumbName);
ImageThumbnails.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
ImageThumbnails.getLayoutParams().height = 85;
ImageThumbnails.getLayoutParams().width = 85;
ImageThumbnails.setPadding(4, 4, 4, 4);
ImageThumbnails.setScaleType(ImageView.ScaleType.FIT_XY);
ImageThumbnails.setOnClickListener(this);
String path = Environment.getExternalStorageDirectory()+ "/" + imageName;
File imgFile = new File(path);
if(imgFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Bitmap bmpCompressed = Bitmap.createScaledBitmap(myBitmap, 85, 85, true);
ImageThumbnails.setImageBitmap(bmpCompressed);
}
ll.addView(ImageThumbnails);
}
Thanks in advance,
You should read those articles on the Android portal that explain exactly how to do it and provide the code:
Displaying bitmaps: http://developer.android.com/training/displaying-bitmaps/index.html
Loading large bitmaps: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Use AsyncTask to download each image individually and save it to disk (individually). Thats what I did for 30+ images for a Magazine App.
I think your problem will be solved with lazy list adapter. Try this example LazyList

Categories

Resources