五种方式显示圆形图片
来源:互联网 发布:为什么还原网络设置 编辑:程序博客网 时间:2024/04/30 16:30
- 依赖
- 自定义CircleImageView
> /** * 圆图片View */ > public class CircleImageView extends ImageView {> > private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;> > private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;> private static final int COLORDRAWABLE_DIMENSION = 1;> > private static final int DEFAULT_BORDER_WIDTH = 0;> private static final int DEFAULT_BORDER_COLOR = Color.BLACK;> > private final RectF mDrawableRect = new RectF();> private final RectF mBorderRect = new RectF();> > private final Matrix mShaderMatrix = new Matrix();> private final Paint mBitmapPaint = new Paint();> private final Paint mBorderPaint = new Paint();> > private int mBorderColor = DEFAULT_BORDER_COLOR;> private int mBorderWidth = DEFAULT_BORDER_WIDTH;> > private Bitmap mBitmap;> private BitmapShader mBitmapShader;> private int mBitmapWidth;> private int mBitmapHeight;> > private float mDrawableRadius;> private float mBorderRadius;> > private boolean mReady;> private boolean mSetupPending;> > public CircleImageView(Context context) {> super(context);> }> > public CircleImageView(Context context, AttributeSet attrs) {> this(context, attrs, 0);> }> > public CircleImageView(Context context, AttributeSet attrs, int defStyle) {> super(context, attrs, defStyle);> super.setScaleType(SCALE_TYPE);> > TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);> > mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width,> DEFAULT_BORDER_WIDTH);> mBorderColor = a.getColor(R.styleable.CircleImageView_border_color,> DEFAULT_BORDER_COLOR);> > a.recycle();> > mReady = true;> > if (mSetupPending) {> setup();> mSetupPending = false;> }> }> > @Override> public ScaleType getScaleType() {> return SCALE_TYPE;> }> > @Override> public void setScaleType(ScaleType scaleType) {> if (scaleType != SCALE_TYPE) {> throw new IllegalArgumentException(String.format("ScaleType %s not supported.",> scaleType));> }> }> > @Override> protected void onDraw(Canvas canvas) {> if (getDrawable() == null) {> return;> }> > canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);> canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);> }> > @Override> protected void onSizeChanged(int w, int h, int oldw, int oldh) {> super.onSizeChanged(w, h, oldw, oldh);> setup();> }> > public int getBorderColor() {> return mBorderColor;> }> > public void setBorderColor(int borderColor) {> if (borderColor == mBorderColor) {> return;> }> > mBorderColor = borderColor;> mBorderPaint.setColor(mBorderColor);> invalidate();> }> > public int getBorderWidth() {> return mBorderWidth;> }> > public void setBorderWidth(int borderWidth) {> if (borderWidth == mBorderWidth) {> return;> }> > mBorderWidth = borderWidth;> setup();> }> > @Override> public void setImageBitmap(Bitmap bm) {> super.setImageBitmap(bm);> mBitmap = bm;> setup();> }> > @Override> public void setImageDrawable(Drawable drawable) {> super.setImageDrawable(drawable);> mBitmap = getBitmapFromDrawable(drawable);> setup();> }> > @Override> public void setImageResource(int resId) {> super.setImageResource(resId);> mBitmap = getBitmapFromDrawable(getDrawable());> setup();> }> > private Bitmap getBitmapFromDrawable(Drawable drawable) {> if (drawable == null) {> return null;> }> > if (drawable instanceof BitmapDrawable) {> return ((BitmapDrawable) drawable).getBitmap();> }> > try {> Bitmap bitmap;> > if (drawable instanceof ColorDrawable) {> bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);> } else {> bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),> drawable.getIntrinsicHeight(), BITMAP_CONFIG);> }> > Canvas canvas = new Canvas(bitmap);> drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());> drawable.draw(canvas);> return bitmap;> } catch (OutOfMemoryError e) {> return null;> }> }> > private void setup() {> if (!mReady) {> mSetupPending = true;> return;> }> > if (mBitmap == null) {> return;> }> > mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);> > mBitmapPaint.setAntiAlias(true);> mBitmapPaint.setShader(mBitmapShader);> > mBorderPaint.setStyle(Paint.Style.STROKE);> mBorderPaint.setAntiAlias(true);> mBorderPaint.setColor(mBorderColor);> mBorderPaint.setStrokeWidth(mBorderWidth);> > mBitmapHeight = mBitmap.getHeight();> mBitmapWidth = mBitmap.getWidth();> > mBorderRect.set(0, 0, getWidth(), getHeight());> mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);> > mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() -> mBorderWidth);> mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);> > updateShaderMatrix();> invalidate();> }> > private void updateShaderMatrix() {> float scale;> float dx = 0;> float dy = 0;> > mShaderMatrix.set(null);> > if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {> scale = mDrawableRect.height() / (float) mBitmapHeight;> dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;> } else {> scale = mDrawableRect.width() / (float) mBitmapWidth;> dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;> }> > mShaderMatrix.setScale(scale, scale);> mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);> > mBitmapShader.setLocalMatrix(mShaderMatrix);> }> > }
- MyApp中初始化fresco和UIL:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); initUIL(); } private void initUIL() { File cacheFile = StorageUtils.getCacheDirectory(this); //缓存文件夹路径 Log.e("MyApplication", "initImageLoader:cacheDir===" + cacheFile); //cacheFile为:/storage/emulated/0/Android/data/com.example.administrator.myglide/cache ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽 .diskCacheExtraOptions(480, 800, null) // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个 .threadPoolSize(3) // default 线程池内加载的数量 .threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级 .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现 .memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值 .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiskCache(cacheFile)) // default 可以自定义缓存路径 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值 .diskCacheFileCount(100) // 可以缓存的文件数量 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) .imageDownloader(new BaseImageDownloader(this)) // default .imageDecoder(new BaseImageDecoder(true)) // default // default,可以自定义defaultOptions来设置是否缓存:cacheInMemory(true)缓存内存和cacheOnDisc(true)缓存硬盘 .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) .discCache(new LimitedAgeDiskCache(cacheFile, 7 * 24 * 60 * 60))// 自定义缓存路径,7天后自动清除缓存 .writeDebugLogs() // 打印debug log .build(); //开始构建 ImageLoader.getInstance().init(config); // 初始化 }}
- 在Manifest中添加权限和注册app:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application ***android:name=".MyApp"*** android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
- 布局文件:
<?xml version="1.0" encoding="utf-8"?><ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#99eace31" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.administrator.myglide.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_diy_iv" android:onClick="clickbutton" android:text="下载图片并加载到自定义的圆形图片" android:layout_width="match_parent" android:layout_height="wrap_content" /> <com.example.administrator.myglide.views.CircleImageView android:id="@+id/diy_iv" android:src="@mipmap/ic_launcher" android:layout_width="match_parent" android:layout_height="300dp" /> <!-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>--> <TextView android:id="@+id/uil_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffffff" android:text="UIL加载网络图片" /> <ImageView android:id="@+id/uil_iv" android:layout_width="match_parent" android:layout_height="300dp " android:scaleType="centerInside" android:src="@mipmap/ic_launcher" /> <!-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>--> <TextView android:id="@+id/glide_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffffff" android:text="glide加载网络图片" /> <ImageView android:id="@+id/glide_iv" android:layout_width="match_parent" android:layout_height="300dp" android:scaleType="centerInside" android:src="@mipmap/ic_launcher" /> <!-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>--> <TextView android:id="@+id/picasso_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffffff" android:text="Picasso加载网络图片" /> <ImageView android:id="@+id/picasso_iv" android:layout_width="match_parent" android:layout_height="300dp" android:scaleType="centerInside" android:src="@mipmap/ic_launcher" /> <!-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>--> <TextView android:id="@+id/fresco_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffffff" android:text="fresco加载网络图片" /> <!-- // com.facebook.drawee.view.SimpleDraweeView的宽度和高度 不支持wrap_content, 如果要设置宽高比, 需要在Java代码中指定setAspectRatio(float ratio); --> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/fresco_iv" android:layout_width="match_parent" android:layout_height="300dp" android:scaleType="centerInside" android:src="@mipmap/ic_launcher" fresco:backgroundImage="@color/blue" fresco:failureImage="@drawable/first_icon25" fresco:failureImageScaleType="centerInside" fresco:placeholderImage="@color/wait_color" fresco:placeholderImageScaleType="fitCenter" fresco:pressedStateOverlayImage="@color/red" fresco:progressBarAutoRotateInterval="1000" fresco:progressBarImage="@drawable/first_icon11" fresco:progressBarImageScaleType="centerInside" fresco:retryImage="@drawable/first_icon19" fresco:retryImageScaleType="centerCrop" fresco:roundAsCircle="true" fresco:roundBottomLeft="true" fresco:roundBottomRight="true" fresco:roundTopLeft="true" fresco:roundTopRight="true" fresco:roundedCornerRadius="1dp" fresco:roundingBorderColor="@color/border_color" fresco:roundingBorderWidth="2dp" /> </LinearLayout></ScrollView>
- MainActivity:
public class MainActivity extends AppCompatActivity { String url = "http://image.codes51.com/Article/image/20150730/20150730121119_3945.gif"; String net_url = "http://img2.3lian.com/2014/f6/173/d/51.jpg"; String gif_url = " http://img15.3lian.com/2015/gif/1/78/1.gif"; private ImageView glide_iv; private ImageView picasso_iv; private SimpleDraweeView fresco_iv; private ImageView uil_iv; private DisplayImageOptions options; private CircleImageView diy_iv; private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews();// 加载圆角图片 useUIL(); usePicasso(); useFresco(); useGlide(); } //自定义的圆形图片 public void clickbutton(View view) { Bitmap bitmap = FileUtils.readImage(net_url); if (bitmap != null) {//读取sd图片 Toast.makeText(this, "sd卡的路径:" + Environment .getExternalStorageDirectory() + "/xq_caches/images" + url.substring(url.lastIndexOf("/") + 1) , Toast.LENGTH_LONG).show(); //路径为:/storage/emulated/0 /qf_caches/images/ 51.jpg diy_iv.setImageBitmap(bitmap); } else { // 发送异步请求 new MyAsyncTask(this).execute(net_url); } } private void useGlide() { Glide.with(this) .load("http://img2.3lian.com/2014/f6/173/d/51.jpg")// 加载图片资源 .skipMemoryCache(false)//是否将图片放到内存中 .diskCacheStrategy(DiskCacheStrategy.ALL)//磁盘图片缓存策略 .dontAnimate()//不执行淡入淡出动画 .crossFade(100)// 默认淡入淡出动画300ms .placeholder(R.mipmap.ic_launcher)// 占位图片 .error(R.mipmap.ic_launcher)//图片加载错误显示 .centerCrop()// 或者 fitCenter() .transform(new GlideCircleTransform(this))//圆角图片 .into(glide_iv); //更新ui } private void useFresco() { DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri(Uri.parse(net_url)) .setAutoPlayAnimations(true) ////自动播放动画,比如:gif .build(); fresco_iv.setController(controller); } private void usePicasso() { Picasso.with(this) .load("http://img2.3lian.com/2014/f6/173/d/51.jpg") .transform(new PicassoCircleTransform())//圆角 .placeholder(R.drawable.first_icon26) .error(R.drawable.first_icon25) .into(picasso_iv); } /** * UIL */ private void useUIL() { options = new DisplayImageOptions.Builder()//构造者模式,option可以放在Application中 .showStubImage(R.mipmap.ic_launcher)//缓冲过程中图片 .showImageForEmptyUri(R.mipmap.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.drawable.first_icon11)// 设置图片加载或解码过程中发生错误显示的图片 .cacheInMemory(true)//缓存到内存 .cacheOnDisc(true)//缓存到硬盘 .bitmapConfig(Bitmap.Config.ARGB_8888) //设置图片的解码类型 .displayer(new UILCircleBitmapDisplayer())//自定义圆形图片,与默认区别在于圆心坐标移到了ImageView的中心// .displayer(new RoundedBitmapDisplayer(60))//默认圆角图片,弧度// .displayer(new CircleBitmapDisplayer(R.color.corner_color))//默认圆形图片,颜色// .displayer(new FadeInBitmapDisplayer(2000))//默认渐明效果,时间 .build(); ImageLoader.getInstance().displayImage("http://img2.3lian.com/2014/f6/173/d/51.jpg", uil_iv, options); /* ImageLoader.getInstance() .loadImage("http://img2.3lian.com/2014/f6/173/d/51.jpg", options, new ImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View view) { } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { } @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { } @Override public void onLoadingCancelled(String imageUri, View view) { } });*/ } private void initViews() { diy_iv = ((CircleImageView) findViewById(R.id.diy_iv)); glide_iv = ((ImageView) findViewById(R.id.glide_iv)); picasso_iv = ((ImageView) findViewById(R.id.picasso_iv)); fresco_iv = ((SimpleDraweeView) findViewById(R.id.fresco_iv)); uil_iv = (ImageView) findViewById(R.id.uil_iv); } class MyAsyncTask extends AsyncTask<String, Void, byte[]> { private ProgressDialog pDialog; public MyAsyncTask(Context context) { pDialog = new ProgressDialog(context); pDialog.setIcon(R.mipmap.ic_launcher); pDialog.setTitle("提示"); pDialog.setMessage("The data is loading...");// 如果没有图标,可以像下面这样构建ProgressDialog:参数为:上下文,title,content// ProgressDialog pDialog = ProgressDialog.show(context, null, "加载中..."); } @Override protected void onPreExecute() { super.onPreExecute(); pDialog.show(); } @Override protected byte[] doInBackground(String... params) { URL url; Bitmap bitmap = null; try { url = new URL(params[0]); //获得连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制 conn.setConnectTimeout(6000); //连接设置获得数据流 conn.setDoInput(true); //不使用缓存 conn.setUseCaches(false); //这句可有可无,没有影响 conn.connect(); //得到数据流 InputStream is = conn.getInputStream(); //解析得到图片 bitmap = BitmapFactory.decodeStream(is); //关闭数据流 is.close(); if (conn.getResponseCode() == 200) { // 缓存工具类:保存图片 Utilsfile.saveImage(params[0], bitmap);// url:params[0] //返回字符数组 ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); return byteArray; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(byte[] result) { super.onPostExecute(result); if (result != null) { Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length); diy_iv.setImageBitmap(bitmap); } pDialog.dismiss(); } }}
- 自定义GlideCircleTransform:
public class GlideCircleTransform extends BitmapTransformation { public GlideCircleTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool,toTransform); } private Bitmap circleCrop(BitmapPool pool, Bitmap source) { int size = Math.min(source.getWidth(), source.getHeight()); int width = (source.getWidth() - size) / 2; int height = (source.getHeight() - size) / 2; Bitmap bitmap = pool.get(size, size, Bitmap.Config.ARGB_8888); if (bitmap == null) { bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); if (width != 0 || height != 0) { // source isn't square, move viewport to center Matrix matrix = new Matrix(); matrix.setTranslate(-width, -height); shader.setLocalMatrix(matrix); } paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return bitmap; } @Override public String getId() { return getClass().getName(); }}
- 自定义PicassoCircleTransform:
public class PicassoCircleTransform implements Transformation { @Override public Bitmap transform(Bitmap source) { /** * 求出宽和高的哪个小 */ int size = Math.min(source.getWidth(), source.getHeight()); /** * 求中心点 */ int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; /** * 生成BitMap */ Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); if (squaredBitmap != source) { //释放 source.recycle(); } /** * 建立新的Bitmap */ Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); /** * 画布画笔 */ Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; /** * 画圆 */ canvas.drawCircle(r, r, r, paint); squaredBitmap.recycle(); return bitmap; } @Override public String key() { return "circle"; }}
- 自定义UILCircleBitmapDisplayer:
/** * 自定义圆形图片,与默认圆形图片区别在于圆心坐标移到了ImageView的中心 */public class UILCircleBitmapDisplayer implements BitmapDisplayer { protected final Integer strokeColor; protected final float strokeWidth; public UILCircleBitmapDisplayer() { this(null); } public UILCircleBitmapDisplayer(Integer strokeColor) { this(strokeColor, 0); } public UILCircleBitmapDisplayer(Integer strokeColor, float strokeWidth) { this.strokeColor = strokeColor; this.strokeWidth = strokeWidth; } @Override public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) { if (!(imageAware instanceof ImageViewAware)) { throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected."); } imageAware.setImageDrawable(new CircleDrawable(bitmap, strokeColor, strokeWidth)); } public static class CircleDrawable extends Drawable { protected float radius; protected final RectF mRect = new RectF(); protected final RectF mBitmapRect; protected final BitmapShader bitmapShader; protected final Paint paint; protected final Paint strokePaint;//描边的画笔 protected final float strokeWidth;//描边的宽度 protected float strokeRadius;//描边的半径 public CircleDrawable(Bitmap bitmap, Integer strokeColor, float strokeWidth) { radius = Math.min(bitmap.getWidth(), bitmap.getHeight()) / 2;//宽高中较小值的一半为半径 bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());//imageview的框架为矩形 paint = new Paint(); paint.setAntiAlias(true); paint.setShader(bitmapShader); paint.setFilterBitmap(true); paint.setDither(true); if (strokeColor == null) { strokePaint = null; } else { strokePaint = new Paint(); strokePaint.setStyle(Paint.Style.STROKE); //设置paint的风格为“空心”// 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE strokePaint.setColor(strokeColor); strokePaint.setStrokeWidth(strokeWidth); // 设置“空心”的外框的宽度// 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度 strokePaint.setAntiAlias(true); } this.strokeWidth = strokeWidth; strokeRadius = radius - strokeWidth / 2; } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRect.set(0, 0, bounds.width(), bounds.height()); radius = Math.min(bounds.width(), bounds.height()) / 2; strokeRadius = radius - strokeWidth / 2; // Resize the original bitmap to fit the new bound Matrix shaderMatrix = new Matrix(); shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL); bitmapShader.setLocalMatrix(shaderMatrix); } @Override public void draw(Canvas canvas) { //自定义圆形图片,与默认区别在于圆心坐标移到了ImageView的中心 Rect bounds = getBounds();//画一个圆圈 //getBounds() 方法与 getRect() 方法类似,返回一个矩形, //getBounds() 方法返回的矩形包括形状的所有笔触,然而 getRect() 方法返回的矩形则不包括 //getRect() 方法返回的值等于或小于由 getBounds() 方法返回的值。 canvas.drawCircle(bounds.width() / 2F, bounds.height() / 2F, radius, paint); if (strokePaint != null) { canvas.drawCircle(bounds.width() / 2F, bounds.height() / 2F, strokeRadius, strokePaint); } } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public void setAlpha(int alpha) { paint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { paint.setColorFilter(cf); } }}
- 利用到的文件工具类:
public class FileUtils { private static final String CACHE_DIR = Environment .getExternalStorageDirectory() + "/qf_caches/images";// 缓存文件夹 /** * 判断sdcard是否挂载 * * @return */ public static boolean isMounted() { String state = Environment.getExternalStorageState(); return state.equals(Environment.MEDIA_MOUNTED); } /** * 获取sdcard的根目录 * * @return */ public static String getSDCARDDir() { return Environment.getExternalStorageDirectory().getAbsolutePath(); } /** * 存储图片一 * * @param url * : 图片的http网络地址 * @param data * @throws IOException */ public static void saveImage(String url, byte[] data) throws IOException { // 1. 判断是否有sdcard if (!isMounted()) { return; } // 2. 判断是否有缓存的文件夹 File dir = new File(CACHE_DIR); if (!dir.exists()) { dir.mkdirs();// 多层文件夹 } // 3. 存储图片到sdcard File file = new File(dir, getFilename(url)); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); } /** * 保存图片二 * * @param url * : 图片的http网络地址 * @param bitmap * @throws IOException */ public static void saveImage(String url, Bitmap bitmap) throws IOException { // 1. 判断是否有sdcard if (!isMounted()) { return; } // 2. 判断是否有缓存的文件夹 File dir = new File(CACHE_DIR); if (!dir.exists()) { dir.mkdirs(); } // 3. 存储图片到sdcard File file = new File(dir, getFilename(url)); FileOutputStream fos = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); } /** * 获取图片名 * * @param url * @return */ public static String getFilename(String url) { return url.substring(url.lastIndexOf("/") + 1); } /** * 读图片 * * @param url * @return */ public static Bitmap readImage(String url) { // 判断是否有sdcard if (!isMounted()) { return null; } File file = new File(CACHE_DIR, getFilename(url)); if (file.exists()) { // file->bitmap return BitmapFactory.decodeFile(file.getAbsolutePath()); } return null; } /** * 清空缓存目录 */ public void clearCaches() { File dir = new File(CACHE_DIR); File[] allfiles = dir.listFiles(); for (File file : allfiles) { file.delete(); } }}
欢迎交流。
0 0
- 五种方式显示圆形图片
- 两种方式实现圆形图片
- 画圆形图片的几种方式
- android两种方式实现圆形图片
- imageview显示圆形图片
- 自定义显示圆形图片
- ImageView图片圆形显示
- cardView显示圆形图片
- 显示圆形图片
- 初始化Universal-Image-Loader并做全局配置,配置图片的显示方式为圆形显示
- 五种分页显示方式
- ImageView的圆形图片显示
- android 圆形图片的显示
- 图片images样式- 圆形显示
- Android Toast 五种显示方式
- Imageloder__类+适配+圆形图片+加载方式
- android 圆形图片多种实现方式
- Android 圆形图片 CircleImageView(Xfermode方式)
- whereis、locate 查找与命令对应的文件
- 使用IRP进行文件操作
- iOS学习项目(24-layer)
- Cocos2dx 场景类-Scene
- NETIF_STATUS_CALLBACK何时会被调用
- 五种方式显示圆形图片
- UISearchController搜索框禁止向上移动
- json 格式解析 及使用
- Microsoft CRM 2016 IFD配置
- poj1125解题报告【动态规划】【弗洛伊德算法-floyd算法】
- UVA 580
- SQL之CRUD综合训练
- 洛谷 P1378 油滴扩展
- Android进阶之intent传递大数据