I want to display an image on the screen but the image edges will be larger than the size of the screen itself.
IE if the maximum screen width is X then I want the width of the image will be X +100 and maximum screen height is Y then the image height is Y +100.
I want this option for the ability to move the image to the right / left and still the image will be shown on the whole screen.
For this purpose I use RelativeLayout with requestLayout function:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="#+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
And in the code generate an appropriate image:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
// example code with bigger dimensions than the screen
Bitmap b = Bitmap.createBitmap(width + 100, height + 100, Bitmap.Config.ARGB_8888);
// draw smth on the bitmap
Canvas c = new Canvas(b);
Paint p = new Paint();
p.setColor(Color.RED);
c.drawCircle(b.getWidth() / 2,
b.getHeight() / 2,
Math.min(b.getWidth(), b.getHeight()) / 2,
p);
// set the image
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(b);
// call this method to change imageview size
iv.requestLayout();
Related
Let's say I have a horizontally long image, "grass". Now, I want to use it as a background image for views, but I want to dock it to the bottom. After searching the web, I discovered that I need to wrap the image as a drawable like:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/grass"
android:gravity="bottom|left" />
The problem is that the image is clipped to the right. So I have tried bottom|left|right but then the aspect ratio was not kept. Can I make the image fit horizontally, but keep the aspect ratio by automatically scaling it vertically? Or is this not possible with drawables?
what your searching for is centerInside ScaleType . please remove the ScaleType from the ImageView and try this :
public static synchronized Bitmap centerInside(Bitmap bitmap,int width,int height){
if(bitmap.getWidth() == bitmap.getHeight()){
Log.i("crop","already matched");
return Bitmap.createScaledBitmap(bitmap, width, height, true);
}
//int size = width > height ? width : height;
float scale = ImageUtils.calculateImageSampleSize(bitmap.getWidth(), bitmap.getHeight(),width,height);
width = (int) ((float)bitmap.getWidth() / scale);
height = (int) ((float)bitmap.getHeight() / scale);
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
if (bitmap.getWidth() >= bitmap.getHeight()){
bitmap = Bitmap.createBitmap(
bitmap,
bitmap.getWidth()/2 - bitmap.getHeight()/2,
0,
bitmap.getHeight(),
bitmap.getHeight()
);
}else{
bitmap = Bitmap.createBitmap(
bitmap,
0,
bitmap.getHeight()/2 - bitmap.getWidth()/2,
bitmap.getWidth(),
bitmap.getWidth()
);
}
return bitmap;
}
You cannot achieve this with XML only. If you don't want to have to draw the bitmap programmatically, you wrap an ImageView in a RelativeLayout and set the ImageView's scaleType property:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/grass"
android:scaleType="fitXY" />
</RelativeLayout>
If I understand Your requirement right Your image need to stretch vertically and be in bounds horizontally.
A good solution I could suggest is creating a 9 patch image out of Your drawable and define the area where the image can stretch.
You can use this tutorial for reference.
I have a cardview with an ImageView aligned to bottom left.
I am getting the height of the ImageView and setting it as the height of the bitmap.
iv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int height = iv.getMeasuredHeight();
Paint widthPaint = new Paint();
widthPaint.setTextSize(200f);
float width = widthPaint.measureText(text);
Bitmap bmOverlay = Bitmap.createBitmap((int) width + S.dpToPx(ctx, 20), height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
canvas.drawColor(Color.argb(220, 244, 244, 244));
paint.setColor(Color.TRANSPARENT);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
paint.setTextSize(200f);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, canvas.getWidth() / 2, (canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2), paint);
iv.setImageBitmap(bmOverlay);
}
});
The output of both iv.getMeasuredHeight(); and bmOverlay.getHeight() is 120. But the bitmap is not covering the ImageView. I cannot understand why.
XML of the ImageView.
<ImageView
android:id="#+id/rquiz_iv_topic"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
What you want to archive: Set ImageView exactly size with the Bitmap is something wrong.
You needs to fits all the phone screen instead of settings it View by pixel.
You can:
1. Respect Parent Way:
Put ImageView in LinearLayout, Set Weight as 0.5 (means fits 50% of LinearLayout), and set related (Vertical or Horizontal) Height or Width to 0dp(to let Layout Manager to handles the size).
And, set your image scale to fitXY / centerCrop.(Or you can try other scaling)
2.Respect Bitmap Way:
Put ImageView in RelativeLayout, set other nearby Views to stand with ImageView by layout_alignBottom/layout_alignLeft etc. And set ImageView Height and/or Width to wrap_content, let the Layout handles the size.
In your imageview set scaleType="centerInside" and adjustViewBounds="true".
<ImageView
android:id="#+id/rquiz_iv_topic"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:scaleType="centerInside"
/>
Refer for more details ImageView.ScaleType
I'm using the HorizontalScrollView and I want to put images inside it but images will be larger than the screen and makes users scroll horizontally while I'm using setScaleType(ImageView.ScaleType.CENTER_CROP) or other attributes.
How can I have images completely fit the screen? I prefer to use XML attributes if it is possible.
activity_main.xml
<HorizontalScrollView
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">
<LinearLayout
android:id="#+id/main"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
MainActivity.java
ImageView image = new ImageView(this);
image.setImageResource(getResources().getIdentifier('file_name', "drawable", getPackageName()));
image.setAdjustViewBounds(true);
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
image.setLayoutParams(layoutParams);
parent.addView(image);
You can use this xml property into your ImageView,
android:scaleType="fitXY"
Or use this dynamic code snippet to fit the ImageView accordingly the screen ratio,
private void scaleImage(ImageView view, int boundBoxInDp)
{
// Get the ImageView and its bitmap
Drawable drawing = view.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// Determine how much to scale: the dimension requiring less scaling is
// closer to the its side. This way the image always stays inside your
// bounding box AND either x/y axis touches it.
float xScale = ((float) boundBoxInDp) / width;
float yScale = ((float) boundBoxInDp) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
// Create a matrix for the scaling and add the scaling data
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
// Create a new bitmap and convert it to a format understood by the ImageView
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
BitmapDrawable result = new BitmapDrawable(scaledBitmap);
width = scaledBitmap.getWidth();
height = scaledBitmap.getHeight();
// Apply the scaled bitmap
view.setImageDrawable(result);
// Now change ImageView's dimensions to match the scaled image
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
private int dpToPx(int dp)
{
float density = getApplicationContext().getResources().getDisplayMetrics().density;
return Math.round((float)dp * density);
}
And sample code for testing:
ImageView image = new ImageView(this);
scaleImage(image , 250); // in dp
Here's the output,
Before,
After,
Source: Scale image into ImageView, then resize ImageView to match the image
I'm trying to scale and crop image at the same time and show it from left to right screen edge. I receive image that is just little bit wider than users screen and I'm able to scale it like this (XML):
<ImageView
android:id="#+id/category_image_top"
android:layout_width="match_parent"
android:layout_height="170dp"
android:maxHeight="170dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:focusable="false"
/>
But this is what I get:
I would like to align image to top right like so:
Is this possible? I've tried all scaleTypes but noting works, image is either scaled to fit by X and Y (fitXY, fitStart) or image cropped but centered (centerCrop). I need something like android:scaleType="cropStart"
<ImageView
android:id="#+id/category_image_top"
android:layout_width="match_parent"
android:layout_height="170dp"
android:maxHeight="170dp"
android:scaleType="centerCrop"
android:paddingLeft="half of your screen width"
android:paddingBottom="half of your screen height"
android:adjustViewBounds="true"
android:focusable="false"
/>
You can set padding to move image left or right and also top and bottom padding to move up and down
As I didn't find a way to deal with this situation through xml (views) I turned (as #serenskye suggested) to code. Here's my code, I hope it helps (ps: I've changed my logic a little bit, I wanted to fit image by width so I've scaled it to predefined imageWidght and then cropped it to imageHeight)
//bm is received image (type = Bitmap)
Bitmap scaledImage = null;
float scaleFactor = (float) bm.getWidth() / (float) imageWidth;
//if scale factor is 1 then there is no need to scale (it will stay the same)
if (scaleFactor != 1) {
//calculate new height (with ration preserved) and scale image
int scaleHeight = (int) (bm.getHeight() / scaleFactor);
scaledImage = Bitmap.createScaledBitmap(bm, imageWidth, scaleHeight, false);
}
else {
scaledImage = bm;
}
Bitmap cropedImage = null;
//if cropped height is bigger then image height then there is no need to crop
if (scaledImage.getHeight() > imageHeight)
cropedImage = Bitmap.createBitmap(scaledImage, 0, 0, imageWidth, imageHeight);
else
cropedImage = scaledImage;
iv.setImageBitmap(cropedImage);
add
android:layout_gravity="center"
Android: how to set the height/width of the image(src image intead of the background) of a ImageButton?
I want to set the height/width of the top level image(not the background) image, the size of image should be customized instead of fullfill the button automatically
You can just Use the scaleType attribute of ImageButton.
Set it to fitXY or fitCenter or anything else according to your need.
like this
<ImageButton
android:id="#+id/imageButton"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitCenter"
android:src="#drawable/some_image">
</ImageButton>
You can use Bitmap.createScaledBitmap to scale the image to the size you want.
Bitmap image = ... //load image from your source
image = Bitmap.createScaledBitmap(image, desiredHeight, desiredWidth, true);
xml
<ImageButton
android:id="#+id/picture_id"
android:layout_width="10dp" //here width with unit. 5 dp exemple
android:layout_height="3dp" //here height with unit. 3 dp exemple
android:src="#drawable/picture_name"
/>
EDIT: (java code)
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
ImageView imageView = new ImageView(this);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
// center the Image
imageView.setScaleType(ScaleType.CENTER);
// add ImageView to the Layout
linLayout.addView(imageView,
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
)
);
I had same problem... change the size of 'src' image of image button(not the size of button just image only).
what i did--
I moved those '.png' file from 'drawable' folder to 'drawable-hdpi' folder.
weird... but it worked.
thanks,
set padding and scaletype to centerInside
Padding will help you customize the source image to provide the required height and width.
<ImageButton
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/location"
android:padding="10dp"
android:scaleType="centerInside"
android:background="#drawable/blue_circle_border"/>