Display image from URL - sizing and screen orientation problems - android

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" >
...
/>

Related

loading full image from url into image view with any image loading library

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

How can i "update" a banner in Android?

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.

Custom image viewing slows down

The problem
Hi there,
I'm developing an application where the user specifies some pictures and how long they are going to be on the screen.So sometimes he wants to create something like a small animation or viewing the images for a small amount of time.The problem is that after some time the images are not previewed when they should and we have a few ms of error.In the application that i'm developing time matters so I would like some help on what the problem might be.
The code
So let me explain how it works.I take the pictures from my web app and then I save them in a HashMap
Bitmap image = ImageOperations(url,String.valueOf(frameNum) + ".jpg");
ImageMap.put(String.valueOf(frameNum), image);
where the mathod ImageOperations is like that:
private Bitmap ImageOperations(String url, String saveFilename) {
try {
Display display = getWindowManager().getDefaultDisplay();
InputStream is = (InputStream) this.fetch(url);
Bitmap theImage = BitmapFactory.decodeStream(is);
if (theImage.getHeight() >= 700 || theImage.getWidth() >= 700) {
theImage = Bitmap.createScaledBitmap(theImage,
display.getWidth(), display.getHeight() - 140, true);
}
return theImage;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
So later I run a thread that updates the UI when the user specified.The method that updates it is this one.
public void setPictures(int NumOfFrame) {
if (frameArray.get(NumOfFrame - 1).frame_pic.contains("n/a") != true) {
ImagePlace.setImageBitmap(ImageMap.get(String.valueOf(NumOfFrame)));
} else {
ImagePlace.setImageDrawable(null);
}
}
After we update the image we put the thread for sleep and when runs again it updates the thread.Is there something that creates the problem?Does it have to do with Garbage collection?
Thank you in advance
Probably the issue is in increasing heap size when it loads additional images. I would suggest You to do some profiling so things will be much clearer and You'll get full picture of timings for the app.
First you are missing a null check at here:
ImageMap.get(String.valueOf(NumOfFrame))
And you do not recycle the old bitmap at here:
theImage.recycle(); // missing line
theImage = Bitmap.createScaledBitmap(theImage,
display.getWidth(), display.getHeight() - 140, true);
It may lead to outofmemory exceptions, with is most likely from your description of the problem.
Also I am not sure if BitmapFactory.decodeStream throw exception when he fails. You need to add a null point check there too.

Size image to fit WebView dimensions

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.

Need suggestion about a mixed "Uri / int id" images ambient

I have the following problem:
suppose that until now, I am using R.drawable.img to set the image in some imageviews
with
imgView.setImage(aProduct.getImgId());
the simplified product class look like this:
class Product{
int imgId;
....
public void setImgId(int id){
this.imgId=id;
}
public int getImgId(){
return this.imgId
}
...
}
my application is now "evolved" because the user can add customized products
taking the img from the camera and getting the Uri of the picture.
and to set the image on the ImageView imgView.setImgURI(Uri)
Now my question is:
what would be the best approach to have a mixed int/Uri image resources ambient?
can I obtain the Uri of a "R.drawable.img"?
I'm not sure if my question is clear, I mean:
I have to check, before to set the imageview, if my product has an Uri or an int Id,
and then make an "if" to call the appropriate method, or there is a simpler solution?
Thank you for reading, and sorry for my english.
Regards.
Your problem is that there are basically 3 types of image resources:
R.id... resources: internal resources, such as icons you put into the res folder
content URI's: local files or content provider resources such as content:// or file:///sdcard/...
remote file URL's: images on the web, such as http://...
You are looking for a way to pass around one identifier that can deal with all three. My solution was to pass around a string: either the toString() of the URI's, or just the string respresentation of the R.id integer.
I'm using the following code, for example, to deal with this and make the code work with it:
public static FastBitmapDrawable returnAndCacheCover(String cover, ImageRepresentedProductArtworkCreator artworkCreator) {
Bitmap bitmap = null;
Uri coverUri = null;
boolean mightBeUri = false;
//Might be a resId. Needs to be cached. //TODO: problem: resId of default cover may not survive across versions of the app.
try {
bitmap = BitmapFactory.decodeResource(Collectionista.getInstance().getResources(), Integer.parseInt(cover));
} catch (NumberFormatException e) {
//Not a resId after all.
mightBeUri=true;
}
if(bitmap==null || mightBeUri){
//Is not a resId. Might be a contentUri.
try {
coverUri = Uri.parse(cover);
} catch (NullPointerException ne) {
//Is null
return null;
}
}
if(coverUri!=null){
if(coverUri.getScheme().equals("content")){
//A contentUri. Needs to be cached.
try {
bitmap = MediaStore.Images.Media.getBitmap(Collectionista.getInstance().getContentResolver(), coverUri);
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
return null;
}
}else{
//Might be a web uri. Needs to be cached.
bitmap = loadCoverFromWeb(cover);
}
}
return new FastBitmapDrawable(bitmap);
}
You might be interested to take over the logic part. Ofcourse cover is the string in question here.
Forget android.resource:// as a replacement for the R.id... integer. Claims are going round it does not work: http://groups.google.com/group/android-developers/browse_thread/thread/a672d71dd7df4b2d
To find out how to implement loadCoverFromWeb, have a look around in other questions or ping me. This web stuff is kind of a field of it's own.
(Based on GPLv3 code out of my app Collectionista: https://code.launchpad.net/~pjv/collectionista/trunk)

Categories

Resources