I'm using the following code to create a resized bitmap, the code works okay, but it's very slow. The problem is that when I try to use this for more than one image the phone freezes until the images are created.
Here is my code:
Bitmap bitmap = null;
File imgFile = new File(my_pic_file);
if(imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 300, 200, false);
first_image.setImageBitmap(resizedBitmap);
}
The problem is that you are doing the work on the main thread. This means that it will freeze the UI until all the processing is finished. You can fix this by either using a thread or asynchronous task.
private class LoadImageTask extends AsyncTask<String, Void, Bitamp> {
private ImageView mImageView = null;
public LoadImageTask(ImageView imageView) {
mImageView = imageView;
}
protected Bitmap doInBackground(String... file) {
Bitmap bitmap = null;
Bitmap resizedBitmap = null;
File imgFile = new File(file);
if(imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
resizedBitmap = Bitmap.createScaledBitmap(bitmap, 300, 200, false);
}
return resizedBitmap;
}
protected void onPostExecute(Bitmap result) {
if (result != null && mImageView != null) {
mImageView.setImageBitmap(result);
}
}
Then in your code just call
new LoadImageTask(first_image).execute(my_pic_file);
Related
I am using the following code to download an image from an url, then saving to sqlite and then view in imageview in an activity.
new LoadProfileImage().execute(jsonObject.getString("image"), id, title, promoexpdate, String.valueOf(i),flag,promostartDate);
The above code is used to call the function to do the above work.
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
String x,y,z,a,w,s;
protected Bitmap doInBackground(String... uri) {
String url = uri[0];
Log.d("ImageURL",url);
x = uri[1];
y = uri[2];
z = uri[3];
a = uri[4];
w = uri[5];
s = uri[6];
Log.d("LogValue",url+x+y+z+a+w+s);
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (IOException e) {
Log.e("ErroronImageParsing", e.getLocalizedMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if (result != null) {
int width = result.getWidth();
int height = result.getHeight();
Bitmap newBitmap = Bitmap.createScaledBitmap(result, width / 2, height / 2, true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
newBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
buffer = out.toByteArray();
if (result!= newBitmap){
result.recycle();
}
Log.d("ImageUploaded", "Success");
}
try {
dbManager.open();
Cursor cursor = dbManager.fetch_PromsID(x);
if (cursor.getCount() > 0){
String fla = cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRO_FLAG));
String pri_ID = cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRO_ID));
if (!w.equals(fla)) {
dbManager.update_Promotions(pri_ID,y,z, buffer,w,s);
}
}else {
dbManager.insertPromotions(x,y,z,buffer,w,s);
}
} catch (SQLException e) {
e.printStackTrace();
}
SqliteData();
panel.setVisibility(View.GONE);
dbManager.close();
}
}
Here, when the code below is executed, image from the url is saved into internal storage. I wish to disable the auto saving while maintaining my intention. Thanks in advance...
Bitmap newBitmap = Bitmap.createScaledBitmap(result, width / 2, height / 2, true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
newBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
buffer = out.toByteArray();
Try to use third library like Picasso or Glid
that offer
loading without caching
loading with memory or storage caching
you can do it with single line of code
Picasso.with(context).load(imageUrl)
.error(R.drawable.error)
.placeholder(R.drawable.placeholder)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
I took a picture from custom camera but I cant display the photo taken in the new activity.
Here is my code byt its not working.
What is wrong?
public class PicturePreview extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture_preview);
Bundle bundle = getIntent().getExtras();
String path = bundle.getString("ImagePath");
ImageView image = (ImageView) findViewById(R.id.photopreview);
File imgFile = new File(path);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
image.setImageBitmap(myBitmap);
}
}
}
And here is the xml file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="involved.dreamon.PicturePreview">
<ImageView
android:id="#+id/photopreview"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
What king of exception do you have..not clear. If there is no problem but not showing image. Then image need to compress to set it in ImageView.
Some times it don't show when image regulation very high
use this method to solve this
public Bitmap imageConversion(Bitmap imageBitmap) {
Bitmap bitmap = imageBitmap;
float lengthbmp = bitmap.getHeight();
float widthbmp = bitmap.getWidth();
if (lengthbmp > 1000) {
if (widthbmp > 800) {
bitmap = Bitmap.createScaledBitmap(bitmap, 600, 800, true);
} else {
bitmap = Bitmap.createScaledBitmap(bitmap, (int) widthbmp, 800,
true);
}
}
return bitmap;
}
use the method like this
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
image.setImageBitmap(imageConversion(myBitmap));
}
In my app i have an ImageView. Before adding that ImageView the app was performing smooth. now it throws ANR.
The image is saved in the database as base 64 encode string and it is decoded to bitmap and loaded to the imageview using :
imageView.setImageBitmap(bitmap);
The conversion of bitmap and applying the bitmap to ImageView all those things are done in an AsyncTask:
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String data = "";
public BitmapWorkerTask(ImageView imageView, String data) {
imageViewReference = new WeakReference<ImageView>(imageView);
this.data = data;
}
#Override
protected Bitmap doInBackground(Integer... params) {
byte[] decodedString = Base64.decode(data, Base64.DEFAULT);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inPurgeable = true;
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length, options);
return decodedByte;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
The AsyncTask is called from the main ui using the following code:
BitmapWorkerTask task = new BitmapWorkerTask(pollWebView,decodedStrings[1]);
task.execute();
decodedStrings[1] contains the base64 encoded image dataUrl.
Any solutions for this problem?
The major issue which is letting your app slow is WeakReference remove it and try whithout that
don't use this
private final WeakReference<ImageView> imageViewReference;
just use
private final ImageView imageViewReference;
Use following code to compress image (75% compression)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
I am working on a video app. I am streaming a video from server link , is it possible for me to generate a video thumbnail from the URL without downloading the video.
Without downloading video you can generate thumbnail from below code:
public static Bitmap retriveVideoFrameFromVideo(String videoPath) throws Throwable
{
Bitmap bitmap = null;
MediaMetadataRetriever mediaMetadataRetriever = null;
try
{
mediaMetadataRetriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
else
mediaMetadataRetriever.setDataSource(videoPath);
// mediaMetadataRetriever.setDataSource(videoPath);
bitmap = mediaMetadataRetriever.getFrameAtTime();
} catch (Exception e) {
e.printStackTrace();
throw new Throwable("Exception in retriveVideoFrameFromVideo(String videoPath)" + e.getMessage());
} finally {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
}
}
return bitmap;
}
NOTE : Video is stored as Intra and non Intra (Picture frames) getFrameAtTime will return the closest non- Intra frame as Bitmap. So basically it won't download the entire video.
I tried this with glide and it worked , Glide version 4.3.1
GlideApp.with(context)
.asBitmap()
.load(FILE_URL)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(iv_picture);
Edit : Glide was working slow for me
The Top answer was not giving result for some videos , here is how i did it
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//give YourVideoUrl below
retriever.setDataSource("YourVideoUrl", new HashMap<String, String>());
// this gets frame at 2nd second
Bitmap image = retriever.getFrameAtTime(2000000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
//use this bitmap image
It is not possible to create thumbnail from steaming link, you have to show it from server. Better upload a thumbnail along the video.
Use the below code to generate thumbnail
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail("picturePath", MediaStore.Video.Thumbnails.MINI_KIND);
Here's your link:
Android: Is it possible to display video thumbnails?
http://developer.android.com/reference/android/media/ThumbnailUtils.html
In my opinion, Server side should create thumbnail from a video and transfer thumbnail video images through your service.
You can generate Thumbnail from server URL like given below
Add Glide Library then use like this following
RequestOptions requestOptions = new RequestOptions();
requestOptions.isMemoryCacheable();
requestOptions.override(70,70);
Glide.with(context).setDefaultRequestOptions(requestOptions).load(model.getMediaURL()).into(myViewHolder.imageView);
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail("VIDEO FILE ADDRESS", MediaStore.Video.Thumbnails.MINI_KIND);
This method will give you thumbnails of all the video files in your phone... feel free to ask questions
public static Bitmap[] getThumbnail(Context context){
Uri uri=MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection=new String[] { MediaStore.Video.Thumbnails._ID };
Cursor ca = context.getContentResolver().query(uri, projection, null, null, null);
Bitmap[] b=new Bitmap[ca.getCount()];
int i=0;
ca.moveToFirst();
while(i<ca.getCount()) {
int id = ca.getInt(ca.getColumnIndex(MediaStore.Video.Thumbnails._ID));
b[i++]=MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(),id, MediaStore.Images.Thumbnails.MINI_KIND, null );
ca.moveToNext();
}
ca.close();
return b;
}
Here is the best solution
"https://img.youtube.com/vi/" + videoID + "/0.jpg"
Here videoID you get from youtube Url.
We fetch all video in Android Phone. http://sunilkmrnishad.blogspot.in/2017/03/read-files-apps-photos-media-from.html
public class ThumbnailExtract extends AsyncTask<String, long[], Bitmap> {
private final String videoUrl;
private final ImageView mThumbnail;
private final boolean mIsVideo;
private MediaMetadataRetriever mmr;
public ThumbnailExtract(String videoLocalUrl, ImageView thumbnail, boolean isVideo) {
this.videoUrl = videoLocalUrl;
mThumbnail = thumbnail;
mIsVideo = isVideo;
if (!isVideo) {
mmr = new MediaMetadataRetriever();
}
}
#Override
protected Bitmap doInBackground(String... params) {
if (!mIsVideo) {
return getBitmap(videoUrl);
} else {
return ThumbnailUtils.createVideoThumbnail(videoUrl,
MediaStore.Images.Thumbnails.MINI_KIND);
}
}
#Override
protected void onPostExecute(Bitmap thumb) {
if (thumb != null) {
mThumbnail.setImageBitmap(thumb);
}
}
private Bitmap getBitmap(String fileUrl) {
mmr.setDataSource(fileUrl);
byte[] data = mmr.getEmbeddedPicture();
Bitmap bitmap = null;
// convert the byte array to a bitmap
if (data != null) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
return bitmap != null ? ScalingUtilities.createScaledBitmap(bitmap, 40, 40, ScalingUtilities.ScalingLogic.FIT) : bitmap;
}
}
I am unable to fiund how to download images to my widget!
In my widget I load in AsyncTask json with url, title, then I show title in TextView and I need to load images from url.
I tried with this but image load, and now showing
class LoadImages extends AsyncTask<Void, Void, Bitmap>{
#Override
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL("http://mysite/simple.img").openStream());
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream);
out.flush();
final byte[] data = dataStream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
//options.inSampleSize = 1;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
Log.e("Log", "Yeah");
} catch (IOException e) {
Log.e("Log", "Could not load Bitmap from: " + "mysiteg");
}
return bitmap;
}
}
And on Update I call this
LoadImages load = new LoadImages();
load.execute();
Bitmap bitmap = load.get();
update.setImageViewBitmap(R.id.imageView0, bitmap);
You should override onPostExecute method in LoadImages class, and set bitmap to your ImageView in that method. When LoadImages task is done, it will call onPostExcute method. Considering WeakReference to wrap your ImageView for better performance.