您的位置:首页 > 移动开发 > Android开发

Android 绘制圆角图片(圆形图片,圆角矩形图片,圆角正方形图片)【转】

2016-09-24 19:19 465 查看
来自:http://blog.csdn.net/ywl5320/article/details/38450021

我们在Android应用中经常要绘制圆角的图片来展示一些背景图,但是每次都制作圆角的图片很麻烦,而且重复使用率不高。所以我们最好的就是在应用中根据已有的图片,动态的绘制所需要的圆角图片用于显示。话不多说,让我们先看看效果图:



这是例子中使用到的图片:



怎么样,效果很好吧。

实现绘制圆角图片的原理很简单,就是在程序中动态生成一张Bitmap,然后再用Paint在这张Bitmap中绘制所需的图形(如圆形),再根据paint的setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN))属性设置在Bitmap中画的圆形和所要显示的图片的交集,并取图片部分,那样就生成了圆形的图片。“

其中Mode取值有如下一些值:

[plain] view
plain copy

1.PorterDuff.Mode.CLEAR

所绘制不会提交到画布上。

2.PorterDuff.Mode.SRC

显示上层绘制图片

3.PorterDuff.Mode.DST

显示下层绘制图片

4.PorterDuff.Mode.SRC_OVER

正常绘制显示,上下层绘制叠盖。

5.PorterDuff.Mode.DST_OVER

上下层都显示。下层居上显示。

6.PorterDuff.Mode.SRC_IN

取两层绘制交集。显示上层。

7.PorterDuff.Mode.DST_IN

取两层绘制交集。显示下层。

8.PorterDuff.Mode.SRC_OUT

取上层绘制非交集部分。

9.PorterDuff.Mode.DST_OUT

取下层绘制非交集部分。

10.PorterDuff.Mode.SRC_ATOP

取下层非交集部分与上层交集部分

11.PorterDuff.Mode.DST_ATOP

取上层非交集部分与下层交集部分

12.PorterDuff.Mode.XOR

取两层绘制非交集。两层绘制非交集。

13.PorterDuff.Mode.DARKEN

上下层都显示。变暗

14.PorterDuff.Mode.LIGHTEN

上下层都显示。变量

15.PorterDuff.Mode.MULTIPLY

取两层绘制交集

16.PorterDuff.Mode.SCREEN

上下层都显示。

原理就是这样,接下来我们看看示例代码怎么应用:

第一:先看布局文件activity_main.xml

[html] view
plain copy

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<ImageView

android:id="@+id/source"

android:layout_width="100dip"

android:layout_height="100dip"

android:layout_centerHorizontal="true"

android:layout_marginBottom="20dip"

android:layout_marginTop="20dip"

android:src="@drawable/demo"/>

<ImageView

android:id="@+id/circle"

android:layout_width="100dip"

android:layout_height="100dip"

android:layout_centerHorizontal="true"

android:layout_below="@id/source"

android:layout_marginBottom="20dip"/>

<ImageView

android:id="@+id/rect"

android:layout_width="100dip"

android:layout_height="100dip"

android:layout_below="@id/circle"

android:layout_centerHorizontal="true"

android:layout_marginBottom="20dip"/>

<ImageView

android:id="@+id/squre"

android:layout_width="100dip"

android:layout_height="100dip"

android:layout_below="@id/rect"

android:layout_centerHorizontal="true"/>

</RelativeLayout>

这里定义了四个Imageview,第一个为原图,第二个为圆形图片,第三个为圆角矩形,第四个为圆角正方形。

第二:为了节省空间,我就把生成图片的代码写在了MainActivity中,如下,注释都很清楚:

[java] view
plain copy

package com.demo.imagetype;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PorterDuffXfermode;

import android.graphics.RectF;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.widget.ImageView;

public class MainActivity extends Activity {

private ImageView circle;

private ImageView rect;

private ImageView squre;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

circle = (ImageView)findViewById(R.id.circle);

rect = (ImageView)findViewById(R.id.rect);

squre = (ImageView)findViewById(R.id.squre);

/** 获取图片资源并转换为 Bitmap类型 */

Drawable drawable = getResources().getDrawable(R.drawable.demo);

BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;

Bitmap bitmap = bitmapDrawable.getBitmap();

circle.setImageBitmap(getCircleBitmap(bitmap));

rect.setImageBitmap(drawRect(bitmap, 80));

squre.setImageBitmap(drawSqureRect(bitmap, 80));

}

/**

* 绘制圆形

* @param source

* @return

*/

public static Bitmap getCircleBitmap(Bitmap source)

{

// 以最小的边为圆的半径

int min = 0;

if(source.getWidth() < source.getHeight())

{

min = source.getWidth();

}

else

{

min = source.getHeight();

}

// 获取图片的中心点,使之与圆形的中心点重合,才不会让图片出现偏移

int x = 0;

int y = 0;

if(source.getWidth() > min)

{

x = -(source.getWidth() - min);

}

else

{

x = min - source.getWidth();

}

if(source.getHeight() > min)

{

y = -(source.getHeight() - min);

}

else

{

y = min - source.getHeight();

}

// 创建画笔

final Paint paint = new Paint();

paint.setAntiAlias(true);

// 以新建的bitmap创建画布

Bitmap bitmap = Bitmap.createBitmap(min, min, Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

// 以图片最小边为直径绘制圆形区域

canvas.drawCircle(min / 2, min / 2, min / 2, paint);

// 设置圆形区域与要显示的图片相交,并取相交区域的图片为结果图片

// Mode.SRC_IN:取两层绘制交集。显示上层。

paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));

canvas.drawBitmap(source, x/2, y/2, paint);

// 返回生成的bitmap,bitmap就是圆形图片

return bitmap;

}

/**

* 绘制圆角矩形

* @param source

* @param radius

* @return

*/

public Bitmap drawRect(Bitmap source, int radius)

{

// 得到要绘制的图片的长和宽,用来绘制圆角矩形的长和宽

int width = source.getWidth();

int height = source.getHeight();

final Paint paint = new Paint();

paint.setAntiAlias(true);

Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

RectF rect = new RectF(0, 0, width, height);

canvas.drawRoundRect(rect, radius, radius, paint);

paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));

canvas.drawBitmap(source, 0, 0, paint);

return bitmap;

}

/**

* 绘制圆角正方形

* @param source

* @param radius

* @return

*/

public Bitmap drawSqureRect(Bitmap source, int radius)

{

int min = 0;//获取最小的边长

if(source.getWidth() < source.getHeight())

{

min = source.getWidth();

}

else

{

min = source.getHeight();

}

int x = 0;//绘制中心的x坐标

int y = 0;//绘制中心的y坐标

if(source.getWidth() > min)

{

x = -(source.getWidth() - min);

}

else

{

x = min - source.getWidth();

}

if(source.getHeight() > min)

{

y = -(source.getHeight() - min);

}

else

{

y = min - source.getHeight();

}

final Paint paint = new Paint();

paint.setAntiAlias(true);

Bitmap bitmap = Bitmap.createBitmap(min, min, Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

RectF rect = new RectF(0, 0, min, min);

canvas.drawRoundRect(rect, radius, radius, paint);

paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));

canvas.drawBitmap(source, x/2, y/2, paint);//将要绘制的图片中心移动到画布中心

return bitmap;

}

}

/**

* 1.PorterDuff.Mode.CLEAR

所绘制不会提交到画布上。

2.PorterDuff.Mode.SRC

显示上层绘制图片

3.PorterDuff.Mode.DST

显示下层绘制图片

4.PorterDuff.Mode.SRC_OVER

正常绘制显示,上下层绘制叠盖。

5.PorterDuff.Mode.DST_OVER

上下层都显示。下层居上显示。

6.PorterDuff.Mode.SRC_IN

取两层绘制交集。显示上层。

7.PorterDuff.Mode.DST_IN

取两层绘制交集。显示下层。

8.PorterDuff.Mode.SRC_OUT

取上层绘制非交集部分。

9.PorterDuff.Mode.DST_OUT

取下层绘制非交集部分。

10.PorterDuff.Mode.SRC_ATOP

取下层非交集部分与上层交集部分

11.PorterDuff.Mode.DST_ATOP

取上层非交集部分与下层交集部分

12.PorterDuff.Mode.XOR

取两层绘制非交集。两层绘制非交集。

13.PorterDuff.Mode.DARKEN

上下层都显示。变暗

14.PorterDuff.Mode.LIGHTEN

上下层都显示。变量

15.PorterDuff.Mode.MULTIPLY

取两层绘制交集

16.PorterDuff.Mode.SCREEN

上下层都显示。

**/

其中在绘制圆角矩形的方法中第二个参数就是圆角的弧度,大家可以自己修改试试,看效果如何。好了,虽然代码不多也不复杂,但是确实很实用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: