Android app multiple imageviews to be loaded together - android

I have the following layout for an activity that displays 4 870x3700 jpeg images (each around 200KB):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/scrollView2" >
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/testlay">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:id="#+id/imageView1"
android:contentDescription="#string/imageph" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:id="#+id/imageView2"
android:contentDescription="#string/imageph" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:id="#+id/imageView3"
android:contentDescription="#string/imageph" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:id="#+id/imageView4"
android:contentDescription="#string/imageph" />
</LinearLayout>
</ScrollView>
</LinearLayout>
And the below code in my onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
setContentView(R.layout.test_pages);
ImageView imageView1 = (ImageView) findViewById(R.id.imageView1);
ImageView imageView2 = (ImageView) findViewById(R.id.imageView2);
ImageView imageView3 = (ImageView) findViewById(R.id.imageView3);
ImageView imageView4 = (ImageView) findViewById(R.id.imageView4);
imageView1.setImageResource(R.drawable.rsz_17_18_21);
imageView2.setImageResource(R.drawable.rsz_22_25_29);
imageView3.setImageResource(R.drawable.rsz_30_31_36);
imageView4.setImageResource(R.drawable.rsz_37_38);
Now on a tablet I'm able to display them with no problems but when I try to run the app on my mobile phone it throws an out of memory exception. I've tried several different resizing methods without any effect, even with a simple method to calculate the aspect ratio and return a height given the screen width.
How can I adjust the size of all the images in a way to avoid loading the original sized image into memory and make it scale down to the display screen's width while maintaining the aspect ratio?

try following
Calculate first the maximum possible inSampleSize that still yields an image larger than your target.
Second Load the image using BitmapFactory.decodeFile(file, options), passing inSampleSize as an option.
Third Resize to the desired dimensions using Bitmap.createScaledBitmap().
Hope this will help you.
Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);
float originalWidth = originalImage.getWidth(), originalHeight = originalImage.getHeight();
Canvas canvas = new Canvas(background);
float scale = width/originalWidth;
float xTranslation = 0.0f, yTranslation = (height - originalHeight * scale)/2.0f;
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawBitmap(originalImage, transformation, paint);
return background;

Related

How to get Imageview location in android

I want to crop picture got from FrameLayout(#+id/previewFrame) as overlapped ImageView(#+id/guide_line_view) yellow guide line boundary.
I got ImageView location and cropped image what I got from previewFrame camera along the border of ImageView.
But imageview location is different from where it is visible, so cropped image not coincide with what I expect
ImageView(#+id/guide_line_view) is rectangle border xml like this
What's wrong with my crop. I searched stackoverflow, google 7 hours, but nothing helps.
#drawable/guide_line.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#FFFF00"
android:dashGap="8dp"
android:dashWidth="30dp"/>
<corners android:radius="8dp" />
</shape>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<FrameLayout
android:id="#+id/previewFrame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/guide_line_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="100dp"
android:background="#drawable/guide_line"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bring Here"
android:textColor="#FFFF00"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guide_line_view"
app:layout_constraintVertical_bias="0.207" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/take"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="takePicture"
tools:ignore="ButtonStyle" />
<Button
android:id="#+id/close"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="close"
tools:ignore="ButtonStyle" />
</LinearLayout>
</LinearLayout>
To get imageview location
below guide variable asserted as global int
And I calculate at onWindowFocusChanged.
guide_left = imageview.getLeft();
guide_top = imageview.getTop();
guide_width = imageview.getWidth();
guide_height = imageview.getHeight();
I've tried this as well. And so on.
int[] guide_location = new int[2];
imageview.getLocationOnScreen(guide_location);
int guide_left = guide_location[0];
int guide_top = guide_location[1];
crop bitmap
public void takePicture() {
cameraView.capture(new Camera.PictureCallback(){
public void onPictureTaken(byte[] data, Camera camera){
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap r_bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
// crop the image
Bitmap cropped_bitmap = Bitmap.createBitmap(r_bitmap, guide_left, guide_top, guide_width, guide_height);
I save cropped_bitmap and check it is correct, but not.
Supposed you take a picture in resolution 4096×2160 , and then set in previewFrame,
but if your device only have 1920x1080 resolution, the previewFrame only measure size in 1920x1080
As post you want to crop the specified rect from the orgin picture , you need to scale the crop ratio up
from 1920x1080 to 4096x2160
--- Try below ---
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap r_bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
// scaled ratio
float ratio = 1f * bitmap.getWidth() / previewFrame.width;
// crop the image
Bitmap cropped_bitmap = Bitmap.createBitmap(r_bitmap,
(int) (guide_left * ratio),
(int) (guide_top * ratio),
(int) (guide_width * ratio),
(int) (guide_height * ratio));

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>

How to keep images in Android layout proportional like in the original?

I need to place an image (a logo) on top of the android screen and I need it to be as wide as the entire screen and I need its' height to be proportional to the width, the same proportion as in the original image. So far, everything I've tried resulted in misproportioned images or images covering the entire screen. How do I fix this?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#color/blue">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/linearLayout"
android:layout_centerVertical="true"
>
<EditText
android:id="#+id/username"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginLeft="#dimen/margin_main"
android:layout_marginRight="#dimen/margin_main"
android:hint="#string/username"
android:textColorHint="#fff"
android:gravity="center"
android:background="#drawable/input_background"
android:layout_marginBottom="#dimen/margin_main"
android:textColor="#fff"
/>
<EditText
android:id="#+id/password"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:inputType="textPassword"
android:layout_marginLeft="#dimen/margin_main"
android:layout_marginRight="#dimen/margin_main"
android:hint="#string/password"
android:textColorHint="#fff"
android:gravity="center"
android:background="#drawable/input_background"
android:layout_marginBottom="#dimen/margin_main"
android:textColor="#fff"/>
<Button
android:id="#+id/login_button"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:text="#string/login"
android:layout_marginLeft="#dimen/margin_main"
android:layout_marginRight="#dimen/margin_main"
android:background="#drawable/button_yellow_background"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="#color/blue"/>
</LinearLayout>
<ImageView
android:id="#+id/logo"
android:layout_width="315dp"
android:layout_height="100dp"
android:background="#drawable/logo"/>
</RelativeLayout>
The image in question is the logo.
All you need to do is change
<ImageView
android:id="#+id/logo"
android:layout_width="315dp"
android:layout_height="100dp"
android:background="#drawable/logo"/>
to
<ImageView
android:id="#+id/logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/logo"/>
Note: Doing this might result in a stretch image if your image is smaller than the screen width.
Try to set scaleType to fitXY:
<ImageView
android:id="#+id/fullImg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/your_image_resource"
android:scaleType="fitXY" />
If you want to do it at runtime you can do that:
// set the ratio (if it can change it's also possible get it from resource id)
double aspect_ratio = 16/9;
// getting a ref to your ImageView
ImageView yourImageView = (LinearLayout) findViewById(R.id.imageView);
// get DisplayMetrics to get screen sizes
DisplayMetrics met = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(met);
// if you have a "activity_horizontal_margin" in your style
int t = getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
int width = (int)((met.widthPixels-2*t));
// otherwise just
int width = (int)((met.widthPixels-2*t));
// go on calculate height
int height = width * aspect_ratio;
// ending with layour params setting
yourImageView.setLayoutParams(new LayoutParams(width, height);
else if you want to do it in xml, you could do something like that
<ImageView
android:id="#+id/yourImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/logo"
android:scaleType="centerInside" />
You should do that at runtime.
Solution 1
Display display = getWindowManager().getDefaultDisplay();
ImageView imageView = (LinearLayout) findViewById(R.id.imageView);
int width = display.getWidth();
int height = (int) width * 0.75; // 0.75 if image aspect ration is 4:3, change accordingly
imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height);
This would make the image to fill the screen width and height as per the aspect ratio of the original image. To use this method you need to hardcode the aspect ratio.
Solution 2 From Scale Image to fill ImageView width and keep aspect ratio
Create a custom image view and do this
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
Drawable drawable = getDrawable();
if (drawable == null) {
setMeasuredDimension(0, 0);
} else {
float imageSideRatio = (float)drawable.getIntrinsicWidth() / (float)drawable.getIntrinsicHeight();
float viewSideRatio = (float)MeasureSpec.getSize(widthMeasureSpec) / (float)MeasureSpec.getSize(heightMeasureSpec);
if (imageSideRatio >= viewSideRatio) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int)(width / imageSideRatio);
setMeasuredDimension(width, height);
} else {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = (int)(height * imageSideRatio);
setMeasuredDimension(width, height);
}
}
} catch (Exception e) {
e.printStackTrace();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

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

Unable to fill imageview by bitmap, weird behavior

Simple layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context="com.testzoom.app.FullscreenActivity">
<TextView android:id="#+id/fullscreen_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:textColor="#33b5e5"
android:textStyle="bold"
android:textSize="50sp"
android:gravity="center"
android:text="#string/dummy_content" />
<Button android:id="#+id/dummy_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/dummy_button"
android:layout_gravity="bottom"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:id="#+id/dummy_image"
/>
</FrameLayout>
Goal - by pressing button on the bottom, set imageview(which is same size as screen) with screenshot bitmap of half size. Result - weird rendering, why fitXY not working?
Click handler:
findViewById(R.id.dummy_button).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
View view = getWindow().getDecorView();
Bitmap bmp = Bitmap.createBitmap(view.getWidth()/2, view.getHeight()/2, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.scale(0.5f,0.5f, bmp.getWidth(), bmp.getHeight());
view.draw(c);
((ImageView)findViewById(R.id.dummy_image)).setImageBitmap(bmp);
}
});
Result on screenshots:
Note that this task is synthetic so don't ask why I am doing this, this is just demonstration of problem.
The problem lies within the call where you are scaling the canvas. You provide the pivot points which are bmp.getWidth() and bmp.getHeight() which are essentially in the middle of the screen.
findViewById(R.id.dummy_button).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
View view = getWindow().getDecorView();
Bitmap bmp = Bitmap.createBitmap(view.getWidth()/2, view.getHeight()/2, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.scale(0.5f,0.5f);//no pivot points
view.draw(c);
((ImageView)findViewById(R.id.dummy_image)).setImageBitmap(bmp);
}
});
I don't think it's the rendering so much as the placement of the new ImageView. You have all three items in a FrameLayout which does nothing to determine the order or placement of view. Where is the code to place the newly created ImageView?

Categories

Resources