An API I hit returns a URL to an image. I want to use a WebView, feed it this URL and have it display the image. However, I want the WebView to be a static 90dip x 90dip (images are square). The images are bigger than 90px. Is there a way I can tell the WebView to size the image to its own dimensions?
Have you tried it yet? Does it not work, if not what does it do instead?
I think you could use an ImageView to display the image with no problems. You can use a method like this to return to you a Drawable object from a url, which you can then set to the ImageView with setImageDrawable(img);
/***********************************************************
* This method will return the image from a URL.
* Note: This should be called from the UI thread.
***********************************************************/
public Drawable getRemoteImage(final URL aURL) {
try {
final URLConnection conn = aURL.openConnection();
conn.connect();
final BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
final Drawable d = Drawable.createFromStream(bis, "src");
bis.close();
return d;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
ImageView's I know for a fact you can set to a static size (90dip x 90dip) and it will handle scaling the image down if need be to make it fit in that size, WebView might try to make it scrollable or something, I am not sure.
Related
I'm downloading an image from a URL and displaying it in an ImageView. I need to download the image at its full original size. I've tried Glide, Picasso and Universal Image Loader with no success. Is there any library or mehod out there to achieve this? I even tried making my own AsyncTask to do it, something like this:
public class ImageLoader extends AsyncTask<Void, Void, Bitmap> {
#Override
protected Bitmap doInBackground(Void... params) {
try {
URL url = new URL(bundle.getString("selectedImage"));
HttpURLConnection conn =
(HttpURLConnection)url.openConnection();
conn.setReadTimeout(6000);
conn.setConnectTimeout(6000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int respose = conn.getResponseCode();
InputStream is = conn.getInputStream();
BufferedInputStream bufferedInputStream = new
BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bufferedInputStream);
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
but no success. Anyone have anything to help me?
1) Try to use Volley library.
https://developer.android.com/training/volley/request.html#request-image
2) Use WebView instead ImageView
I'm not really sure what you mean by "its full original size". I haven't experienced any automagic scaling of images simply by downloading them.
Maybe you could double-check that you have an appropriate android:scaleType on the target ImageView. You can read more on the different values of the scale type property here: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
If you want to pan the image, like an "unscaled" web page in the browser (typically when the image is bigger than the screen), you might need to add further logic to manage this. Maybe it could be as easy as having a ScrollView wrap your ImageView (which then would wrap its content, of course).
The error was down to photo bucket giving me a scaled down URL instead I used flikr and on my device I get an image almost identical to my original (Picasso limit is 2048x2048) but on other devices I still seem to get a 1080 x 910 image, will investigate further but it seems the answer is not to use photo bucket
I have an app where I have one banner in the top with News, when I want to put other news I need to open the code and change the resource .jpg and the Link. There is a way to change the banner and the Link (or at least the banner) without modifing the code? Idk maybe uploading it to a webpage or something like this.
thanks
My suggestion would be to upload a banner.jpg to a server that your app can access and dynamically load. This would prevent having to update your app every time you want to change the banner, and makes it cleaner (no excessive Google Play updates). To do actually load the image you can use this code:
ImageView image1 = (ImageView) findViewById(R.id.mybanner);
new Thread(new Runnable(){//create a new thread so we can do network operations
#Override
public void run() {//main thread function
try {//attempt to do network stuff
URL url = new URL("http://your-hosting-site.com/banner.jpg");//create aURL object with the path to your banner
HttpURLConnection con = (HttpURLConnection) url.openConnection();//create the connection object from the url
con.setReadTimeout(15000);
con.setConnectTimeout(15000);
con.setRequestMethod("GET");
con.setDoInput(true);
con.connect();//connect to the server
InputStream is = con.getInputStream();//get the stream so we can read the image
Drawable d = Drawable.createFromStream(is, "MyBanner");//create a drawable from the image
Bitmap bmp = ((BitmapDrawable) d).getBitmap();//create a bitmap from the drawable
final Drawable dS = new BitmapDrawable(Bitmap.createScaledBitmap(bmp, 192, 192, true));//scale it to whatever size you need
con.disconnect();//disconnect now that we're done
runOnUiThread(new Runnable(){//run UI update code on the main thread
#Override
public void run() {
image1.setImageDrawable(dS);//set the imageview to the banner we downloaded
}
});
} catch (MalformedURLException e) {//catch url error
e.printStackTrace();
} catch (IOException e) {//catch io error when downloading
e.printStackTrace();
}
}
}).start();//run the thread
Change "http://your-hosting-site.com/banner.jpg" (line 6) to wherever you uploaded the .jpg, R.id.mybanner (line 1) to the id of your ImageView, and "MyBanner" (line 14) to whatever you want to call the image.
You might want to save your banner to the phone and only check after X days/hours for an update to save data, but that is up to you.
I am trying to display an image from a URL, which may be larger than the screen dimensions. I have it kind of working, but I would like it to scale to fit the screen, and I also have problems when the screen orientation changes. The image is tiny, and I would like it to scale its width to the screen as well. (In both cases, I would like the image to fill the screen width with scrollbars (if necessary for height).
Here is my ImageView:
<ImageView android:id="#+id/ImageView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true">
</ImageView>
Here is the java code which loads the image: (some error handling code removed for simplicity)
Object content = null;
try{
URL url = new URL("http://farm1.static.flickr.com/150/399390737_7a3d508730_b.jpg");
content = url.getContent();
}
catch(Exception ex)
{
ex.printStackTrace();
}
InputStream is = (InputStream)content;
Drawable image = Drawable.createFromStream(is, "src");
Image01.setImageDrawable(image);
I have tried different settings for android:scaleType. I'm sorry if this question has been asked before. I've gone through a number of tutorials on the subject, but they don't seem to work for me. Not sure if it has anything to do with the way the image is loaded. (from the web instead of a local resource)
Another issue is that sometimes the image doesn't even load. There are no runtime errors, I just get nothing in the ImageView.
Please let me know if you need more information or clarification.
the issue about that "sometimes the image doesn't even load" is related to the context so I used this functions to solve that issue
public Object fetch(String address) throws MalformedURLException,
IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
private Drawable ImageOperations(Context ctx, String url) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
}
}
so to fill the screen width with your image you must have a code like this
try{
String url = "http://farm1.static.flickr.com/150/399390737_7a3d508730_b.jpg";
Drawable image =ImageOperations(this,url);
Image01.setImageDrawable(image);
}
catch(Exception ex)
{
ex.printStackTrace();
}
Image01.setMinimumWidth(width);
Image01.setMinimumHeight(height);
Image01.setMaxWidth(width);
Image01.setMaxHeight(height);
UPDATE::
if you load a big size image obviously you will have to wait more time, and download problems could be caused for UnknowHostException.
yes you are right you will save your image locally, the local access is faster than the download.
to avoid problems on rotation change set your configChanges="keyboardHidden|orientation" property inside your Manifest.xml
<activity android:name=".myActivity"
...
android:configChanges="keyboardHidden|orientation" >
...
/>
In Android, what is the simplest approach to the following:
Load an image from a remote server.
Display it in an ImageView.
Here's a method that I actually used in an application and I know it works:
try {
URL thumb_u = new URL("http://www.example.com/image.jpg");
Drawable thumb_d = Drawable.createFromStream(thumb_u.openStream(), "src");
myImageView.setImageDrawable(thumb_d);
}
catch (Exception e) {
// handle it
}
I have no idea what the second parameter to Drawable.createFromStream is, but passing "src" seems to work. If anyone knows, please shed some light, as the docs don't really say anything about it.
The easiest way so far is build a simple image retriver:
public Bitmap getRemoteImage(final URL aURL) {
try {
final URLConnection conn = aURL.openConnection();
conn.connect();
final BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
final Bitmap bm = BitmapFactory.decodeStream(bis);
bis.close();
return bm;
} catch (IOException e) {}
return null;
}
Then, you just have to supply a URL to the method and it will returns a Bitmap. Then, you will just have to use the setImageBitmap method from ImageView to show the image.
Be careful with both of the answers here - they both run the chance of an OutOfMemoryException. Test your application by attempting to download a large image, such as a desktop wallpaper. To be clear, the offending lines are :
final Bitmap bm = BitmapFactory.decodeStream(bis);
and
Drawable thumb_d = Drawable.createFromStream(thumb_u.openStream(), "src");
Felix's answer will catch it in the catch{} statement, and you could do something about it there.
Here is how to work around the OutOfMemoryException error:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(is, null, options);
} catch (OutOfMemoryError ome) {
// TODO - return default image or put this in a loop,
// and continue increasing the inSampleSize until we don't
// run out of memory
}
And here are my comments on this in my code
/**
* Showing a full-resolution preview is a fast-track to an
* OutOfMemoryException. Therefore, we downsample the preview image. Android
* docs recommend using a power of 2 to downsample
*
* #see <a
* href="https://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue/823966#823966">StackOverflow
* post discussing OutOfMemoryException</a>
* #see <a
* href="http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize">Android
* docs explaining BitmapFactory.Options#inSampleSize</a>
*
*/
Links from above comments:
Link 1
Link 2
You can also try this lib:
https://github.com/codingfingers/fastimage
When we had few projects with the same pattern, and the lib came up ;) so why not to share with others...
This is simple:
Add this dependency in you gradle script:
implementation 'com.squareup.picasso:picasso:2.71828'
*2.71828 is current version
Then do this for the image view:
Picasso.get().load(pictureURL).into(imageView);
I've been looking everywhere to see if there is a standard way of achieving this but I find a different solution every-time.
Basically, I am trying to build a Custom ListView with an image and two-three lines of text besides it.
In order to optimize it, I understand that the following have to be used:
convertView: Basically if the view was already inflated, use it
Lazy-Loading: Do not load the content of the rows until they are called for
Background Downloading & Caching: Download images in their own threads and then update the row (and possible cache them?)
I could manage 1 and 2 but the third one is really confusing me.
Is there a best practice for this?
Thanks
Thanks to Mark for his help. This is one way of doing what he suggested (just in case some else is curious):
private class DownloadImageTask extends AsyncTask<Object, Integer, Bitmap> {
private ImageView iv;
protected Bitmap doInBackground(Object... params) {
try {
iv = (ImageView) params[0];
URL aURL = new URL("http://URLTOIMAGE/img" + params[1] + ".png" );
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
return bm;
} catch (IOException e) {
return null;
}
}
protected void onPostExecute(Bitmap result) {
iv.setImageBitmap((Bitmap) result);
}
}
And it would be used as follows:
new DownloadImageTask().execute(new Object[] {ImageViewHandle, position});
Note that this is not a working code. This was taken from a larger code base so you will have to make appropriate changes to make this work.
It may be a bit early to describe something as "best practice". AsyncTask or a thread monitoring a LinkedBlockingQueue are fine ways to offload something like image fetching.
You may be interested in my ThumbnailAdapter, which handles the background downloading and caching for you.