Android get dead area size around camera view - android

I am using FrameLayout or PreviewView to display the camera feed. The view is match_parent for the width and height (as I am unable to wrap_content for the height) and the scaleType is fitCenter to get the correct aspect ratio. Doing that as expected results in black area above and below the camera feed. How can I know the top and bottom dead area heights so that I can position other UI elements exactly in that area?
Thanks!!

So to answer my own. Since I was trying to achieve a fitCenter scale for the camera preview which for mobile phones is 4:3 what I was able to do is within a ConstraintLayout add a frame layout with a dimension ration of 4:3. That way the camera preview was contained exactly in that layout without any dead areas, and I was to position other UI elements above and below by constraining them to the top and bottom of the frame layout.
<FrameLayout
android:id="#+id/cameraView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="W,4:3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:clipChildren="false" />

The "dead area"/black bars around the preview won't always be on the top and bottom, they might also be on the right and left. Their position depends on the size of the view (which I'm assuming you can get easily), and the aspect ratio of the preview, or even better, its size.
When setting up the Preview use case, if you're configuring its aspect ratio with setTargetAspectRatio(), then you already know the preview's aspect ratio.
Otherwise, you can still indirectly get it, one way I can think of is calling PreviewView.getBitmap() (after the preview has started), the returned Bitmap's size will be the size of the preview, you can use it directly, or you can use its aspect ratio bitmapWidth / bitmapHeight, which will represent the preview's aspect ratio.

Related

FFImageloading xamarin android fit to parent

I am creating a android app in Xamarin with the mvvmcross framework.
Am trying to display pictures from the server to our users(the pictures are Urls). But the pictures refuse to scale to fill their parent.
How can I achieve the right fit for these images? , I use the FillParent on the Width tag. But the images refuse to scale to the size of the container.
My current setup
<FFImageLoading.Cross.MvxImageLoadingView
android:id="#+id/my_plannymap_listitem_title_picture"
android:layout_width="fill_parent"
android:layout_height="150dp"
local:MvxBind="DataLocationUri ImageUrl; Click OpenDetailCommand" />
above code creates(sorry for the volume thing), As you can see the images do not fill, they remain their "original" size
other activity (same problem here)
<FFImageLoading.Cross.MvxImageLoadingView
android:layout_width="fill_parent"
android:layout_height="150dp"
android:scaleType="fitCenter"
android:id="#+id/overview_image"
android:background="#580AB0"
local:MvxBind="DataLocationUri ImageUrl"
TransparencyEnabled="false"
DownSampleToFit="true" />
It sounds like you want to fix the height to 150dp, and fix the width to the width of the parent. If that is the case it can be done, but it will stretch any image that isn't the correct aspect ratio to begin with.
<FFImageLoading.Cross.MvxImageLoadingView
android:id="#+id/my_plannymap_listitem_title_picture"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="fitXY"
local:MvxBind="DataLocationUri ImageUrl; Click OpenDetailCommand" />
(note I used match_parent since fill_parent is deprecated)
If you don't want your image to stretch in a strange way and you can't guarantee that the aspect ratio of incoming images matches that of your layout, you need to select one aspect (either width or height) to dictate the size of the other, in such a way that the ratio remains unchanged. You can do that with the following (in this case you're deciding the width, and calculating the height from it based on the image's aspect ratio):
<FFImageLoading.Cross.MvxImageLoadingView
android:id="#+id/my_plannymap_listitem_title_picture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="DataLocationUri ImageUrl; Click OpenDetailCommand" />
In almost all cases where you cannot guarantee the aspect ratio of the image you're scaling, the second option gives a better result than the first.

How to handle ImageView for different screen sizes without hardcoding?

I've an app that display list of images along with some text in a listview.
It actually fetches those images through web service.
If i use wrap_content for ImageView, it may stretch and the list will be irregular if the image size varies.
If i hardcode by giving some width and height (in dp), does it affects our multi screen support concept?
I wouldn't advise you to use wrap_content for the ImageView.
You could try setting a fixed height to it and use it full-width.
For the fixed size you have to use dp(Density Independent Pixels) which will result in having the size of this view 'almost' the same on any device. An by almost I mean you won't have the exact same percentage on the screen(for obvious reasons) but Android will scale it appropriately.
Second and most important is to set the scale_type property to the ImageView component in the xml file. There are various options but probably center_crop would fit your needs the best(I advise you to try out all the rest of them too, so you can understand the difference between, center, centerCrop, centerInside, fitCenter, fitEnd, fitStart, fitXY, matrix - these are all the possible values scale_type can have).
EDIT:
Here is the documentation description for these types:
center Displays the image centered in the view with no scaling.
centerCrop Scales the image such that both the x and y dimensions are greater than or equal to the view, while maintaining the image aspect ratio; crops any part of the image that exceeds the size of the view; centers the image in the view.
centerInside Scales the image to fit inside the view, while maintaining the image aspect ratio. If the image is already smaller than the view, then this is the same as center.
fitCenter Scales the image to fit inside the view, while maintaining the image aspect ratio. At least one axis will exactly match the view, and the result is centered inside the view.
fitStart Same as fitCenter but aligned to the top left of the view.
fitEnd Same as fitCenter but aligned to the bottom right of the view.
fitXY Scales the x and y dimensions to exactly match the view size; does not maintain the image aspect ratio.
If You want to display it in a ListView then it is better to hard-code the dimension. and add ScaleType you want to the image.
If you want to use GridView then use this property
android:stretchMode="columnWidth"
android:numColumns="auto_fit"
the columns are adjusted dynamically according to the density of the screen when using auto_fit

How can I use this background image for all aspect ratio?

I have an image like this used as background in a RelativeLayout:
This image is used as background for all the levels of my game. Every level is drawn onto the blue area.
I want to keep fixed the aspect-ratio of the blue area, changing the size of the red edges to avoid to show to the user unused pixels of their screen. The green area must be fixed to 80dp for all phones. Then I must add a View (a GLSurfaceView) in my layout in such a way that it fit perfectly the blue area. Thus all levels of my Android game will be perfectly the same in all Android device.
How can I solve this problem?
The real image that I use is a little more complex. You can look it here:
Real image
I would use a FrameLayout for the middle part of the screen(blue), add an ImageView, containing the BackgroundImage you want to display, and put the GLSurfaceView on top of it.
Since the aspect ratio is always the same, you could set the ImageViews sclaing to fit xy and the image should always look the same.
Lets assume you are using a simple SurfaceView, the xml code id use to put a ImageView begind it would look like this
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
As i dont know how you build your View i cant post the code that does the job, but just add a FrameLayout instead of your GLSurfaceView to your View, with the Same Dimensions, the GLSurfaceView would have.
To that FrameLayout first add the ImageView, then the GLSurfaceView. Both with height and width set to match_parent.
To Figure out the size of your SurfaceView...
Retrieve Display Dimensions
Substract Green Bar Dimensions
Calculate the size of the Blue View, get the Height/Width (whatever is bigger) calculate the missing Dimension
Set the Red Views to Occupie the empty space.
So you would have to do this programmatically :)

Photo: wrap_content, but max_width = layout width

I have a normal "read an article" type page with a single large photo at the top.
I'd like it to:
not scale larger than the source imgae
not be larger than the screen
not be CRAZY long vertically
side things I already have working
border (via padding), center crop (would rather top crop, but seems not avail)
The main issue I'm having is - I can either have it fill_parent (ie full width) OR wrap_content (ie as large as the original image). And nothing I have done so far allows the image to be normal size (ie keep from enlarging).
Is there a "norm" for this kind of thing? I'm sure there's some kind of sweet spot or combination of attributes for this that works - I just can't find them.
My current attempt:
<ImageView
android:id="#+id/article_photo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/super_light_gray"
android:scaleType="centerCrop"
android:contentDescription="#string/articlePhoto"
android:cropToPadding="true"
android:layout_marginBottom="20dp"
android:padding="1dp"/>
You can write some code in the Activity to get the image size and display size.
If the image size exceeds display size set width to display, if not set to image size. If you want to be fancy you can find the ratio between the x and y and scale vertically also.

Image doesnt cover image view fully

I am trying to apply image on an image view instance...but it doesnt cover it properly...
please advise
here it is my image view code:
android:id="#+id/imageViewVessel"
android:layout_width="fill_parent"
android:scaleType="fitStart"
android:layout_height="170dip"
android:src="#drawable/vessel"
EDIT by kcoppock: Adding code from devaditya's comment below
TableRow rowImage = new TableRow(this);
rowImage.setBackgroundColor(Color.GRAY);
rowImage.setMinimumHeight(150);
rowImage.setGravity(Gravity.CENTER);
rowImage.setMinimumWidth(LayoutParams.FILL_PARENT);
ImageView imgViewVessel=new ImageView(this);
imgViewVessel.setImageResource(R.drawable.vessel);
imgViewVessel.setMinimumHeight(150);
imgViewVessel.setMinimumWidth(LayoutParams.FILL_PARENT);
imgViewVessel.setScaleType(ScaleType.FIT_XY);
rowImage.addView(imgViewVessel);
To expand on Gao's answer, you do need to set a scaleType for your ImageView, but it is unlikely that fitXY is the scaleType that you are looking for. You can find the complete list at the above link, but a few of the most common are:
centerCrop: This will maintain the aspect ratio of the image, filling the frame entirely, but cropping off either the left and right, or top and bottom of the if the aspect ratio of the frame and source image are different.
centerInside: This also maintains the aspect ratio, but the image is scaled to fit entirely within the view, so that the longest edge is the same size as the frame. This can give you a letterbox type of effect if the aspect ratios of the frame and source image are different. fitStart and fitEnd are the same scaling method, but they have different placement of the image (top-left and bottom-right, respectively).
fitXY: This one should only be used if disproportionate scaling does not affect the graphic. In the case of bitmap graphics, this is almost always bad to use. This sets the width of the source image to the width of the view, and the height of the source image to the height of the view, without maintaining the aspect ratio of the source image.
You can set scale type in the layout file : android:scaleType="fitXY" or call setScaleType with fitXY.

Categories

Resources