problems with the resolution of loaded images from url - android

I am loading images in an ImageView from url. (from RSS feed)
The problem is that the resolution of the loaded image is lower than the original image !!
I searched Stackoverflow and found that the solution is to set the "inScaled" option to false to prevent image re-scaling.
but, this solution didn't work for me.
Here is the code:
URL feedImage= new URL(img_link);
HttpURLConnection conn= (HttpURLConnection)feedImage.openConnection();
InputStream is = conn.getInputStream();
BitmapFactory.Options BFoptions = new BitmapFactory.Options();
BFoptions.inScaled = false;
Bitmap img = BitmapFactory.decodeStream(is,null, BFoptions);
int density = img.getDensity(); Log.e("img", "Image density is " + density);
int width =img.getWidth(); Log.e("img", "Image width is " + width);
int height = img.getHeight(); Log.e("img", "Image height is " + height);
my_image.setImageBitmap(img);
The variables density, width and height are lower than the original image's values.
and here is a part of my layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/joke_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="temp description"/>
<ScrollView
android:id="#+id/SV"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:background="#drawable/background"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingBottom="50dp">
<!-- bla
bla
bla
-->
</ScrollView>
</RelativeLayout>
Thanks in advance

Finally it was solved :)
It appeared to be not related to the code or the ImageViews, .....
All the images in the RSS feeds are thumbnails ... which is the reason that they appear small in the app but large in the website.
So the solution was to replace the "_s.jpg" at the end of each image's url with "_n.jpg" :)
I hope this answer will help someone else :)

Related

Image in ImageView showing up smaller than expected (Android)

I have this animation/code where a tap on the photo enlarges it to the full screen while the rest of the screen turns black. When I use this banana stock photo the size turns out large enough. However, when I pull images from the web using an API the images turn out very small I tried checking the size of the image and it does not seem to be naturally that small. The water bottle image is actually h:89 and w:273 pixels when downloaded from the source.
//pulling the image and finding its sizes
Glide.with(getContext()).load(currentFood.getImageUrl()).into(ivFullScreen);
int ih=ivFullImage.getMeasuredHeight();//height of imageView = 1440
int iw=ivFullImage.getMeasuredWidth();//width of imageView = 2464
int iH=ivFullImage.getDrawable().getIntrinsicHeight();//original height of underlying image = 3332
int iW=ivFullImage.getDrawable().getIntrinsicWidth();//original width of underlying image = 4442
Toast.makeText(getContext(), "view height: " + ih + " view width: " + iw + " image height: " + iH + " image width: " + iW, Toast.LENGTH_LONG).show();
The Toast showed that the `ivFullImage` size is h:1440 and w:2464 and the image's size is h:3332 and w:4442.
XML:
<LinearLayout android:id="#+id/llFullScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:alpha="0.0">
</LinearLayout>
<ImageView android:id="#+id/ivFullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/bananas1"
android:scaleType="centerInside"
android:visibility="invisible"
/>
Just try to add android:adjustViewBounds="true" attribute to your ImageView :
<ImageView android:id="#+id/ivFullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/bananas1"
android:scaleType="centerInside"
android:adjustViewBounds="true" />
More info : ImageView
If the emulator/device size is too big it might be natural for the image to look small. Even though, I can see that you're adding the image statically from the XML with android:src="#drawable/bananas1", and not dynamically from the code. If you want to download an image from the internet and add it what you can do is call your ImageView of your layout from your code and then get the image you want to add from the URL you have
ImageView mImage = (ImageView) findViewById(R.id.ivFullImage);
//get the image from the url using the library you have, convert to bitmap
mImage.setImageBitmap(yourImageInBitmap);
Also, in your XML, you need to define the width and height of your ImageView to adjust to the dimensions of the image you're going to insert by saying
android:layout_width="wrap_content"
android:layout_height="wrap_content"

ScrollView not working with Drawables Android

I am using Html.fromHtml() to get content and display it on my activity. To do this I am using an ImageGetter. I was having a problem that if the phone could not connect to the internet the app crashed as the pictures could not load. Instead I wanted to have a placeholder image saved in my ldpi/mdpi/...etc folders that would be inserted whenever a picture could not be loaded.
My ImageGetter uses URLImageParser which has the following onPostExecute() method:
#Override
protected void onPostExecute(Drawable result) {
//check to see if an image was found (if not could
//be due to no internet)
if(result ==null){
//the drawable wasn't found so use the image not found
//png
Drawable imageNotFound = a.getResources().getDrawable(R.drawable.image_not_found);
result = imageNotFound;
}
intrinsicHeight = result.getIntrinsicHeight();
intrinsicWidth = result.getIntrinsicWidth();
DisplayMetrics dm = new DisplayMetrics();
((WindowManager) c.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels -50;
int height = width * intrinsicHeight / intrinsicWidth;
result.setBounds(0, 0, 0 + width, 0
+ height);
urlDrawable.setBounds(0, 0, 0+width, 0+height);
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
// For ICS
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ height));
// Pre ICS
URLImageParser.this.container.setEllipsize(null);
}
I have simply inserted the if(result==null) statement at the top of this method. But now if the pictures can be loaded the app works perfectly. If the images cannot be loaded and the placeholders are used instead I get some odd behavior.
The scrollview never scrolls to the bottom of the screen, and I have no idea why this is. In theory there should be no difference between my imageNotFound drawable (which is a png file) and the files downloaded off the internet. The scrollview will only move slightly.
I have no idea what is causing this. When searching online most people seem to be having problems with RelativeLayouts. I couldn't find anyone having trouble with drawables or TableLayouts.
My xml for the layout is as follows:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:paddingBottom = "0dip"
android:orientation = "vertical" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1"
android:shrinkColumns="0,1"
android:id = "#+id/SharedTableLayout"
android:paddingBottom = "0dip" >
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingBottom = "0dip">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id = "#+id/SharedTableContent"
android:layout_span="2"
android:gravity = "left"
android:paddingLeft = "10dip"
android:paddingRight = "10dip"
android:paddingTop = "20dip"
android:paddingBottom = "0dip"/>
</TableRow>
</TableLayout>
</ScrollView>
I would really appreciate any suggestions on this, I've been stuck on it for weeks.
Thanks for your time
The TextView with id SharedTableContent displays a string that was converted from html using Html.fromHtml() so the images may be surrounded by text which means I cannot hard code a solution into xml as there is no way of telling how many images there will be to download in advance, thats all done programmatically.
Try changing the layout width of the scrollview to match_parent.
android:layout_width="match_parent"
android:layout_height="match_parent"
Or try this
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="#+id/ScrollView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView android:id="#+id/HorizontalScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/ImageView01"
android:src="#drawable/pic"
android:isScrollContainer="true"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:adjustViewBounds="true">
</ImageView>
</HorizontalScrollView>
</ScrollView>

Best way to display an image from server in android

I am trying to display an image in android. Image needs to be taken from the server. What should be the best approach for making sure that the image stored at the server fits with all android device screens. In the image displaying XML I need to display a textview (below the image) also for giving a brief description about the image. Do I have to create the image with a specific height and width or is there any other approach?
You should store a large enough image on the server.
// Know the required width of the image
URL url = new URL(remotePath);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
inputStream = (InputStream) urlConnection.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, options);
int height = options.outHeight;
int width = options.outWidth;
int sampleSize = requiredWidth / width; // Calculate how you want to sample the images so you can keep the memory small
options.inSampleSize = sampleSize;
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, options);
imageView.setImageBitmap(bitmap);
Hope this helps.
If you want to display on that screen only the image and description below it, you could place the 2 component in a LinearLayout with the orientation vertical and use the layout_weight property of the LinearLayout, for example you could do something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="center" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
You could download the image from the server manually or you could use a library like UIL, or webImageLoader.

Why do I need to wrap an ImageView into a FrameLayout?

Here is a simple layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="40dp" <!-- notice I've limited a height -->
android:scaleType="fitStart"
android:adjustViewBounds="true"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/companyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/companyIcon"
android:layout_marginLeft="3dp"
android:layout_centerVertical="true"
android:textStyle="bold"
android:textColor="#20526d" />
</RelativeLayout>
The height of an image I will set by setImageBitmap() is more that 40dp.
Using this layout I have an extra space between ImageView and TextView, where did it come from?
But after I wrap the ImageView with FrameLayout I don't have this unnecessary extra space:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/image_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:scaleType="fitStart"
android:adjustViewBounds="true"
android:layout_alignParentLeft="true" />
</FrameLayout>
<TextView
android:id="#+id/companyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/image_container"
android:layout_marginLeft="3dp"
android:layout_centerVertical="true"
android:textStyle="bold"
android:textColor="#20526d" />
</RelativeLayout>
And the result:
Can you guys explain why shall I put ImageView into FrameLayout to have things as intended? Thank you very much.
The height of an image I will set by setImageBitmap() is more that 40dp. Using this layout I have an extra space between ImageView and TextView, where did it come from?
Since the android:layout_height="40dp" with a android:scaleType="fitStart", the image is getting scaled down (and to the left/start) to fit the height, so this "extra space" is actually the original width of the image, since your android:layout_width="wrap_content". I recreated your layout with my own image that is larger than 40dp. When you select the ImageView, you can see that its bounds stretch to the image's original width.
To further prove this, if I set android:scaleType="center", no fit is applied and you can see the ImageView's original width.
Can you guys explain why shall I put ImageView into FrameLayout to have things as intended?
It appears that since your FrameLayout uses android:layout_width="wrap_content", it gets the correct scaled down width from your ImageView after it gets scaled due to android:adjustViewBounds="true". It is strange that the ImageView itself uses android:layout_width="wrap_content", but shows the original image's width, and not the scaled width. My hunch is that the height and width of ImageViews get set before the scaling is applied, so the ImageView gets the original image's width, but the parent FrameLayout gets the scaled width of it's ImageView child after the scaling is applied. This may not be true, but it appears that way to me.
However, you can solve the unscaled width issue (without using a FrameLayout) by using android:maxHeight="40dp" on the ImageView. You can then set android:layout_height="wrap_content" so your images can be smaller than 40dp if the image is smaller.
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:maxHeight="40dp"
android:scaleType="fitStart" />
This applies to almost all the view but answer is written considering specifically ImageView
Guideline to set Height and Width
Choose one of this three options only.
Set both height and width to "WRAP_CONTENT"
Set both height and
width to "FILL_PARENT"
Set both height and width to "FIXED SIZE"
*Avoid using mixture of them say Width=WRAP_CONTENT and Height=FILL_PARENT
Guideline to set SCALETYPE for ImageView
What does ScaleType do?
It scale the image you set to the ImageView, It doesn't scale
ImageView so when you set it to fitStart it will scale your image and
show on the right but your imageView will remain same in terms of
height and width as what you have specified.
As if you are using WRAP_CONTENT for height and width you don't need to specify ScaleType cause your ImageView is automatically going to be as big as your image.
As if you are using FILL_PARENT for height and width you will have option to show the image in Center,Start,End or in Full view.. so based on that you can choose your ScaleType.
As if you are using FIXED_SIZE fpr height and width you should opt for scaletype=FITXY.
Guideline to set Image into ImageView
As if you are setting image statically in XML then you have one image on your hand so you can create image of the size you wish as per your layout design and just move on with WRAP_CONTENT.
As if you are setting image at runtime after downloading it from somewhere, that time download the image and create bitmap of the size you prefer and then set it to ImageView
Specific to your case
You can see that your image is quite stretched and the text is not readable that's because you have downloaded and set image as it is but in smaller height and width.. rather you should have done like,
Set ImageView height and width to WRAP_CONTENT in XML file
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" />
Download image in your required size say 50X100, for example see this code
class LoadPics extends AsyncTask<Void, Bitmap, Bitmap> {
String urlStr;
ImageView iv;
int width, height;
public LoadPics(ImageView iv, String url, int width, int height) {
this.iv = iv;
this.urlStr = url;
this.width = width;
this.height = height;
}
#Override
protected Bitmap doInBackground(Void... params) {
try {
InputStream in = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.connect();
in = httpConn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
int scale = 2;
if (o.outHeight > width || o.outWidth > height) {
scale = 2 ^ (int) Math.ceil(Math.log(width
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5));
}
if (scale <= 1 && o.outHeight > 150) {
scale = 5;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap b1 = BitmapFactory.decodeStream(in, null, o2);
b1 = Bitmap.createScaledBitmap(b1, width, height, true);
loader.addToCache(urlStr, b1);
publishProgress(b1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
iv.setImageBitmap(values[0]);
}
}
And call this method with your arguments,
new LoadPics(ivUser,imgURL,100,50).execute();
try to replace android:scaleType="fitStart" with this android:scaleType="fitXY"
Edit
in your image view you should set the width of imagView to wrap-content this will take the size of image. If you hard-code the imageView's width (as you have done it by giving the width to 40dp) then this will not look so good in other android mobile devices.
Still if you want to do so then Try to load image of lesser in resolution. if this image is 200X100 in resolution, then try to load the image of 100X50 in your ImageView
If you do android:scaleType="FIT_END", without the FrameLayout, does that put the Subway image near the "Subway" text? I wonder, because you have android:layout_alignParentLeft="true" in there. I'm thinking that the ImageView's original size before the scaling is what is throwing off the layout without a FrameLayout.
It probably doesn't matter too much, but it does take some processing to scale and resize the image for what you want it to do. If it is viable for what you want to do, I'd simply resize the image myself instead of relying on XML. If I wanted to cater to multiple sizes, I would have a couple of different layouts made. This of course may be overkill for your purpose, I do not know.
Extra space came in first image because u set match parent in image container layout. but second u used wrap content in FrameLayout which is image container.
my suggession to do these thing Create linear layout insider relative layout and apply layout_weight propert so ratio will be same in both view.
try to set the scale type to center_inside.

android - fitting image in imageview

I'm implementing a widget where i'm trying to display a large image inside an image view (8mpx) like this :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" android:id="#+id/widget"
android:background="#000000"
android:padding="15dp"
android:layout_margin="5dp"
android:layout_gravity="top|center_vertical|center_horizontal"
>
<LinearLayout android:background="#ffffff" android:padding="1dp" android:layout_width="wrap_content" android:layout_weight="1"
android:layout_height="wrap_content" >
<ImageView
android:adjustViewBounds="true"
android:id="#+id/image"
android:src="#drawable/sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="top|center_horizontal"
android:scaleType="fitXY"
android:maxWidth="200dip"
android:maxHeight="300dip"
/>
</LinearLayout>
In the emulator everything seems ok, but when i deploy to device, i get the "problem loading widget" message.
the emulator is HVGA and my device has a 480x800 resolution.
Any ideea what am i doing wrong ?
Thank you!
==================================================
As advised by you guys i've made a screenshot of the logcat.
Here it is :
imageview.setScaleType(ScaleType.CENTER_INSIDE);
Try below code
<ImageView
android:adjustViewBounds="true"
android:id="#+id/image"
android:src="#drawable/sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:scaleType="centerInside"
/>
use this
imageview.setImageResource(your_image);
imageview.setScaleType(ScaleType.MATRIX);
Old post, but you never know...
The logcat shows the problem:
"allocation too large for this process"
The image you are trying to render is too large to fit into memory. You need to scale the image down, but don't try to create a scaled version of the bitmap or you'll hit the same problem. The solution is the load the Bitmap into memory but ONLY for it's dimensions, then create a new Bitmap with a sample size that reduces the overall size of the image.
Actually you don't even need to load in the image to get it's original size to do this but it often makes sense so you can choose an appropriate sample size.
e.g.
Assuming your Bitmap is obtained from an InputStream:
InputStream in = ... // Your Bitmap Stream
// Decode JUST the dimensions
Options dimensionOptions = new Options();
dimensionOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, dimensionOptions);
// Get the dimensions of the raw
int rawWidth = dimensionOptions.outWidth;
// Choose a target width for the image (screen width would make sense)
int targetWidth = 480;
// Select the sample size which best matches our target size.
// This must be an int
float sampleSize = (float)rawWidth / (float)targetWidth;
// Assume lower, which will result in a larger image
int sample = (int) FloatMath.floor(sampleSize);
// Use this to decode the original image data
Options scaleOptions = new Options();
scaleOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; // 4 bytes per pixel
scaleOptions.inSampleSize = sample;
// Now create a bitmap using the sample size
Bitmap scaled = BitmapFactory.decodeStream(in, null, scaleOptions);

Categories

Resources