I have an image like this->
And I want to show like this->
Then I can choose how much I can see(0~1,0=can not see,1=Whole picture,0.5=half picture,....etc,read from user input)
How to do that?
I tried to use android:scaleType but it is not working.
My best suggestion is to wrap your BitmapDrawable with a ClipDrawable.
ClipDrawable lets you define clipping for any other drawable, so instead of drawing the entire drawable, only a part of it will be drawn.
How would that work? Your ImageView can display a drawable - assignable through setImageDrawable(). Naturally, you would place a BitmapDrawable of your image bitmap there. If you wrap your BitmapDrawable first with ClipDrawable, and only then assign to the ImageView, you should be fine.
<ImageView
android:id="#+id/imageView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/clip_source" />
and this is clip_source drawable:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="#drawable/your_own_drawable"
android:gravity="top" />
You can define the amount of clipping by calling the function setLevel() on your ClipDrawable (clip_source). A level of 0 means the image is completely hidden and a level of 10000 means the image is completely revealed. You can use any int value in the middle.
You'll have to set the level in code, so your code should first get a reference to the ClipDrawable. You can do this by running getDrawable() on your ImageView instance. When you have a reference to your ClipDrawable, simply run setLevel(5000) on it (or any other number 0-10000).
ImageView img = (ImageView) findViewById(R.id.imageView1);
mImageDrawable = (ClipDrawable) img.getDrawable();
mImageDrawable.setLevel(5000);
here is another way to achieve this
public static Bitmap getScaleBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
final RectF rectF = new RectF(rect);
final float roundPx = 0;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Here in below line
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
set hight as you require..
Enjoy :)
I've achieved this by setting the scrollY on my ImageView in the markup. From android's documentation, clearly this is not an option if you're dealing with devices running less than API 14. Also, in my case, I'm using fixed size images that I'm loading based on application state, so they're always the same size. As such, I'm able to just implement it in markup. I realize this approach won't work for everyone.
I wrap the image in a layout that's half as tall as the icon and intentionally have the icon's size at it's actual size. Without the scrollY set, it displays only the top half of the image. Setting the scrollY moves it to where I want it - displaying only the lower half of the image.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:gravity="center_horizontal">
<ImageView
android:id="#+id/icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/default_icon"
android:scrollY="50dp" />
</LinearLayout>
So, from my example, it's only displaying the bottom half of the icon.
Here's an easy way.. Create a separate layout in your main layout just for your images. Make sure it is realitive. Now put your image view for your pictures in side the layout and make it fill parent. OK now make a blank image and add that image view to the bottom of the layout and the top to the center of the layout. Just mess with the margins and size of the imageviews till it looks the way you want it. Hope this helps.
Convert your drawable into a bitmap and crop to get top of the image to form another bitmap, then display it into your image view.
// to convert drawable to bitmap
Bitmap resource = BitmapFactory.decodeResource(context.getResources(),
R.drawable.your_resource);
// to set width of bitmap to imageview's width if necessary,
int width = imageView.getMeasuredWidth();
// to crop the bitmap to specific width and height,
resource = Bitmap.createBitmap(resource, 0, 0, width, height);
here is the code to crop image into two part
public static Bitmap getScaleBitmap(Bitmap bitmap, int check) {
final Bitmap toBeCropped = bitmap;
final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inTargetDensity = 1;
toBeCropped.setDensity(Bitmap.DENSITY_NONE);
int top = 0;
int bottom = 0;
int targetheight = 0;
if (check == 0) {// return 1st half of image
top = 0;
bottom = bitmap.getHeight() / 2;
} else {// return 2nd half of image
top = (bitmap.getHeight() / 2) - 10;
bottom = (bitmap.getHeight() / 2) - 10;
}
int fromHere = (int) (toBeCropped.getHeight() * 0.5);
Bitmap croppedBitmap = Bitmap.createBitmap(toBeCropped, 0, top, toBeCropped.getWidth(), bottom);
return croppedBitmap;
}
Related
I am using Camera api to capture ID cards pictures, I have an over lay as shown in the image bellow. I want to crop the image in the box. could you suggest on how exactly it should be done. I have written down what I have tried and the results it gives me.
This is the screenshot of the id i want to capture..
Output.
white rectangular box is a photo frame which is right in the centre in a Relative layout
<View
android:id="#+id/photo_frame"
android:layout_width="match_parent"
android:layout_height="212dp"
android:background="#drawable/bg_photo_frame"
android:layout_centerInParent="true"
android:layout_margin="#dimen/double_padding"
android:visibility="visible"/>
How do I calculate this frame to cut the image
this is what I have to cut the image which needs modification but not sure what is the way forward
public Bitmap cutImage(final Bitmap srcBmp, final int pixepWidth, final int pixelsHeight, float widthRatio) {
// Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, 20, 20, pixepWidth, pixelsHeight);
// return croppedBitmap;
Bitmap dstBmp;
if (srcBmp.getWidth() >= srcBmp.getHeight()){
dstBmp = Bitmap.createBitmap(
srcBmp,
srcBmp.getWidth()/2 - srcBmp.getHeight()/2,
0,
srcBmp.getHeight(),
srcBmp.getHeight()
);
}else{
dstBmp = Bitmap.createBitmap(
srcBmp,
0,
srcBmp.getHeight()/2 - srcBmp.getWidth()/2,
srcBmp.getWidth(),
srcBmp.getWidth()
);
}
return dstBmp;
}
Resizing view using onTouchListener
You apply some kind of touchListener to the overlay view for resizing and moving the overlay. ImageButton seems to work, so I use ImageButton with a frame.xml to draw a border.
Then you apply the global coordinates of the overlay (x, y, width, height) against the coordinates of the bitmap (x, y, width, height).
The overlay x and the overlay y can’t be less than 0, and the overlay x + the overlay width cannot be greater than the bitmap width.
To perform the crop, use Bitmap.createBitmap():
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)
How to crop Bitmap?
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'm showing images from gallery to Imageview.
I'm using below code
Bitmap background = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888);
float originalWidth = bMap.getWidth(), originalHeight = bMap.getHeight();
Canvas canvas = new Canvas(background);
float scale = width/originalWidth;
float xTranslation = 0.0f, yTranslation = (height - originalHeight * scale)/2.0f;
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawBitmap(bMap, transformation, paint);
imageView1.setImageBitmap(background);
Case 1: working.
Original Image
Output of above code.
Case 2: not working
Original Image.
Output of above code.
in case 2 why image is not getting scaled properly, to fill the imageview?
Please let me know where I'm going wrong.
Android already provides a method to create scaled bitmap. check this out LINK
Are you wanting it to stretch? Use fitxy.
Use the scaleType attribute on your ImageView in your layout xml file.
Example:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
Then you can set your image on the ImageView using setImageUri(Uri uri) (I assume you have the Uri of the image to show).
background
I have a small circular contact photo view that I need to show the user.
If the photo is available, I should show it, while the image gets rounded to a circle, and has an elevation.
If the photo isn't available, I show an icon inside with a background, while still it's rounded and has elevation.
The problem
I've managed to make the photo showing work only on Android 5 and above:
But, it has a bad color around the edges as it tries to show the background of the FAB, and on Android 4.x and below it it showing as a simple rectangular content, with nothing that's related to FAB, probably because padding is what's protecting it for the shadow to be shown.
I also need to be able to add a stroke (a thin line of specific color around the rounded image), but I'm not sure how to add it.
What I've tried
This is in the layout file:
<android.support.design.widget.FloatingActionButton
android:id="#+id/image"
android:layout_width="#dimen/test"
android:layout_height="#dimen/test"/>
"test" is 80dp.
And this is in the code:
FloatingActionButton floatingActionButton = (FloatingActionButton) view.findViewById(R.id.image);
floatingActionButton.setPadding(0, 0, 0, 0);
final Bitmap bitmap = ...
RoundedCornersDrawable roundedCornersDrawable = new RoundedCornersDrawable(getResources(), bitmap, bitmap.getWidth() / 2);
floatingActionButton.setImageDrawable(roundedCornersDrawable);
code of RoundedCornersDrawable:
public class RoundedCornersDrawable extends BitmapDrawable {
private final BitmapShader bitmapShader;
private final Paint p;
private final RectF rect;
private final float borderRadius;
public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float borderRadius) {
super(resources, bitmap);
bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
final Bitmap b = getBitmap();
p = getPaint();
p.setAntiAlias(true);
p.setShader(bitmapShader);
final int w = b.getWidth(), h = b.getHeight();
rect = new RectF(0, 0, w, h);
this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
}
#Override
public void draw(final Canvas canvas) {
canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
}
}
The question
How do I get the FAB to work this way? How can I disable the padding at will, for all Android versions, and yet still have a rounded image with shadow ?
How do I also add a stroke to the rounded FAB ?
I think I was too fast in writing this post, while it seems there is already one about it here:
How to add a shadow and a border on circular imageView android?
I will have a look at it and see if it matches the requirements of what I need.
EDIT: it doesn't look as well as FAB (especially the shadow), plus I don't see the ability to put the small content in the center, like in FAB. It always puts the content in center-crop way.
Of course, I could just put a smaller sized image in it....
EDIT: I think I've found the right library this time:
https://github.com/lopspower/CircularImageView
It allows a shadow, customize the shadow size and color, and also a border, and also how to scale the image.
It's not quite a FAB, and it doesn't have the ability to put the image at the center without cropping, but it's enough for me.
I want to implement cover flow as below
I have tried Carousel, but its not the same thing. Did some google search was not able to find something even near to the cover flow implemented in given example.
Definitely have a look at this, FancyCoverFlow.
There is a demo app for it in the Play store as well that shows the reflection requirement you'd like.
have you tried this:
blog post
public Bitmap getRefelection(Bitmap image) {
// The gap we want between the reflection and the original image
final int reflectionGap = 0;
// Get you bit map from drawable folder
Bitmap originalImage = image;
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matix applied to it.
// We only want the bottom half of the image
/*if(bitmapWithReflection!=null && !bitmapWithReflection.isRecycled()){
bitmapWithReflection.recycle();
bitmapWithReflection=null;
}*/
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,(height + height / 2), Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
//Draw the reflection Image
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x40ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
if(originalImage!=null && originalImage.isRecycled()){
originalImage.recycle();
originalImage=null;
}
if(reflectionImage!=null && reflectionImage.isRecycled()){
reflectionImage.recycle();
reflectionImage=null;
}
return bitmapWithReflection;
}
Have you gone through the Android Coverflow which is bit different form the Carousel which you want.
I made cover flow widget which is not dependent on gallery.
You can find it here. I will add some samples later.
http://applm.github.io/ma-components/