在Android開(kāi)發(fā)中經(jīng)常需要圖標(biāo)上以及甚至在應(yīng)用圖標(biāo)的快捷方式上顯示數(shù)字憨奸,表示未讀消息數(shù)以及在以及在某條信息右上角標(biāo)志小圓形,表示這條消息是未讀的狀態(tài)等等锚赤,之前對(duì)此內(nèi)容不熟悉的時(shí)候也表示困擾匹舞,現(xiàn)在對(duì)圖片一些操作也寫在一個(gè)工具類中,以方便調(diào)用线脚。
按照慣例先來(lái)看一下最終效果圖:
BitmapUtil.class
package com.xiaolijuan.bitmapdome.utils;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
/**
* @author: xiaolijuan
* @description: 圖片工具類
* @projectName: BitmapDome
* @date: 2016-01-19
* @time: 21:48
*/
public class BitmapUtil {
// 默認(rèn)圓角半徑
private static final int DEFAULT_CORNER_RADIUS_DIP = 8;
// 默認(rèn)邊框?qū)挾? private static final int DEFAULT_STROKE_WIDTH_DIP = 2;
// 邊框的顏色
private static final int DEFAULT_STROKE_COLOR = Color.WHITE;
// 中間數(shù)字的顏色
private static final int DEFAULT_NUM_COLOR = Color.parseColor("#CCFF0000");
/**
* 生成有數(shù)字的圖片(沒(méi)有邊框)
*
* @param context 上下文
* @param icon 圖片
* @param isShowNum 是否要繪制數(shù)字
* @param num 數(shù)字字符串:整型數(shù)字 超過(guò)99赐稽,顯示為"99+"
* @return 重新生成帶數(shù)字的圖片
*/
public static Bitmap generatorNumIcon2(Context context, Bitmap icon,
boolean isShowNum, String num) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
// 基準(zhǔn)屏幕密度
float baseDensity = 2.3f;
float factor = dm.density / baseDensity;
// 初始化畫布
int iconSize = (int) context.getResources().getDimension(
android.R.dimen.app_icon_size);
Bitmap numIcon = Bitmap.createBitmap(iconSize, iconSize,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(numIcon);
// 拷貝圖片
Paint iconPaint = new Paint();
iconPaint.setDither(true);// 防抖動(dòng)
iconPaint.setFilterBitmap(true);// 用來(lái)對(duì)Bitmap進(jìn)行濾波處理,這樣浑侥,當(dāng)你選擇Drawable時(shí)姊舵,會(huì)有抗鋸齒的效果
Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
Rect dst = new Rect(0, 0, iconSize, iconSize);
canvas.drawBitmap(icon, src, dst, iconPaint);
if (isShowNum) {
if (TextUtils.isEmpty(num)) {
num = "0";
}
if (!TextUtils.isDigitsOnly(num)) {
// 非數(shù)字
num = "0";
}
int numInt = Integer.valueOf(num);
if (numInt > 99) {// 超過(guò)99
num = "99+";
}
// 啟用抗鋸齒和使用設(shè)備的文本字體大小
// 測(cè)量文本占用的寬度
Paint numPaint = new Paint(Paint.ANTI_ALIAS_FLAG
| Paint.DEV_KERN_TEXT_FLAG);
numPaint.setColor(Color.WHITE);
numPaint.setTextSize(20f * factor);
numPaint.setTypeface(Typeface.DEFAULT_BOLD);
int textWidth = (int) numPaint.measureText(num, 0, num.length());
/**
* 繪制圓角矩形背景
*/
int backgroundHeight = (int) (2 * 15 * factor);
int backgroundWidth = textWidth > backgroundHeight ? (int) (textWidth + 10 * factor)
: backgroundHeight;//圓角矩形背景的寬度
canvas.save();// 保存狀態(tài)
ShapeDrawable drawable = getDefaultBackground(context);
drawable.setIntrinsicHeight(backgroundHeight);
drawable.setIntrinsicWidth(backgroundWidth);
drawable.setBounds(0, 0, backgroundWidth, backgroundHeight);
canvas.translate(iconSize - backgroundWidth, 0);
drawable.draw(canvas);
canvas.restore();// 重置為之前保存的狀態(tài)
// 繪制數(shù)字
canvas.drawText(num,
(float) (iconSize - (backgroundWidth + textWidth) / 2),
22 * factor, numPaint);
}
return numIcon;
}
/**
* 生成有數(shù)字的圖片(有邊框的)
*
* @param context 上下文
* @param icon 圖片
* @param isShowNum 是否要繪制數(shù)字
* @param num 數(shù)字字符串:整型數(shù)字 超過(guò)99,顯示為"99+"
* @return 重新生成帶數(shù)字的圖片
*/
public static Bitmap generatorNumIcon3(Context context, Bitmap icon,
boolean isShowNum, String num) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
// 基準(zhǔn)屏幕密度
float baseDensity = 2.2f;
float factor = dm.density / baseDensity;
// 初始化畫布
int iconSize = (int) context.getResources().getDimension(
android.R.dimen.app_icon_size);
Bitmap numIcon = Bitmap.createBitmap(iconSize, iconSize,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(numIcon);
// 拷貝圖片
Paint iconPaint = new Paint();
iconPaint.setDither(true);// 防抖動(dòng)
iconPaint.setFilterBitmap(true);// 用來(lái)對(duì)Bitmap進(jìn)行濾波處理寓落,這樣括丁,當(dāng)你選擇Drawable時(shí),會(huì)有抗鋸齒的效果
Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
Rect dst = new Rect(0, 0, iconSize, iconSize);
canvas.drawBitmap(icon, src, dst, iconPaint);
if (isShowNum) {
if (TextUtils.isEmpty(num)) {
num = "0";
}
if (!TextUtils.isDigitsOnly(num)) {
// 非數(shù)字
num = "0";
}
int numInt = Integer.valueOf(num);
if (numInt > 99) {// 超過(guò)99
num = "99+";
}
// 啟用抗鋸齒和使用設(shè)備的文本字體大小
// 測(cè)量文本占用的寬度
Paint numPaint = new Paint(Paint.ANTI_ALIAS_FLAG
| Paint.DEV_KERN_TEXT_FLAG);
numPaint.setColor(Color.WHITE);
numPaint.setTextSize(20f * factor);
numPaint.setTypeface(Typeface.DEFAULT_BOLD);
int textWidth = (int) numPaint.measureText(num, 0, num.length());
/**
* 繪制圓角矩形背景:先畫邊框伶选,再畫內(nèi)部的圓角矩形
*/
// 圓角矩形背景的寬度
int backgroundHeight = (int) (2 * 15 * factor);
int backgroundWidth = textWidth > backgroundHeight ? (int) (textWidth + 10 * factor)
: backgroundHeight;
// 邊框的寬度
int strokeThickness = (int) (2 * factor);
canvas.save();// 保存狀態(tài)
int strokeHeight = backgroundHeight + strokeThickness * 2;
int strokeWidth = textWidth > strokeHeight ? (int) (textWidth + 10
* factor + 2 * strokeThickness) : strokeHeight;
ShapeDrawable outStroke = getDefaultStrokeDrawable(context);
outStroke.setIntrinsicHeight(strokeHeight);
outStroke.setIntrinsicWidth(strokeWidth);
outStroke.setBounds(0, 0, strokeWidth, strokeHeight);
canvas.translate(iconSize - strokeWidth - strokeThickness,
strokeThickness);
outStroke.draw(canvas);
canvas.restore();// 重置為之前保存的狀態(tài)
canvas.save();// 保存狀態(tài)
ShapeDrawable drawable = getDefaultBackground(context);
drawable.setIntrinsicHeight((int) (backgroundHeight + 2 * factor));
drawable.setIntrinsicWidth((int) (backgroundWidth + 2 * factor));
drawable.setBounds(0, 0, backgroundWidth, backgroundHeight);
canvas.translate(iconSize - backgroundWidth - 2 * strokeThickness,
2 * strokeThickness);
drawable.draw(canvas);
canvas.restore();// 重置為之前保存的狀態(tài)
// 繪制數(shù)字
canvas.drawText(
num,
(float) (iconSize
- (backgroundWidth + textWidth + 4 * strokeThickness)
/ 2 - 1), (22) * factor + 2 * strokeThickness,
numPaint);
}
return numIcon;
}
/**
* 圓角矩形史飞,相當(dāng)于用<shape>的xml的背景
*
* @param context 上下文
* @return
*/
private static ShapeDrawable getDefaultBackground(Context context) {
// 這個(gè)是為了應(yīng)對(duì)不同分辨率的手機(jī),屏幕兼容性
int r = dipToPixels(context, DEFAULT_CORNER_RADIUS_DIP);
float[] outerR = new float[]{r, r, r, r, r, r, r, r};
// 圓角矩形
RoundRectShape rr = new RoundRectShape(outerR, null, null);
ShapeDrawable drawable = new ShapeDrawable(rr);
drawable.getPaint().setColor(DEFAULT_NUM_COLOR);// 設(shè)置顏色
return drawable;
}
/**
* 圓角矩形仰税,相當(dāng)于用<shape>的xml的背景
*
* @param context 上下文
* @return
*/
private static ShapeDrawable getDefaultStrokeDrawable(Context context) {
// 這個(gè)是為了應(yīng)對(duì)不同分辨率的手機(jī)构资,屏幕兼容性
int r = dipToPixels(context, DEFAULT_CORNER_RADIUS_DIP);
int distance = dipToPixels(context, DEFAULT_STROKE_WIDTH_DIP);
float[] outerR = new float[]{r, r, r, r, r, r, r, r};
// 圓角矩形
RoundRectShape rr = new RoundRectShape(outerR, null, null);
ShapeDrawable drawable = new ShapeDrawable(rr);
drawable.getPaint().setStrokeWidth(distance);
drawable.getPaint().setStyle(Paint.Style.FILL);
drawable.getPaint().setColor(DEFAULT_STROKE_COLOR);// 設(shè)置顏色
return drawable;
}
/**
* dp to px
*
* @param context 上下文
* @param dip
* @return
*/
public static int dipToPixels(Context context, int dip) {
Resources r = context.getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
r.getDisplayMetrics());
return (int) px;
}
/**
* 在原圖右上角畫圓形狀態(tài)標(biāo)志,其中icon為原圖陨簇,color為所需狀態(tài)標(biāo)示的顏色吐绵,一般取值為"Color.**",r為所畫圓的半徑
*
* @param icon 原圖
* @param res 獲取Resources
* @param color 所需狀態(tài)標(biāo)示的顏色,一般取值為"Color.**"
* @param r 所畫圓的半徑
* @return
*/
public static Bitmap generatorStatusIcon(Bitmap icon, Resources res,
int color, int r) {
// 初始化畫布
int iconSize = (int) res.getDimension(android.R.dimen.app_icon_size);
Bitmap contactIcon = Bitmap.createBitmap(iconSize, iconSize,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(contactIcon);
// 拷貝圖片
Paint iconPaint = new Paint();
iconPaint.setDither(true);// 防抖動(dòng)
iconPaint.setFilterBitmap(true);// 用來(lái)對(duì)Bitmap進(jìn)行濾波處理,這樣河绽,當(dāng)你選擇Drawable時(shí)拦赠,會(huì)有抗鋸齒的效果
Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
Rect dst = new Rect(0, 0, iconSize, iconSize);
canvas.drawBitmap(icon, src, dst, iconPaint);
Paint countPaint = new Paint(Paint.ANTI_ALIAS_FLAG
| Paint.DEV_KERN_TEXT_FLAG);
countPaint.setColor(color);
canvas.drawCircle(iconSize - r, r, r, countPaint);
return contactIcon;
}
/**
* 傳入一張Bitmap型的方形圖片使之變成圓形
*
* @param bitmap 圖片
* @return
*/
public static Bitmap makeRoundCorner(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int left = 0, top = 0, right = width, bottom = height;
float roundPx = height / 2;
if (width > height) {
left = (width - height) / 2;
top = 0;
right = left + height;
bottom = height;
} else if (height > width) {
left = 0;
top = (height - width) / 2;
right = width;
bottom = top + width;
roundPx = width / 2;
}
Bitmap output = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
int color = 0xff424242;
Paint paint = new Paint();
Rect rect = new Rect(left, top, right, bottom);
RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 傳入一張Bitmap型的方形圖片使之變成圓角矩形,ratio值在1以上就很明顯
*
* @param bitmap 圖片
* @param ratio 比例葵姥,這里是寬高與半徑的比例
* @return
*/
public static Bitmap toRoundCorner(Bitmap bitmap, float ratio) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(rectF, bitmap.getWidth() / ratio,
bitmap.getHeight() / ratio, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 使bitmap圖標(biāo)邊角圓弧化荷鼠,pixels值在10以上才比較明顯,變化慢
*
* @param bitmap 圖片
* @param pixels 圓角的半徑
* @return
*/
public static Bitmap toRoundCorner_1(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.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(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 在一張背景圖片上合成四個(gè)頭像
*
* @param backGroundIcon 背景圖片
* @param res 獲取Resources
* @param first 圖片1
* @param second 圖片2
* @param third 圖片3
* @param four 圖片4
* @return
*/
public static Bitmap add4Bitmap(Bitmap backGroundIcon, Resources res,
Bitmap first, Bitmap second, Bitmap third, Bitmap four) {
int iconSize = (int) res.getDimension(android.R.dimen.app_icon_size);
Bitmap contactIcon = Bitmap.createBitmap(iconSize, iconSize,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(contactIcon);
Paint iconPaint = new Paint();
iconPaint.setDither(true);// 防抖動(dòng)
iconPaint.setFilterBitmap(true);// 用來(lái)對(duì)Bitmap進(jìn)行濾波處理榔幸,這樣允乐,當(dāng)你選擇Drawable時(shí),會(huì)有抗鋸齒的效果
Rect src = new Rect(0, 0, backGroundIcon.getWidth(),
backGroundIcon.getHeight());
Rect dst = new Rect(0, 0, iconSize, iconSize);
canvas.drawBitmap(backGroundIcon, src, dst, iconPaint);
int width = iconSize / 2;
int height = iconSize / 2;
canvas.drawBitmap(pictureZoom(first, iconSize / 2, iconSize / 2), 0, 0,
iconPaint);
canvas.drawBitmap(pictureZoom(second, iconSize / 2, iconSize / 2),
width, 0, iconPaint);
canvas.drawBitmap(pictureZoom(third, iconSize / 2, iconSize / 2), 0,
height, iconPaint);
canvas.drawBitmap(pictureZoom(four, iconSize / 2, iconSize / 2), width,
height, iconPaint);
return contactIcon;
}
/**
* 圖片縮放
*
* @param bitMap 原圖片
* @param newWidth 新的寬
* @param newHeight 新的高
* @return
*/
public static Bitmap pictureZoom(Bitmap bitMap, int newWidth, int newHeight) {
int width = bitMap.getWidth();
int height = bitMap.getHeight();
// 計(jì)算縮放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要縮放的matrix參數(shù)
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的圖片
bitMap = Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix, true);
return bitMap;
}
/**
* 渲染成灰色圖片
*
* @param bitmap 圖片
* @return
*/
public static final Bitmap grey(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap faceIconGreyBitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(faceIconGreyBitmap);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
ColorMatrixColorFilter colorMatrixFilter = new ColorMatrixColorFilter(
colorMatrix);
paint.setColorFilter(colorMatrixFilter);
canvas.drawBitmap(bitmap, 0, 0, paint);
return faceIconGreyBitmap;
}
}