setImageBitmap() modifies the predifined layout - android

I prepared a layout with 2 images of same size in a vertical LinearLayout so both appear with exact same size in AS.
The layout is as follow:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/partner_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/fake_background" />
<LinearLayout
android:id="#+id/partner_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="0dp">
<ImageView
android:id="#+id/imageGuide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/partner_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="0dp"
>
<ImageView
android:id="#+id/partner_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
<ListView android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="1dp"
android:background="#F2F2F2"/>
<ListView android:id="#+id/right_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="1dp"
android:background="#F2F2F2"/>
</android.support.v4.widget.DrawerLayout>
The RelativeLayouts are here because I will have some other objects in.
If I execute it on my device, everything is ok, I get the exact same rendering.
But now, I want to change the bottom logo with one downloaded from my server.
I download the exact same image and then, I set it like that:
ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageBitmap(bitmap);
}
When I look at bitmap in the debugger, the image is 512x512 as expected.
But the result is that one:
Could you tell me why the layout is modified?
Edit
I made some tests to try to set both images programmatically and I discovered that using:
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageBitmap(bitmap);
}
set an image smaller than using:
partnerLogo.setImageDrawable(getResources().getDrawable(R.drawable.my_logo));
But both images are exactly the same PNG images!?!
So I think the problem comes from setImageBimap() and not from the layout.
EDIT 2
According to many post about similar problems, it seems that Android needs a drawable to be able to scale it as needed.
That would confirm my experiment given in first EDIT.
So I tried that:
ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
BitmapDrawable drawable = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
if (bitmap != null) {
drawable = new BitmapDrawable(getResources(), bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageDrawable(drawable);
}
But that doesn't work better !?!

On your layout on the LinearLayout add android:weightSum="2"
On your both RelativeLayout containing a ImageView change android:layout_height="wrap_content" to android:layout_height="0dp"
But those RelativeLayout are superfluous you can remove it and put on the ImageView's
android:layout_height="0dp"
android:layout_weight="1"
This ensures that the vertical space will be divided between the two images

Just modified relevant code. Add it and check.
Modification Like:
Adding weightSum to LinearLayout
Giving equal weight to the LinearLayout's immediate children
Modified your LinearLayout (partner_layout ).
This is just modified piece of your XML file.
<LinearLayout
android:id="#+id/partner_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:orientation="vertical">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:padding="0dp">
<ImageView
android:id="#+id/imageGuide"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/partner_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:padding="0dp">
<ImageView
android:id="#+id/partner_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo" />
</RelativeLayout>
</LinearLayout

Our first aim should be how to resolve the issue.It seems that it could be handled by your xml layout.
So in my suggestion if you are using relative layout try to fix width and height of your imageView.
Other wise try some other layout like tableLayout, frameLayout or gridLyout and try to change width and height of your imageview with various available option(match_parents/wrap_content etc or also try with fix size).and also add
android:scaleType="fitXY"
Hope this will resolve your issue.

When You set Images from Drawable then Android system Automatically resize that image accrding available width and height but when you set Any image using setImageBitmap() method it dose not resize and actual image shown.
Although the system performs scaling and resizing to make your
application work on different screens, you should make the effort to
optimize your application for different screen sizes and densities. In
doing so, you maximize the user experience for all devices and your
users believe that your application was actually designed for their
devices—rather than simply stretched to fit the screen on their
devices.
Find your solution and more details regarding Images,Bitmap scaling and resizing ,drawables in below links :
How to stop Android form automatically scaling drawables?
Supporting Multiple Screens

So the only solution I found is to scale the image by hand, based on the layout built with fake images.
And the code is based on the one found quiet a long time ago somewhere in SO:
final ImageView myLogo = (ImageView) findViewById(R.id.image_logo);
bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.my_logo_512x512);
final ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
try {
bitmap2 = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
ViewTreeObserver vto = myLogo.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myLogo.getViewTreeObserver().removeOnPreDrawListener(this);
finalHeight = myLogo.getMeasuredHeight();
finalWidth = myLogo.getMeasuredWidth();
pictureWidth = bitmap.getWidth();
pictureHeight = bitmap.getHeight();
float ratioImage = (float)pictureWidth / (float)pictureHeight;
float ratioView = (float)finalWidth / (float)finalHeight;
if (ratioView > ratioImage) { // finalHeight is the limit
finalWidth = (int)((float)pictureWidth * ((float) finalHeight / (float) pictureHeight));
} else { // finalWidth is the limit
finalHeight = (int)((float)pictureHeight * ((float) finalWidth / (float) pictureWidth));
}
bitmap = Bitmap.createScaledBitmap(bitmap, finalWidth, finalHeight, false);
myLogo.setImageBitmap(bitmap);
if (bitmap2 != null) {
bitmap2 = Bitmap.createScaledBitmap(bitmap2, finalWidth, finalHeight, false);
partnerLogo.setImageBitmap(bitmap2);
}
return true;
}
});
}
I saw that a comic downvoted my question, I hope that next time he will motivate it.

Related

Bitmap get croped when setting to Image inside scrollview

Scrollable Imageview, Image will be inside the scrollview in framelayout, and that layout will have fix size and image will be scrolled.
So When runtime changing size of framelayout, affecting bitmap and get crop from the bottom and the size of framelayout changed and also imageview size.
Only the problem with the bitmap croped
Layout.xml
<FrameLayout
android:id="#+id/frameLayout_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/grid">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scrollbars="none">
<ImageView
android:id="#+id/image_picture"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</FrameLayout>
Programatically changing the framelayout like
private void changeSizeOfImage(int width,int height){
mImageViewImage.destroyDrawingCache();
mImageViewImage.buildDrawingCache();
mFrameLayoutImageMain.setLayoutParams(new LinearLayout.LayoutParams(width, height));
if (bitmap != null) {
mImageViewImage.setImageBitmap(null);
mImageViewImage.setImageBitmap(bitmap);
}
}
}

Android - Image coming from web service has different size on different devices

I know there are lots of question about this topic. But still I need help. I want to show my ImageView has equal width and height in my TableLayout. But on different devices I couldn't be able to do this.
Here is I get the image using URL in AsyncTask, and set the ImageView on onPostExecute method.
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
// set the imageview
bmImage.setImageBitmap(result);
}
Here is my XML file (news.xml) where my ImageView located
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:paddingBottom="10dp"
android:id="#+id/mylayout"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image"
android:clickable="true"
android:background="#drawable/border"/>
<TextView
android:layout_width="match_parent"
android:layout_height="75dp"
android:maxLines="4"
android:id="#+id/text"
android:layout_below="#+id/image"
android:layout_alignEnd="#+id/image"
android:layout_alignRight="#+id/image"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</RelativeLayout>
I thought that I can create a TableLayout, and locate the View (above) inside a TableRow like, side by side 2 view.(view is above)
To do this I get the screen width and subtract the paddings and divide by 2 and give that width to the ImageView to be able to get same size for all image views.
Here is my code,
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
tableLayout = (TableLayout) view.findViewById(R.id.tableLayout);
Log.e("screenwidth",":"+screenWidth);
// here is my paddings converted to pixel and will be subtracted from screen width
int pixValue = (int) (20 * Resources.getSystem().getDisplayMetrics().density);
int imageWidthPix = ( screenWidth - pixValue ) / 2;
Log.e("imageWidthPix ",":"+imageWidthPix );
for (int i = 0; i < categoryNews.get(myString).size(); i++) {
if (i % 2 == 0) {
tr = new TableRow(getActivity());
tableLayout.addView(tr);
}
//here is where my ImageView layout (news.xml)
View oneNews = inflater.inflate(R.layout.news, null);
ImageView imageView = (ImageView) oneNews.findViewById(R.id.image);
TextView textView = (TextView) oneNews.findViewById(R.id.text);
//here I set the width as I want
imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidthPix, RelativeLayout.LayoutParams.WRAP_CONTENT));
String imagePath = "http://my.url.com/" + categoryNews.get(myString).get(i).getImagePath();
new DownloadImageTask(imageView,getActivity().getApplicationContext())
.execute(imagePath);
I got the perfect result on my phone. But on the different device which has different screen size, ImageView has spaces on top and bottom. I tried to convert nine patch chunk and convert that into again bitmap but there were no difference. If I wouldn't get the images from web service, I would put other resolution images into mipmap-hpdi, mipmap-mdpi etc folders and there would be no error. But I am getting images dynamically so how can achieve that ImageView has half of screen width?
Thanks in advance.
Here I have edited your xml
Try Linear layout with weights,change the weight according to your need, change the layout_weight to make your image view and textview smaller or larger.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:orientation="vertical"
android:id="#+id/mylayout"
android:weightSum="10">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:id="#+id/image"
android:src="#drawable/sd"
android:clickable="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:maxLines="4"
android:id="#+id/text"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</LinearLayout>

Layout issue in different device in Android

I have Imageview inside a framelayout. I have set scaletype for imageview as MATRIX, but it's looks different in different devices.
Here is layout I used:
<FrameLayout
android:id="#+id/canvasView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible"
tools:context=".MainActivity">
<ImageView
android:id="#+id/img_baseview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="matrix" />
<Utils.DrawingHelper
android:id="#+id/drawing"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#00000000"
/>
</FrameLayout>
In my Java file I am displaying image
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
actualImageBitmap = BitmapFactory.decodeFile(new File(Datas.received_uri.getPath()).getAbsolutePath(), options);
ImageViewHeight = options.outHeight;
ImageViewWidth = options.outWidth;
img_baseview.setScaleType(ImageView.ScaleType.MATRIX);
canvasView.getLayoutParams().height = ImageViewHeight;
canvasView.getLayoutParams().width = ImageViewWidth;
canvasView.requestLayout();
Log.e("ESize", ImageViewWidth + "---" + ImageViewHeight);
Log.e("ESize", canvasView.getHeight() + "---" + canvasView.getWidth());
try {
actualImageBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Datas.received_uri);
bitmapMaster = actualImageBitmap;
effect_bitmap = bitmapMaster;
} catch (IOException e) {
e.printStackTrace();
}
// img_baseview.setImageURI(Datas.received_uri);
img_baseview.setImageBitmap(actualImageBitmap);
use CENTER_INSIDE
Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding). The image is then centered in the view. From XML, use this syntax: android:scaleType="centerInside".
instead of MATRIX
remve img_baseview.setScaleType(ImageView.ScaleType.MATRIX);
Check out
<FrameLayout
android:id="#+id/canvasView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Utils.DrawingHelper
android:id="#+id/drawing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:layout_alignLeft="#+id/img_baseview"
android:layout_alignStart="#+id/img_baseview"
android:layout_alignRight="#+id/img_baseview"
android:layout_alignEnd="#+id/img_baseview"
android:layout_alignTop="#+id/img_baseview"
android:layout_alignBottom="#+id/img_baseview" />
<ImageView
android:id="#+id/img_baseview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="centerInside"
android:src="#mipmap/ic_launcher"/>
</RelativeLayout>
</FrameLayout>

Resize ImageView even if ScaleType

I have a problem, I'm trying to resize a ImageView and its parent container but the problem is that the ImageView has ScaleType:"matrix", and I cant`t resize the image or its container
this is my code:
public void resize() {
LayoutParams contet = relativeLayout.getLayoutParams();
LayoutParams photo = image.getLayoutParams();
int widPhoto = image.getWidth();
int hePhoto = image.getHeight();
photo.width = ((widPhoto * 6) / 2);
photo.height = ((hePhoto * 6) / 2);
contenedor.width = widPhoto * 2;
contenedor.height = hePhoto * 2;
relativeLayout.setLayoutParams(contenedor);
image.setLayoutParams(photo );
}
and my xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/containerImg"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="matrix" />
</RelativeLayout>
setLayoutParams() does nothing but remove the property ScaleType if I resize everything correctly, but I cant´t remove that property. Any way to resize? they could put the property ScaleType: NONE? thank you very much and sorry for my bad English
To resize your ImageView, I suggest to use FrameLayout:
<FrameLayout
android:id="#+id/fm_id"
android:layout_width="img_width"
android:layout_height="img_height"
... ...
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:gravity="center"
/>
</FrameLayout>
then you just need to resize 'img_width' and 'img_height' in your codes
I got the solution, if you are using the Layout ScaleType: matrix
you need to use matrix.setScale (); for Resizing

Adapt ImageView for show picture correctly

I have some pictures stored on internal storage, that have different sizes and i would like to show it inside a scrollview contains imageview. I would that in each dimension case (image wider than higher, image higher than wider, squared image) image occupy entire screen width.
But code i've write for do that doesn't work well. If an image is squared or higher than wider everithing works well, but not if image is wider than higher.
this is xml of scrollview
<RelativeLayout
....
>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/linearInsideScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
and this is xml of single imageView that i will inflate inside layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
othed widget
-->
<ImageView
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
and this is how i fill my view (pics is a list object contains image informations):
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearInsideScroll);
for (int i = 0; i < pics.size(); i++) {
View new_element = inflater.inflate(R.layout.single_element, null,
false);
if (pics.get(i).getWidth() > pics.get(i).getHeight()) {
imageView.getLayoutParams().width = width_px;
imageView.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
} else if (pics.get(i).getWidth() < pics.get(i).getHeight()) {
imageView.getLayoutParams().height = height_px;
imageView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
}
else {
imageView.getLayoutParams().height = width_px;
imageView.getLayoutParams().width = width_px;
}
linearLayout.addView(new_element);
}
For the imageView, set scaleType.
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

Categories

Resources