Why background of Round imageView is dark? - android

I have created a round imageView based on this answer.
It makes image round perfectly. However, I have two problems.
Image rotated 90 degree that I have no idea why (user clicks on a button, user's gallery displays, user selects an image as his profile pic)
image has dark background that I have no idea comes from where.
The class that I'm using:
public class RoundImageView extends ImageView {
private Path path;
private Paint paint;
private PorterDuffXfermode porterDuffXfermode;
public RoundImageView(Context context) {
super(context);
init();
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setWillNotDraw(false);
path = new Path();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
// Create a circular path.
final float halfWidth = canvas.getWidth()/2;
final float halfHeight = canvas.getHeight()/2;
final float radius = Math.max(halfWidth, halfHeight);
path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);
paint.setXfermode(porterDuffXfermode);
canvas.drawPath(path, paint);
}
}
The way I'm adding it in layout:
<com.allstarxi.widget.RoundImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:src="#drawable/ic_launcher"
android:id="#+id/imageView"
android:contentDescription="#string/general_content_description"
android:scaleType="center" />
This is screenshot:

try putting this in the RoundImageView class :
public Bitmap getCroppedBitmap(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());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
//Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
//return _bmp;
return output;
}
Then put this in onDraw:
getCroppedBitmap(BitmapFactory.decodeResource(getResources(), getDrawable()));

Since, I couldn't find how to fix this issue, I used RoundedImageView library. It is good when you fix width and height of imageView.
This is my sample:
<com.makeramen.RoundedImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="#drawable/ic_launcher"
android:id="#+id/ivUserPic"
android:contentDescription="#string/general_content_description"
android:scaleType="centerCrop"
app:mutate_background="true"
app:border_width="0dp"
app:corner_radius="18dp"
app:oval="true"/>

I have same experienced before because I loaded something from database in UI Thread, Are you load something from database/disk in UI Thread? if yes you need to load it using AsynTask, if not it will effecting your UI Rendering process

It is all about this: android:scaleType="center"
Try another scaleTypes from here and see the result:
CENTER,
CENTER_CROP,
CENTER_INSIDE ,
FIT_CENTER ,
FIT_END ,
FIT_START,
FIT_XY,
MATRIX

Related

Background image with rounded bottom in XML android

I wanted to add an image in the background of my linear layout and I know the attribute will be android: background="#drawable/login_bg" but now I have to create a drawable resource file and in that file, I want the bottom left and bottom right sides to be rounded and top left and right sides to be rectangular .
Remember: I need an Image inside the background with rounded corners.
I have tried this link
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" android:padding="10dp">
<corners
android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp"/>
</shape>
</item>
<item android:drawable="#drawable/login_bg" />
</layer-list>
Try to use this customview. But you must change from android: background to android: src
class RadiusImageView: AppCompatImageView {
private val clipPath = Path()
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
override fun onDraw(canvas: Canvas) {
//float radius = 36.0f;
val rect = RectF(0f, 0f, width.toFloat(), height.toFloat())
// 4 Pair of radius : top-left, top -right, bottom-right, bottom left, each pair is radius
// for rx and ry for each corner
clipPath.addRoundRect(rect, floatArrayOf(0f,0f,0f,0f,40f,40f,40f,40f) Path.Direction.CW)
canvas.clipPath(clipPath)
super.onDraw(canvas)
}
}
I got a solution and I did it this in the following way:
I am writing a part of my onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
topbackground=(ImageView) findViewById(R.id.topbackground);
Bitmap image1 = BitmapFactory.decodeResource(getResources(),R.drawable.login_bg)
topbackground.setImageBitmap(roundedImage.getRoundedCornerBitmap(this,
image1,200,image1.getWidth(),image1.getHeight(),true,true,false,false ));
}
RoundedImage roundedImage = new RoundedImage();
There is an image with the name "login_bg" , "topbackground" is the view of Image and I am calling a separate class named "RoundedImage" and performing this by passing its parameters and my class RoundedImage is as follows:
public class RoundedImage {
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int
pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL,
boolean squareBR ) {
Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier =
context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
//make sure that our rounded corner is scaled appropriately
final float roundPx = pixels*densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
//draw rectangles over the corners we want to be square
if (squareTL ){
canvas.drawRect(0, 0, w/2, h/2, paint);
}
if (squareTR ){
canvas.drawRect(w/2, 0, w, h/2, paint);
}
if (squareBL ){
canvas.drawRect(0, h/2, w/2, h, paint);
}
if (squareBR ){
canvas.drawRect(w/2, h/2, w, h, paint);
}
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, paint);
return output;
}
}
This is how it goes and I am able to get what was needed.

Android imageview be larger on small device screen

I'm having a problem with the imageView
it's larger when i open it on small screen device
this image show the different
on the left screen size its 1440 * 2560
and the right one its size 400 * 800
also this is my code xml ImageView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="#+id/tt">
<customfonts.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ssz2"
android:scaleType="fitXY"
android:adjustViewBounds="false" />
</RelativeLayout>
and this is the class that's make my image rounded
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& drawable instanceof VectorDrawable) {
((VectorDrawable) drawable).draw(canvas);
b = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas();
c.setBitmap(b);
drawable.draw(c);
}
else {
b = ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0,0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if(bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(),
sbmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
and the imageView source size its 75 * 75
i want to make the size if this imageView same in all device
The problem you're experiencing is that the image is the same size in pixels.
But as the density of the pixels is lower on the screen to the right it appears bigger.
What you need to do is to take the screen's pixels and density into account.
This is what Google is using dp for to make sure that the views look the same even if the screens are different between the devices.
There would be different ways of solving this, but I think you want to convert the size from pixels to dp before you draw it on the canvas.
The problem is that your ImageView dimensions are set to be "wrap_content", and your content (image source) size is determined using pixels. On a device with a smaller screen where the are less pixels, those 75 pixels will look relatively larger.
You should set your ImageView to have a fixed dp size such as:
android:layout_width="50dp"
android:layout_height="50dp"
You could use a calculator such as this one: https://pixplicity.com/dp-px-converter/ to get the correct density-pixel dimensions.
To Support all screen devices you have to create multiple copies of with different dimensions.
res/drawable-mdpi/graphic.png // bitmap for medium-density
res/drawable-hdpi/graphic.png // bitmap for high-density
res/drawable-xhdpi/graphic.png // bitmap for extra-high-density
res/drawable-xxhdpi/graphic.png // bitmap for extra-extra-high-density
See Android official docs.
You use
android:layout_width="wrap_content"
android:layout_height="wrap_content"
If you want fixed size use
android:layout_width="75dp"
android:layout_height="75dp"
but I advice you not to.
Read more about density independence https://developer.android.com/guide/practices/screens_support.html#density-independence

Bitmap in ImageView with rounded corners

I have an ImageView and I want to make it with rounded corners.
I use this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#null"/>
<stroke android:width="1dp"
android:color="#ff000000"/>
<corners android:radius="62px"/>
</shape>
And set this code as background of my imageview.
It works, but the src image that I put on the ImageView is going out of the borders and doesn't adapt itself into the new shape.
How can I solve the problem?
try this one :
public class CustomImageView extends ImageView {
public static float radius = 18.0f;
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
//float radius = 36.0f;
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
}
and
<your.pack.name.CustomImageView
android:id="#+id/selectIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
CustomImageView iconImage = (CustomImageView )findViewById(R.id.selectIcon);
iconImage.setImageBitmap(bitmap);
or,
ImageView iv= new CustomImageView(this);
iv.setImageResource(R.drawable.pic);
It's strange that nobody here has mentioned RoundedBitmapDrawable from Android Support Library v4. For me it is the simplest way to get rounded corners without borders. Here is example of usage:
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
final float roundPx = (float) bitmap.getWidth() * 0.06f;
roundedBitmapDrawable.setCornerRadius(roundPx);
Make one function which make rounded to your bitmap using canvas.
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
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());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
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;
}
for more info:> here
The accepted answer uses path clipping, but it doesn't support anti-aliasing. See Romain Guy's comments on his post. "path clipping does not support antialiasing and you get jagged edges."
http://www.curious-creature.com/2012/12/11/android-recipe-1-image-with-rounded-corners/
There is one good library(vinc3m1’s RoundedImageView) that supoorts rounded corners on ImageView, but it only supports the same radiuses on every corners. So I made one that you can set different radiuses on each corners.
It doesn't rely on path clipping, nor redrawing. It only draws one time with canvas.drawPath() method. So I finally got result that I wanted like below.
See : https://github.com/pungrue26/SelectableRoundedImageView
For me, the below method does the magic. :)
This method accepts a bitmap object and returns it back with rounded corners. roundPx is the number of rounded pixels you want:
public static Bitmap getRoundedCornerBitmap(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());
final RectF rectF = new RectF(rect);
final float roundPx = 12;
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;
}
...or you could use this library instead of ImageView without any further coding.
If you need make Bitmap with different corner radii and I recommend follow code:
private static Bitmap createRoundedRectBitmap(#NonNull Bitmap bitmap,
float topLeftCorner, float topRightCorner,
float bottomRightCorner, float bottomLeftCorner) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = Color.WHITE;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
Path path = new Path();
float[] radii = new float[]{
topLeftCorner, bottomLeftCorner,
topRightCorner, topRightCorner,
bottomRightCorner, bottomRightCorner,
bottomLeftCorner, bottomLeftCorner
};
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
path.addRoundRect(rectF, radii, Path.Direction.CW);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
If you need border also then:
1. You can use a rounded box image with a transparent body and white from outside. For Example:
and use this with target image like below:
<FrameLayout
android:layout_width="100px"
android:layout_height="100px" >
<ImageView
android:id="#+id/targetImage"
android:layout_width="100px"
android:layout_height="100px"
android:src="#drawable/app_icon"
android:layout_gravity="center" />
<ImageView
android:id="#+id/boxImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/box" />
Adding CardView as parent layout of ImageView also be a good solution.
It can be done with background drawable, like explain in many posts including this one, but it also needs to set clipping.
Here a full example:
The code:
AppCompatImageView iconView = findViewById(R.id.thumbnail);
iconView.setClipToOutline(true);
The layout:
<android.support.v7.widget.AppCompatImageView
android:id="#+id/thumbnail"
android:layout_width="80dp"
android:layout_height="80dp"
android:contentDescription="#string/thumbnail"
android:scaleType="centerInside"
android:background="#drawable/round_view" <!--here set the drawable as background -->
tools:src="#mipmap/ic_user" />
The drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
</shape>
/**
* Creates new circular bitmap based on original one.
* #param newCornerRadius is optional
*/
fun Bitmap.toCircular(context: Context, newCornerRadius: Float? = null): RoundedBitmapDrawable {
return RoundedBitmapDrawableFactory.create(context.resources, this).apply {
isCircular = true
newCornerRadius?.let {
cornerRadius = it
}
}
}
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap rounder = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvasRound = new Canvas(rounder);
Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xferPaint.setColor(Color.BLACK);
final int rx = this.getWidth(); //our x radius
final int ry = this.getHeight(); //our y radius
canvasRound.drawRoundRect(new RectF(0,0,rx,ry), rx, ry, xferPaint);
xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(rounder, 0, 0, xferPaint);
}
}
Kotlin version
fun Bitmap.roundCorner(pixels: Int): Bitmap {
val output: Bitmap = Bitmap.createBitmap(
width, height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, width, height)
val rectF = RectF(rect)
val roundPx = pixels.toFloat()
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawRoundRect(rectF, roundPx, roundPx, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(this, rect, rect, paint)
return output
}
call by:
sourceBitmap.roundCorner(60)
The method to make rounded corners for imageview in android is not rocket science guys! just use a png with required curves with the same color as your background and set the overlay to FITXY.!
public void drawRoundImage(boolean isEditPicEnable){
if(originalImageBitmap != null){
setBackgroundResource(R.drawable.ic_account_user_outer_circle_blue);
if (isEditPicEnable) {
setBackgroundResource(R.drawable.ic_account_user_outer_circle_white);
Bitmap mask = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_white_mask);
Bitmap mask1 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_pencil_bg);
originalImageBitmap = Bitmap.createScaledBitmap(originalImageBitmap, mask.getWidth(), mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(originalImageBitmap, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
mCanvas.drawBitmap(mask1, 0, 0, null);
Bitmap mask2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_pencil);
mCanvas.drawBitmap(mask2, 0, 0, null);
setImageBitmap(result);
setScaleType(ScaleType.FIT_XY);
} else {
Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.ic_account_white_mask);
originalImageBitmap = Bitmap.createScaledBitmap(originalImageBitmap, mask.getWidth(),mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(originalImageBitmap, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
setImageBitmap(result);
setScaleType(ScaleType.FIT_XY);
}
}else{
setBackgroundResource(R.drawable.ic_account_user_outer_circle_blue);
setImageResource(R.drawable.my_ac_default_profile_pic);
}
}

Crop square image to circle - Programmatically

i was searching for past one day and i was not successful .
i get the image from API , and i download it to a bitmap file using the following code .
private Bitmap DownloadImage(String URL)
{
Bitmap bitmap = null;
InputStream in = null;
try
{
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
return bitmap;
}
private InputStream OpenHttpConnection(String urlString) throws IOException
{
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try
{
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK)
{
in = httpConn.getInputStream();
}
}
catch (Exception ex)
{
throw new IOException("Error connecting");
}
return in;
}
And i get the image as a square and i want to crop the four corners and make it to circular image . Is there any possible way to achieve ?
Any related answers are welcomed . Thanks in advance .
Once the bitmap is retrieved RoundedBitmapDrawableFactory can be used to generate a RoundedBitmapDrawable from the v4 Support Library. That Drawable can then be applied to an ImageView or directly drawn to a Canvas.
// Create the RoundedBitmapDrawable.
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
roundDrawable.setCircular(true);
// Apply it to an ImageView.
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageDrawable(roundDrawable);
// Alternatively, draw it to an canvas (e.g. in onDraw where a Canvas is available).
// setBounds since there's no View handling size and positioning.
roundDrawable.setBounds(left, top, right, bottom);
roundDrawable.draw(canvas);
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
DrawingView dv = new DrawingView(this);
setContentView(dv);
}
class DrawingView extends View {
Bitmap bitmap;
public DrawingView(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.glossy_overlay);
}
#Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint();
// paint.setColor(Color.CYAN);
canvas.drawBitmap(getclip(), 30, 20, paint);
}
public Bitmap getclip() {
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());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
// paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2,
bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
}
use the function below to draw a circle on bitmap and then set the circled bitmap to imageView
public static Bitmap getClip(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f,
bitmap.getWidth() / 2f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Note: Dividing numbers must be float
Roman Nurik propose a very direct use of shaders to do things like that, with a custom drawable.
I change the code a bit to make an oval image and tested myself. The effect and performance are really good:
public class StreamDrawable extends Drawable {
private static final boolean USE_VIGNETTE = true;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
public StreamDrawable(Bitmap bitmap, int margin) {
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
mMargin = margin;
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);
if (USE_VIGNETTE) {
RadialGradient vignette = new RadialGradient(
mRect.centerX(), mRect.centerY() * 1.0f / 0.7f, mRect.centerX() * 1.3f,
new int[] { 0, 0, 0x7f000000 }, new float[] { 0.0f, 0.7f, 1.0f },
Shader.TileMode.CLAMP);
Matrix oval = new Matrix();
oval.setScale(1.0f, 0.7f);
vignette.setLocalMatrix(oval);
mPaint.setShader(
new ComposeShader(mBitmapShader, vignette, PorterDuff.Mode.SRC_OVER));
}
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRect, mPaint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
}
This can be simply done in xml, Please see my answer here:
https://stackoverflow.com/a/18287979/665930
<RelativeLayout
android:id="#+id/icon_layout"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<ImageView
android:id="#+id/icon"
android:layout_width="#dimen/icon"
android:layout_height="#dimen/icon"
android:layout_centerInParent="true"
android:scaleType="fitXY" >
</ImageView>
<ImageView
android:id="#+id/icon_mask"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_centerInParent="true"
android:background="#drawable/circle"
android:scaleType="fitXY" >
</ImageView>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#00FFFFFF" android:endColor="#00FFFFFF"
android:angle="270"/>
<stroke android:width="10dp" android:color="#FFAAAAAA"/>
I tried the solutions above but none worked well for me. This is because my phone camera don't take square image but just rectangle images. So, I make some changes in the #actsai solution to always take the minor dimension and then crop the image in a circle:
public static Bitmap getBitmapClip(Bitmap bitmap) {
int maxLenth = bitmap.getWidth() <= bitmap.getHeight() ? bitmap.getWidth() : bitmap.getHeight();
Bitmap output = Bitmap.createBitmap(maxLenth,
maxLenth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, maxLenth, maxLenth);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(maxLenth / 2, maxLenth / 2,
maxLenth / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
I used the following scale property to fill my ImageView with the new bitmap:
<ImageView
android:id="#+id/iv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="fitXY" />
After hunting lot of answers I came up with this small hack which exploits FrameLayout(overlays child views as a stack) and stroke attribute of oval-shape. This can be done simply in XML without much hassle and third party libraries.
Create new Layout resource file "circle_image.xml" under res/layout directory.
Add a new FrameLayout as the root view in the circle_image.xml.
Create an ImageView (base/background) to hold your Image or Icon which you want to crop as the first child in the FrameLayout.
Create an ImageView (mask/foreground) to hold the shape(oval made into circle with size attribute having same height and width) that masks the background image as the second/last child inside the FrameLayout.
Note:
our idea here is to exclude the area around the circle and display the contents of the image that is visible inside the circle)
Create new Drawable resource file "circle_mask.xml" under res/drawable directory.
Add new shape with android:shape="oval" in the circle_mask.xml.
Add size tag for the shape to specify height and width which must be equal(to make it a circle) and should match that of its parent FrameLayout.
Add solid tag for the shape to specify the transparency inside the circle.
10.Add stroke tag for the shape so that there will be a ring of particular width(android:width) with the color specified by the android:color attribute.
Note:
a. The color(stroke color) specified in the stoke tag is the MaskColor/BackgroundColor around our cropped image. since I wanted this color to be same as that of my base view which was a cardView. I used the same color "white".
b. The width (stroke width) is set to a huge value such that it is too thick with enough space for our cropped image in the centre.
c. The ImageView(top mask layer) created in Step-4 is also exploited by specifying a huge dimension that is much larger than its parent FrameLayout making it expand outside the FrameLayout dimensions. This fills up the area which we are interested in masking with the color of large stroke width ring.
circle_image.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/icon_layout"
android:layout_width="64dp"
android:layout_height="64dp">
<ImageView
android:id="#+id/iv_profile_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher_background"
android:contentDescription="TODO"/>
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_gravity="center"
android:background="#drawable/circle"
android:scaleType="fitXY" >
</ImageView>
</FrameLayout>
circle_mask.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="64dp"
android:height="64dp"/>
<solid android:color="#android:color/transparent"/>
<stroke
android:width="18dp"
android:color="#android:color/white" />
</shape>

Antialiased rounded corners on Android ImageView [duplicate]

This question already has answers here:
How to make an ImageView with rounded corners?
(58 answers)
Closed 9 years ago.
I am new to android dev, and I have been trying for a few hours now to add nice and smooth rounded corners to an ImageView, without success.
First thing I tried is simply to round corners of my images directly, but this implies changing the bitmap, and since I need to keep the raw ones, and those are pretty big, this is not really memory friendly. This would also cause other difficulties since my ImageView is fluid.
Second thing I tried to use is the clipPath method after subclassing my view. This works, but corners are aliased. I then tried adding a PaintFlagsDrawFilter to implement the aliasing, but this didn't worked. I'm using monodroid, and I was wondering this was supposed to work in Java.
Here is my code (C#):
public class MyImageView : ImageView
{
private float[] roundedCorner;
/**
* Contains the rounded corners for the view.
* You can define one, four or height values.
* This behaves as the css border-radius property
*
* #see http://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF, float[], android.graphics.Path.Direction)
*/
public float[] RoundedCorners{
get{
return roundedCorner;
}
set{
float[] finalValue = new float[8];
int i=0;
if(value.Length == 1){
for(i=0; i<8;i++){
finalValue[i] = value[0];
}
}else if(value.Length == 4){
for(i=0; i<4;i++){
finalValue[2*i] = value[i];
finalValue[2*i+1] = value[i];
}
}
roundedCorner = finalValue;
}
}
public SquareImageView (Context context) :
base (context)
{
Initialize ();
}
public SquareImageView (Context context, IAttributeSet attrs) :
base (context, attrs)
{
Initialize ();
}
private void Initialize ()
{
RoundedCorners = new float[]{0,0,0,0};
}
public override void Draw (Android.Graphics.Canvas canvas)
{
Path path = new Path();
path.AddRoundRect(new RectF(0,0, Width,Height),RoundedCorners, Path.Direction.Cw);
canvas.ClipPath(path);
base.Draw (canvas);
}
/**
* try to add antialiasing.
*/
protected override void DispatchDraw (Canvas canvas)
{
canvas.DrawFilter = new PaintFlagsDrawFilter((PaintFlags)1, PaintFlags.AntiAlias);
base.DispatchDraw (canvas);
}
}
Thanks for your help!
I've created a RoundedImageView based off Romain Guy's example code that wraps this logic into an ImageView that you should be able to just use. It supports borders and antialiasing out of the box.
It's more efficient than other rounded corner examples because it doesn't create another copy of the bitmap, nor does it use clipPath which draws twice to the canvas.
use below code
public Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels)
{
Bitmap output = null;
if(bitmap != null)
{
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());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
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;
}
and call this method like
imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 10));

Categories

Resources