Scale images in android relative to screen width - android

I have a layout with two images:
one that should strech to the screen width
one above it that should scale to the same proportion the first one was automaticaly scaled (relative to the original image size)
More specific: the two images are slices of the same image, and therefore some details inside them should match.
Can I make this in XML?
If I cannot do it through XML, maybe I could prescale the graphics. In this case, how should I prescale them?

This is a bit of a hack, but it would allow you to do this in xml.
If you know that, for example, the top image is X% of the size of the bottom one, then you can use LinearLayout's layout_weight to position and size the top image in terms of percentage of the screen:
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView android:id="#+id/left_filler" android:layout_weight="20"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<ImageView android:id="#+id/top_image" android:layout_weight="50"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<ImageView android:id="#+id/right_filler" android:layout_weight="30"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
... bottom image
The above would size top_image at 50% of the screen with an offset of 20% from the left. As long as top_image is 50% the size of bottom_image, this will keep similar scale.
Alternatively, the "right" way to do this is probably to override onDraw() in a custom view and use canvas drawing methods.

You could use the Canvas class method drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
for drawing the specified bitmap by scaling/translating automatically to fill the destination rectangle. This can be used for both the bitmaps with different Rect. The Rect can be formulated by dividing the current width and height of the layout. So that the program will scale the images in accordance with devices having different screen size.

Related

Showing a full-width ImageView containing a SVG distorts it

My aim is to show a SVG background image filling the whole screen's width, in a ConstraintLayout. A Button is superposed to this background image, that's why you can see in the mock-up below:
The background image is the one that contains the stars. Its start and end sides would be constrained to the root GroupView, so that it would fill entirely the width of the screen.
The problem is the following: whether I bind the bottom side to the bottom side of the screen or not, the background image appears distorded, as illustrated in the following:
Here is the code I've written:
<ImageView
android:id="#+id/imageView16"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/ic_background_stars"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/linearLayout4" // "linearLayout4" is just a widget shown above, it's not an important element for this StackOverflow question
/>
<Button
android:id="#+id/button_home_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:background="#color/colorRoyalRedLight"
android:text="TextView"
android:textAllCaps="false"
android:textColor="#color/white"
app:layout_constraintStart_toStartOf="#+id/imageView16"
app:layout_constraintEnd_toEndOf="#+id/imageView16"
app:layout_constraintTop_toTopOf="#+id/imageView16"
app:layout_constraintBottom_toBottomOf="#+id/imageView16"
/>
My question
How could I use my SVG image as a background image that would appear without any distorsion, filling the whole screen's width? The height can of course adapt itself (to keep good proportions), but shouldn't be shorter (in Y and in X) than the button.
For the ImageView try setting android:scaleType="centerCrop". See ImageView.ScaleType.
CENTER_CROP
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 larger than the corresponding dimension of the view (minus padding). The image is then centered in the view. From XML, use this syntax: android:scaleType="centerCrop".

Crop image and retain positioning android

I have two images that are positioned in the same space, effectively overlapping one another.
They are slightly different but identically sized.
I want to be able to crop the top laying image but retain the initial positioning.
So almost like cutting it in half, and keeping the left half in place, which would perfectly overlap the underlaying image.
The following is the code I have, just two ImageView's within a FrameLayout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="380dp"
android:layout_height="wrap_content"
android:src="#drawable/level_off">
</ImageView>
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="190dp"
android:layout_height="wrap_content"
android:src="#drawable/level_on">
</ImageView>
</FrameLayout>
Any ideas? I've done my best to explain what I mean! Thanks!
You could try an programmatic approach by inheriting ImageView and override onDraw(), doing so will also save you an extra layout group.
In onDraw()you have to:
obtain the imageMatrix from your original image
alter the canvas to left/right half of your original size
draw the second image in that altered canvas with the same matrix as the original image
I've done a similar thing and theoretically it should work for your case as well.

Android bitmap rotate canvas crops/cuts image

bmpAndroidMarker = BitmapFactory.decodeResource(context.getResources(), R.drawable.t_move2);
bmpAndroidMarkerResult = Bitmap.createBitmap(bmpAndroidMarker.getWidth(), bmpAndroidMarker.getHeight(), Bitmap.Config.ARGB_8888);
Canvas tempCanvas = new Canvas(bmpAndroidMarkerResult);
tempCanvas.rotate(direction+45, bmpAndroidMarker.getWidth()/2, bmpAndroidMarker.getHeight()/2);
tempCanvas.drawBitmap(bmpAndroidMarker, 0, 0, null);
This it the code I have written (borrowed). The icon is generated within an imageview, inside a listview.
My problem is that on rotating this 'arrow', it seems that it 'clips' part of the far edges off, as if it were keeping the original bitmap's dimensions. I can't figure out how to allow it to 'overflow' and render the correct size image.
Is there some way of doing this?
You're rotating the Image by 45 degrees so the resultant Bitmap should be the width of the original plus the originals diagonal width (Pythagoras' Theorem should be able to help).
AFAIK you'll need to do that Maths yourself when creating the result Bitmap as that's the canvas which is being drawn upon, rotating it's contents will not rotate the container.
Try wrapping your ImageView in a FrameLayout and setting the frame layout's width and height as the size of the image you are trying to render. You can do this in the view's layout file like ...
<FrameLayout
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="YOUR IMAGE WIDTH"
android:layout_height="YOUR IMAGE HEIGHT">
<ImageView
android:scaleType="matrix"
android:layout_width="YOUR IMAGE WIDTH"
android:layout_height="YOUR IMAGE HEIGHT"
android:src="#drawable/YOUR IMAGE FILE" />
</FrameLayout>
... or in a programmatic way by building your FrameLayout with your specified dimensions then adding your ImageView as a subview.
If your image is bigger than the screen you can use android:scaleType="matrix" to keep it from scaling and ensure your aspect ratio is retained.
This was originally answered by Pavlo Viazovskyy here. Credit where credit is due!

How to create an ImageView that fills the parent height and displays an Image as big as possible?

I have an ImageView that is defined in the following way:
<ImageView
android:id="#+id/cover_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/title"
android:layout_above="#id/divider"
android:adjustViewBounds="true"
android:src="#drawable/image_placeholder"
android:scaleType="fitStart"/>
Now after downloading a new bitmap I change the drawable. The image now appears in the top left corner of the ImageView. Is there a way to have the image fill up the whole height that is possible and then adjust the width of the view to enable scaling the image without changing the ascpect ratio?
The image fills up all the space on a standard screen but on a WVGA Resolution the image takes only about half of the actual height of the ImageView.
If I'm understanding you correctly, what you need to use is the centerCrop scaleType. fitStart scales the image proportionally, but neither the width nor height will exceed the size of the view, and the image will, as you said, have a top|left gravity.
Using centerCrop scales the image proportionally, but causes the shortest edge of the image to match the size of the view, and if there is additional data on the long side that does not fit, it is simply cropped off. The gravity is, of course, center. The below worked for me:
<ImageView
android:src="#drawable/image_placeholder"
android:id="#+id/cover_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
/>
You can change scale type to fitXY via call to
imageView.setScaleType(ScaleType.FIT_XY);
simply do it in xml like
android:scaleType="fitXY"
Basically the answer here is that there is no predefined value for what you are trying to achieve. The solution is to create a Matrix that fits to your needs and call setImageMatrix(matrix) on your ImageView.

Android image scaling and alignment

I'm trying to show an image scaled while preserving its aspect ratio, but at the same time align it to the bottom.
Using android:scaleType="FitXY" causes the image to be centered vertically and horizontally, so it doesn't get aligned to the bottom.
Using "FitEnd" causes the image to be aligned to the bottom right corner, so it isn't centered horizontally.
Is there any way to get around this? Maybe using some matrix to scale it (scaleType="matrix")?
EDIT: To clarify a bit on what it is I want exactly...
I have an ImageView, whose layout (location, size, gravity, etc.) I can't change. I want to load a bitmap as its source image, but have that bitmap get scaled to the ImageView's size (preserving the aspect ratio of the bitmap) and then aligned to the ImageView's bottom.
EDIT: After trying everything I could think of (and everything that was suggested here), we ended up sub-classing ImageView and doing the scaling/translation ourselves in onDraw.
Try using android:scaleType="centerInside" instead of fitXY.
Layout being used in a Blrfl Labs application to scale an image to fit the area the layout gives it without hosing up the aspect ratio:
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1.0"
android:gravity="center"
android:src="#drawable/blah_blah_blah"
android:scaleType="centerInside"
android:adjustViewBounds="false"
/>
You can use
android:layout_centerHorizontal="true"
android:scaleType="fitEnd"
if your ImageView is inside a RelativeLayout.
Untested, but try adding:
android:layout_gravity="bottom|center_horizontal"
to your ImageView along with FitXY scaling.

Categories

Resources