Align large image inside the ImageView without scaling - android

I am trying to display a large image (wider than screen) inside the ImageView and I use matrix scale type.
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/pizza_intro_test"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:scaleType="matrix"
/>
However, I am not able to align the image inside the ImageView. I would like to display "right" part of the image but ImageView displays "left" part instead.
This is the current state:
This is the state I am trying to achieve:

Checkout Matrix.setRectToRect method and try to implement it.
http://developer.android.com/reference/android/graphics/Matrix.html#setRectToRect%28android.graphics.RectF,%20android.graphics.RectF,%20android.graphics.Matrix.ScaleToFit%29

Try setting the gravity of your imageview to right.
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:src="#drawable/pizza_intro_test"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:scaleType="matrix"
/>

I did something similar by setting source and destination Rect. The trick is to use negative value on the destination Rect. That way you can "start drawing" the left side of the image outside the visible canvas, and the right side will be drawn on the canvas itself.
The destination rect should be something like this:
float scale = canvas.getHeight() / (float)bm.getHeight();
Rect dest = new Rect(canvas.getWidth()-bm.getWidth()*scale,canvas.getWidth(), canvas.getHeight())
you can define it on the onDraw() and use it with
canvas.drawBitmap(bm, null, mDstRect, mPaint);
You don't need to set any scaleType on the XML or code.

Maybe this is too late, but even I ran into the same problem today and fixed it by using the following snippet.
All the alignment/scaling options are in the scaleType attribute.
Now, if you want to align the image with the beginning of the ImageView, use android:scaleType="fitStart".
Similarly, android:scaleType="fitEnd" to align it with the bottom of the ImageView.

Related

Scaling an Image on Android makes the Image render outside the ImageView boundaries

I am trying to scale an image inside an ImageView, but I want the image to get cropped if it goes outside the view boundaries. This is what it looks like. The image just gets rendered outside the View boundaries. I have tried all the different forms of android:scaleType and android:adjustViewBounds but none of them work to keep the image inside those boundaries. Basically what I want to have as an end result is an image that can zoom in and zoom out but when you zoom in, the image gets cropped to fit in the space. Maybe this is one of those things that is just not possible?
android:layout_width="wrap_content"
android:layout_height="wrap_content"
means that the view will adjust its size in acordance with the content. If you want the image to crop, specify those, e.g.
android:layout_width="40dp"
android:layout_height="40dp"
scaleX and scaleY is scalling the image. Removing both will solve your problem. Also give it a fixed height and width.
Edit these lines
android:layout_width="50dp"
android:layout_height="50dp"
And remove these lines
android:scaleX="2"
android:scaleY="2"

Scaling and anchoring an image within an imageview

I am currently using a custom ArrayAdapter for a list. List items span the whole width of the screen so on some devices are very wide.
I overlay an ImageView on some of the list items which you can swipe to dismiss.
The xml for the ImageView is below:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:scaleType="matrix"
android:src="#drawable/myImage" />
The view is placed correctly, but in order for the image to fit devices with really wide screens, or in landscape mode, the image has to be very wide.
The problem is, I want to scale the image to fit vertically (i.e. fitY which doesn't exist as a scaleType, then to anchor the image to the left of the view, and for everything that doesn't fit to be cropped.
I have tried all of the scaleType values, and none of them are quite right. As such, I felt I should probably use matrix and define my own translation for the image, so I tried this in getView:
//snipped out code before to initiate variables etc.
Drawable src = imageView.getDrawable();
//scale by the ratio of the heights.
int scaleFactor = imageView.getHeight() / src.getIntrinsicHeight();
Matrix imageMatrix = new Matrix();
//set the scale factor for the imageMatrix
imageMatrix.setScale(scaleFactor, scaleFactor);
//set the translation to be 0,0 (top left);
imageMatrix.setTranslate(0,0);
//assign the image matrix to the imageview.
imageView.setImageMatrix(imageMatrix);
But this is not having any effect at all (even if I make the values really crazy). I presume I am setting the imageMatrix in the wrong place - is there an onDraw() event I can hook into for a custom ArrayAdapter subclass?
Or am I going about solving the problem in completely the wrong way?
In the end I had to explicitly set imageView.setScaleType(ScaleType.MATRIX); in code, then apply my imageMatrix to it. Using the xml attribute scaleType="matrix" didn't seem to work.
The fitXY scaleType only work when you set the layout_width and layout_height to match_parent or fill_parent according to the API level that your are using for.
so you must use this code in your xml only:
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:scaleType="fitXY"
android:src="#drawable/myImage" />

Animate ImageView width without scaling

I'm trying to animate an ImageView so it's slowly shown from left to right.
When I asked this before I was having trouble to explain what I wanted, so this time I created the desired effect using HTML / JS:
http://jsfiddle.net/E2uDE/
What would be the best way to get this effect in Android?
I tried changing the scaleType and then applying a ScaleAnimation directly to that ImageView:
Layout:
<ImageView
android:id="#+id/graphImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
android:background="#android:color/transparent"
android:contentDescription="#string/stroom_grafiek"
/>
Java:
scale = new ScaleAnimation((float)0,
(float)1, (float)1, (float)1,
Animation.RELATIVE_TO_SELF, (float)0,
Animation.RELATIVE_TO_SELF, (float)1);
scale.setDuration(1000);
graphImage.startAnimation(scale);
But this stil scales the image.
I also tried wrapping the ImageView in a FrameLayout, hoping I could just animate the FrameLayout:
<FrameLayout
android:layout_width="70dp"
android:layout_height="fill_parent"
android:clipChildren="true"">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left|clip_horizontal" />
</FrameLayout>
This will still try to scale my ImageView to fit inside the FrameLayout.
There are several ways to do this - one way is to simply change the clip on the canvas (i.e. the area where the view is allowed to draw) of the ImageView drawing your image. Slowly increasing the right-hand edge of the draw bounds will result in same effect as in your example link.
I have written some example code which illustrates this technique. If you download/build/run the project, clicking on the image will run the reveal animation.
Have a look at the onDraw method of the CoveredImageView class, which has the following basic structure:
#Override
protected void onDraw(Canvas canvas) {
...
canvas.getClipBounds(mRect);
mRect.right = ...;
canvas.clipRect(mRect);
...
super.onDraw(canvas);
...
invalidate();
}
The clip is adjusted and then invalidate() is called, causing onDraw() to be called again.
I have also written some code to interpolate the right clip value from the elapsed time, which does not depend on any particular version of Android. However, as a note, from Android 3.0 there is a new animation framework and a ValueAnimator class which could help perform such tasks.
You could overlap your imageview with another one, for example one with a plain white drawable. Then you can animate the overlapping imageview without worrying about scale until it has a width of 0 and remove it. For that to work you have to place your imageView in a RelativeLayout ofc.

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