Using setLayerInset on LayerDrawable with Bitmap gives unexpected results - android

I'm dynamically placing small dot bitmaps ('hotspots') over a large bitmap image using LayerDrawable. The layer at index 0 contains the large image. The dots' positions on the image are specified to me in terms of percentage of large image. For example, I might have a hotspot that is supposed to be 50% from the left and 75% from the top of the large base image. In order to position the dots over the correct part of the image, I'm using
setLayerInset(layer, leftOffset, topOffset, rightOffset, bottomOffset)
and calculating the offsets based on the width and height of the ImageView which contains the LayerDrawable. I'm happy that the calculations are correct and that the right height and width are being retrieved, and expect the dots to be correctly displayed, but they are not. The dots are being skewed along the Y axis and their positions are incorrect (too high and too far to the left). Has anyone encountered a similar problem and found a solution?

I spend a day and a half working on this, trying to make sense of the numbers, and here's what I found:
In the situation I am dealing with, where the first layer contains a BitmapDrawable and I'm setting insets for the subseqent layers, the offset in the call:
setLayerInset(layer, leftOffset, topOffset, rightOffset, bottomOffset)
are relative to the dimensions of the bitmap in the first layer, even if those dimensions are greater than the view in which the DrawableLayer is being placed (e.g. when the Bitmap is being redimensioned automatically by the view).
Bizarre and unexpected, but true. Hope this saves somebody some time.

Related

ImageView android:cropToPadding, what it actually does?

I went through the documentation for the tag android:cropToPadding here, it only says:
If true, the image will be cropped to fit within its padding.
May be a boolean value, such as "true" or "false".
which is quite confusing for me to understand.
I have an ImageView inside my app, (which was developed by someone else):
<ImageView
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center"
android:maxWidth="100dp"
android:padding="20dp" />
This ImageView had cropToPadding tag inside it, there were like 20 ImageView on main screen, which all had this tag inside them, and the app was obviously taking time to load as there were more Images, but then removing images was not an option, so I was finding stuff that was useless and trying to optimize the layout when I came across this tag.
Removing this tag did no change to the images that were shown inside the ImageView, but there must be some reason that every image contained this tag. So I started finding what this tag did, and documentation wasn't much clear as to why this tag should be used.
Can someone please explain what this tag does to the Image? I found out not many resources, all that I found was "This crops the Image to padding", what does that mean! I know what padding is, I know what cropping is, but what does "Sets whether this ImageView will crop to padding" mean?
This is a complex question to answer, because we have to drill into some nitty-gritty details of how ImageView actually draws the image to the screen.
The first thing to establish is that there are two rectangles that affect ImageView drawing behavior. The first is the rectangle defined by the ImageView's dimensions ignoring padding. The second is the rectangle defined by the ImageView's dimensions considering padding. (Obviously, if padding is 0, then these will be the same.)
The next thing to establish is that ImageViews all have a scale type that defines how the image is stretched and/or cropped when the image's intrinsic size doesn't match the size of the rectangle that it is being drawn into.
The default scale type is FIT_CENTER, which scales the image down to fit within the view bounds + padding (that is, the image will be drawn inside the rectangle that considers padding). Since the image is being drawn inside the padding rectangle, android:cropToPadding has no effect.
However, other scale types work differently. The scale type CENTER simply positions the image in the middle of the view, but performs no scaling (so the image will be clipped if it is bigger than the view). In this case, android:cropToPadding defines whether the image will be clipped by only the view's bounds or also clipped by the view's padding.
A picture is worth a thousand words:
This picture shows the same 72x72 image inside a 72x72 view with 16dp padding and CENTER scale type. The left ImageView has android:cropToPadding="false" and the right ImageView has android:cropToPadding="true".

how to scale image between 2 views with given coordinates in android

In my application I have a requirement to animate an image (this image view has an arrow set as source).
I am unable to figure this out how I can achieve this.To solve this i got x and y coordinates of second view that is rectangle after getting coordintes i am setting
scaleX() of image view that is purple line but I am not geeting desire out put because it stretches to the whole screen along x-axis
here is the code what i tried is
int x = (int) imageView.getX();
imageView2.setScaleX(x);
here imageview is rectangular box and imageview 2 is the purple line
Why you dont try with scenes? It's exactly what you need.
http://developer.android.com/training/transitions/scenes.html
I think you are getting the correct output when using the above code. Scale is defined against initial dimensions. And you would need to use something like this
dist = box.getX() - circle.getX()
and your scale would be
imageView2.setScale(dist/distInitial)
where distInitial you compute it at creation time using the dist formula.
You might need to change the position because it is scaled around the center of it (i.e. a smaller scale shrink margins to center of image)
You might want to perform this operations using a Canvas. It might be more efficient.

Place an imageview on customdialog screen depending on variable

I'm trying to place a small image on the top of a big one in a custom dialog.
I want the small one to be placed in a different place depending on a variable, which I called "pos". It contains a int value from 0 to 100, meaning percentage of the dialog width.
If pos = 0, I want to place the image in the left margin of the big one, if pos = 30 it should be placed in the 30% of the screen, starting from the left.
If pos = 50 I want it to able placed right in the middle, being 100 the maximum value for it and placing it in the right margin.
I include a draft to explain myself a bit better.
I tried with RelativeLayout.LayoutParams but I never get expected output.
Perhaps a simpler strategy is to extend ImageView, then create a custom image using Canvas commands in the onDraw method that draw the bitmap appropriately on the x axis with a background set to match your layout.
You can determine the width of the custom dialog in the the onMeasure method of your custom ImageView, so the returned bitmap (including empty background) can be the correct width, and the position of the smaller bitmap can be correctly apportioned.
Once you've created the class, which will take just a few minutes, you can add it to your XML layout with something like:
<com.domain.yourapp.YourCustomerImageView
android:id="#+id/bitmap_graph"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"/>

Behaviour of ImageView when scaled

I do some operations with my Views that scale then trough:
imageView.setScaleX(2);
imageView.setScaleY(2);
On that ImageView I put a image that is two times greater than it, as expected when the scale is 1, the Bitmap is scaled down to the view size, my question is:
When the view is scaled up, the portion of the bitmap I see is the original image or the scaled-down image scaled up.
The difference is that if a tiny image is scaled up we lost contrast on letters, if it's the original image it wont.
When you scale an image up you're loosing quality. In you're case, you're doubling the width and height therefore, for each pixel you get 4 pixels assigned to it. The extra 3 pixels won't give you the quality you wanted.
If you want to go back to the original size you should decode the source again. This way you'll get the quality you're looking for.

Locate the same area of an ImageView regardless of scaling

I want to identify a certain part of an ImageView -- based on the actual size of the image regardless of how the image is scaled for the particular device.
Example: I have an image that is 480x320. I want a rectangle that (at this size) is defined as
Rect(10,35,20,50). What I'm wanting to do is figure out how I can define this rectangle relative to the actual size of the image when it scaled and displayed on the screen.
Can you just scale each part of the rectangle? For instance, if your image is displayed at 2x -- 960x480 -- then would the correct rectangle be (20,70,40,100)?
Use percentages from a pivot point: the top-left or the bottom-right.

Categories

Resources