Simple Android Image Download Async - java

I'm attempting to obtain an image URL through JSON data, which works successfully. Everything below works SLOWLY. However, I am trying to figure out a way to get a URL to display much faster below in Android Volley or another fast method. I am trying to download these images from a URL (resized too) into a MapView pin icon. If there is a more efficient example anyone can find, I am all in. Please let me know if you need more information from me. I am following this guide: Android load from URL to Bitmap
final String profilePicture = profilePic;
URL url = new URL(profilePicture);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
Bitmap bit = BitmapFactory.decodeStream(is);
Bitmap b = Bitmap.createScaledBitmap(bit, 100, 100, false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 10, out);
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(decoded);

Use picasso library :
http://square.github.io/picasso/
Its easy to use and have alot of useful feature !
For example :
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)

You can use Koushik Ion library. Its very easy to use.
[https://github.com/koush/ion][1]

Related

Convert Java Code of Bitmap into C# code In Console app

I am trying to convert Java code into c#
So here is Java code
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap decodeStream = BitmapFactory.decodeStream(openInputStream, null, options);
Then I am saving this bitmap by
File appDirectory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File dest = new File(appDirectory, "yourImage.jpg");
try (FileOutputStream out = new FileOutputStream(dest)) {
decodeStream.compress(Bitmap.CompressFormat.JPEG, 100, out); // bmp is your Bitmap instance
} catch (IOException e) {
e.printStackTrace();
}
Now can anyone help me to convert this code into c#. I Tried to import Xamrine Android DLL but got success no far.
I am
As far as I understand you only need to load simple jpg image. That is all your java code do.
If you want to load jpg image from stream you can use
Bitmap.FromStream()
e.g.
using (FileStream fs = new FileStream(#"Image Address.jpg", FileMode.Open, FileAccess.Read))
{
var decodeStream = Bitmap.FromStream(fs);
}
of course you can open your image without stream too.
var image = Bitmap.FromFile(#"Image Address.jpg");
So your code will be something like this
File appDirectory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File dest = new File(appDirectory, "yourImage.jpg");
var image = Bitmap.FromFile(dest.FullName);
You can not access Bitmap class out of the box.
For dot net core install package System.Drawing.Common.
For dot net framework add reference to System.Drawing.
For Xamarin see this answer https://stackoverflow.com/a/34869330/5964792

Generate a thumbnail from a video uri in android and convert it to base64

I am trying to get a frame from the video (thumbnail) and convert it to base64. I have used the following code but sometimes it doesn't work:
Uri selectedVideo = Uri.parse(intent.getStringExtra("trimmedVideo"));
MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
mMMR.setDataSource(this, selectedVideo);
Bitmap thumbnail = mMMR.getFrameAtTime();
Log.d(Global.getTag(), "thumbnail: "+thumbnail);
Also I get this error in logcast:
E/MediaMetadataRetrieverJNI: getFrameAtTime: videoFrame is a NULL pointer
And thumbnail is null. Thanks in advance.
Note:
I also try to use the next code but it doesn't work.
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MICRO_KIND);
Ref: https://stackoverflow.com/a/32517167/13533028
1st Method
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MICRO_KIND);
The Thumbnails part decides the type of thumbnail it will be.(big or small)
2nd Method
https://github.com/sushinpv/SuziVideoThumbnailLoader
This is a library which will make it easier for you to implement
3rd Method
Using Glide Library
RequestOptions requestOptions = new RequestOptions();
Glide.with(getContext())
.load("video_url")
.apply(requestOptions)
.thumbnail(Glide.with(getContext()).load("video_url"))
.into("yourimageview");

Android : FileNotFoundException when trying to get an image from Uri

I am trying to get an image's width and height in order to rezize it in case it is too big before showing it. My method receive an uri of the image but I always get a FileNotFoundException when trying to decode it using BitmapFactory.
Here is a sample of my code :
Uri myUri;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(myUri.getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
Decode File returns throws a FileNotFoundException here. However, I can still show the image using the uri without using a bitmap factory using this :
Uri myUri;
Bitmap myBitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), myUri);
The problem with this code is that the returned bitmap might cause an OutofMemoryError when using big images.
When I debug my Uri, I get this :
content://com.android.providers.media.documents/document/image%3A20472
UPDATE || Here is the working code
Uri myUri;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// This is the part that changed
InputStream inputStream = context.getApplicationContext().getContentResolver().openInputStream(myUri);
BitmapFactory.decodeStream(inputStream,new Rect(),options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
All of this of course surrounded by try/catch.
Use decodeStream instead of decodeFile.
Open the stream with getContentResolver().openInputStream(myUri).
After playing around with this for a while, I think the issue is probably that the image file really isn't there.
If you are attempting to access a local file on your computer, that file won't be in the Android sandbox where the app is actually running. You'll need to add it to the app as a resource, then access it as a resource instead of a file.
If you are attempting to access a web image, you need to download it first. The AbsolutePath of a web image 'http://example.com/example.jpg' would be '/example.jpg', which won't do you much good when you try to open it.

Performance of JSoup and Bitmap Images

I've been working on an Android app where I am getting an RSS feed and I need to parse some additional HTML for image source links. So, I figured I would use JSoup and see how it went. It IS working and I can get the image src link correctly. However the .Parse method is taking a very long time to complete and I can't have the user waiting that long. All of this fetching of the RSS takes place in onStart() in the app by the way.
My ultimate goal is to retrieve the images from the src url's and display them next to article text. I've had my fair share of dealing with the common OutOfMemory errors in relation to the heap. As of now I seem to have sort of dealt with it. But I still cannot figure out why the loading of the program is taking so long. Right now there are 10 articles in the RSS feed and the HTML parsing for each one is not really long. Maybe someone can spot something stupid I'm doing and figure out why the loading of my program is taking so long. I would certainly appreciate it! Here is my code involving the images and Jsoup.
public static Bitmap parseForImg(String desc) throws IOException
{
Document doc = Jsoup.parse(desc);
Elements images = doc.select("img[src~=(?i)\\.(png|jpe?g|gif)]");
String imgURL = "";
Bitmap img = null;
if(images.size() > 0)
{
for (Element image : images)
{
imgURL = image.attr("src");
break;
}
String editedImgURL = imgURL.replace("/sites/", "https://www.").trim();
img = ArticleRSSReader.grabImgFromURL(editedImgURL);
}
else
{
//in the event there is no image related to a description in the rss feed, just display
//the logo for now...
InputStream inputS = MainActivity.globalTHIS.getResources().getAssets().open("defaultlogo.png");
img = BitmapFactory.decodeStream(inputS);
//no need to grab image from url, just return
}
return img;
}
public static Bitmap grabImgFromURL(String imageURLLoc)
{
URL imageURL = null;
Bitmap resizedBit = null;
try
{
imageURL = new URL(imageURLLoc);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
try
{
HttpURLConnection connection = (HttpURLConnection) imageURL
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
//bitmap = BitmapFactory.decodeStream(inputStream);// Convert to
// bitmap
// image_view.setImageBitmap(bitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
options.inPurgeable = true;
resizedBit = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream,null,options), 100, 100, false);
}
catch (IOException e)
{
e.printStackTrace();
}
return resizedBit;
}

Loading images from URL partially, just like what is implemented in WhatsApp

WhatsApp developers recently improved the image loading in which immediately loading some portion of the image (getting its dimension and some pixels of the images) and then after loading the entire image, replace the placeholder with the full image:
My question is, how did they implement it? Do they read the dimension of the image by reading its header (meta-data)? How about the image content? Or do they have two versions of the image at the server-side, a smaller one with low-quality which is loaded first and a bigger one which is the full image? Note that if it's the second approach then they still need to extract the smaller version of the image at the server side once receiving the image from the sender. Any other approaches?
There is another alternative to the colored placeholder solution, which is to show a thumbnail image (may be only a 100 X 100 px) as the placeholder until loading the real image, which is away more cooler than having only a colored placeholder :) .
I did it in Zingoo and made a blog post about it. Using Picasso, you can do it like this:
Transformation blurTransformation = new Transformation() {
#Override
public Bitmap transform(Bitmap source) {
Bitmap blurred = Blur.fastblur(LiveImageView.this.context, source, 10);
source.recycle();
return blurred;
}
#Override
public String key() {
return "blur()";
}
};
Picasso.with(context)
.load(thumbUrl) // thumbnail url goes here
.placeholder(R.drawable.placeholder)
.resize(imageViewWidth, imageViewHeight)
.transform(blurTransformation)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
Picasso.with(context)
.load(url) // image url goes here
.resize(imageViewWidth, imageViewHeight)
.placeholder(imageView.getDrawable())
.into(imageView);
}
#Override
public void onError() {
}
});
more details in the post itself including the Blur class.
Yet another up-to-date answer for an older post. You could try the progressive JPEG streaming feature of the Fresco library to achieve that effect.
Basically all you'd need to do is calling .setProgressiveRenderingEnabled(true) while creating an ImageRequest. I have included a complete example for Fresco's progressive JPEG streaming into my demo application mentioned in this answer, you might want to try it out to see how it works.
For the lazy ones: when working with Fresco, create a DraweeController as following:
ImageRequest imgReq = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
.setProgressiveRenderingEnabled(true)
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(imgReq)
.setOldController(yourDrawee.getController())
.build();
yourDrawee.setController(controller);
Note: this approach has some restrictions as explained in the docs.
After several experiments, I got the dimensions without downloading the entire image:
String address = "image_url";
URL url = new URL(address);
URLConnection urlC = url.openConnection();
urlC.connect();
InputStream is = urlC.getInputStream();
for(int i = 0; i < 92; i++) is.read();
nt byte1 = is.read();
int byte2 = is.read();
int width = (byte1 << 8) + byte2;
for(int i = 0; i < 10; i++) is.read();
byte1 = is.read();
byte2 = is.read();
int height = (byte1 << 8) + byte2;
System.out.println("width = " + width + " | height = " + height);
is.close();
Using Glide lib:
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);

Categories