import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Log;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.weijuba.api.utils.FileUtils;
import java.io.File;
/**
* Created by 大灯泡 on 2015/11/13.
* 水印工具类(请在异步线程执行本操作)
*/
public class WaterMarkUtils {
public static final int TYPE_PIC = 1;
public static final int TYPE_CHAR = 2;
public static final int POS_LEFT = 11;
public static final int POS_MIDDLE = 20;
public static final int POS_RIGHT = 30;
public static final int POS_TOP = 40;
public static final int POS_BOTTOM = 55;
/**
* 对两个bitmap操作
*
* @param source 原图
* @param mark 水印图
* @param alpha 透明度
* @param posType 相对位置
* @param fileName url,一般传原图的url
*/
public static String addWaterMark(Bitmap source, Bitmap mark, int alpha, int posType,
String fileName) {
if (StringUtils.isEmpty(fileName)) fileName = "empty";
return addWaterMark(source, mark, "", alpha, 0, 0, TYPE_PIC, posType, fileName);
}
/**
* 添加文字水印
* @param sourceUrl 原图路径
* @param text 文字
* @param alpha 透明度
* @param color 颜色
* @param textSize 文字大小
* @param posType 相对位置
* @param fileName 文件名,如果是空,则默认赋值为"emtpy"
* @return
*/
public static String addCharWaterMark(String sourceUrl, String text, int alpha, int color,
int textSize, int posType, String fileName) {
if (StringUtils.isEmpty(fileName)) fileName = "empty";
return addWaterMark(ImageLoader.getInstance().loadImageSync(sourceUrl), null, text, alpha,
color, textSize, TYPE_CHAR, posType, fileName);
}
/**
* 添加图片水印
* @param sourceUrl 原图url
* @param markUrl 水印图url
* @param alpha 透明度
* @param posType 相对位置
* @return
*/
public static String addImageWaterMark(String sourceUrl, String markUrl, int alpha, int posType){
return addWaterMark(ImageLoader.getInstance().loadImageSync(sourceUrl),ImageLoader.getInstance().loadImageSync(markUrl),"",alpha,0,0,TYPE_PIC,posType,sourceUrl);
}
/**
* 添加文字水印
*
* @param source 原图路径
* @param charMark 文字
* @param alpha 透明度
* @param color 颜色
* @param size 文字大小
* @param posType 相对位置
*/
public static String addWaterMark(Bitmap source, String charMark, int alpha, int color,
int size, int posType,String fileName) {
if (StringUtils.isEmpty(fileName))
fileName="empty";
return addWaterMark(source, null, charMark, alpha, color, size, TYPE_CHAR, posType, fileName);
}
/**
* 最终方法
* @param source 原图
* @param mark 水印图
* @param charMark 文字
* @param alpha 透明度
* @param color 颜色
* @param size 大小
* @param type 类型
* @param posType 位置
* @param fileName 文件名
*/
private static String addWaterMark(Bitmap source, Bitmap mark, String charMark, int alpha,
int color, int size, int type, int posType, String fileName) {
Bitmap outPutBitmap = null;
switch (type) {
case TYPE_PIC:
return addPicMark(source, mark, alpha, posType, fileName);
case TYPE_CHAR:
return addCharMark(source, charMark, alpha, color, size, posType, fileName);
default:
break;
}
return null;
}
/** 添加文字水印 */
private static String addCharMark(Bitmap source, String charMark, int alpha, int color,
int size, int posType, String url) {
if (source == null || source.isRecycled()) return null;
Bitmap outPut = null;
if (StringUtils.notEmpty(charMark)) {
int w = source.getWidth();
int h = source.getHeight();
//样式
String fontType = "宋体";
Typeface font = Typeface.create(fontType, Typeface.NORMAL);
TextPaint textPaint = new TextPaint();
textPaint.setColor(color);
textPaint.setTypeface(font);
textPaint.setTextSize(size);
//换行确定
StaticLayout layout =
new StaticLayout(charMark, textPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F,
true);
try {
//生成与原图大小一致的空画布
outPut = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas cv = new Canvas(outPut);
// 在 0,0坐标开始画入src
cv.drawBitmap(source, 0, 0, null);
int markW = layout.getWidth();
int markH = layout.getHeight();
int[] pos = getMarkPos(w, h, markW, markH, posType);
cv.drawText(charMark, pos[0], pos[1], textPaint);
cv.save(Canvas.ALL_SAVE_FLAG);// 保存
cv.restore();// 存储
} catch (OutOfMemoryError error) {
Log.i("OutOfMemoryError", "out of memory, clearing mem cache");
outPut = null;
}
}
return new saveBitmap(outPut, url).getUrl();
}
/** 添加图片水印 */
private static String addPicMark(Bitmap source, Bitmap mark, int alpha, int posType,
String url) {
if (source == null || source.isRecycled()) return null;
Bitmap outPut = null;
int w = source.getWidth();
int h = source.getHeight();
try {
//生成与原图大小一致的空画布
outPut = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas cv = new Canvas(outPut);
// 在 0,0坐标开始画入src
cv.drawBitmap(source, 0, 0, null);
Paint paint = new Paint();
//加入图片
if (mark == null || mark.isRecycled()) return null;
int markW = mark.getWidth();
int markH = mark.getHeight();
//需要透明度么。。。。
paint.setAlpha(50);
int pos[] = getMarkPos(w, h, markW, markH, posType);
// 在src的对应位置画入水印
cv.drawBitmap(mark, pos[0], pos[1], paint);
// 保存
cv.save(Canvas.ALL_SAVE_FLAG);
// 存储
cv.restore();
} catch (OutOfMemoryError error) {
Log.i("OutOfMemoryError", "out of memory, clearing mem cache");
outPut = null;
}
return new saveBitmap(outPut, url).getUrl();
}
/** 得到各个位置类型的水印所处的left和top */
private static int[] getMarkPos(int sourceW, int sourceH, int markW, int markH, int posType) {
int[] markPos = new int[2];
//距离边缘n像素
int padding = 10;
if (sourceW > markH && sourceH > markH) {
switch (posType) {
case POS_LEFT:
//左边(默认左下)
markPos[0] = 0 + padding;
markPos[1] = sourceH - padding - markH;
break;
case POS_LEFT + POS_TOP:
//左上
markPos[0] = 0 + padding;
markPos[1] = 0 + padding;
break;
case POS_LEFT + POS_MIDDLE:
//左中
markPos[0] = 0 + padding;
markPos[1] = sourceH / 2 - markH / 2;
break;
case POS_LEFT + POS_BOTTOM:
//左下
markPos[0] = 0 + padding;
markPos[1] = sourceH - padding - markH;
break;
case POS_MIDDLE:
//正中
markPos[0] = sourceW / 2 - markW / 2;
markPos[1] = sourceH / 2 - markH / 2;
break;
case POS_MIDDLE + POS_TOP:
//上中
markPos[0] = sourceW / 2 - markW / 2;
markPos[1] = 0 + padding;
break;
case POS_MIDDLE + POS_BOTTOM:
//下中
markPos[0] = sourceW / 2 - markW / 2;
markPos[1] = sourceH - padding - markH;
break;
case POS_RIGHT:
//右(默认右下)
markPos[0] = sourceW - markW - padding;
markPos[1] = sourceH - padding - markH;
break;
case POS_RIGHT + POS_TOP:
//右上
markPos[0] = sourceW - markW - padding;
markPos[1] = 0 + padding;
break;
case POS_RIGHT + POS_MIDDLE:
//右中
markPos[0] = sourceW - markW - padding;
markPos[1] = sourceH / 2 - markH / 2;
break;
case POS_RIGHT + POS_BOTTOM:
//右下
markPos[0] = sourceW - markW - padding;
markPos[1] = sourceH - padding - markH;
break;
default:
break;
}
}
return markPos;
}
/** 保存bitmap到本地 */
static class saveBitmap {
Bitmap mBitmap;
private String path = "";
private Runnable mRunnable;
private String name;
public saveBitmap(Bitmap bitmap, String name) {
mBitmap = bitmap;
this.name = name;
}
public String getUrl() {
if (StringUtils.notEmpty(name)) {
this.name = MD5Tools.MD5(name);
}
File file = new File(FileUtils.getWaterMarkImagePath() + name + ".jpg");
if (!file.exists()) {
if (mBitmap != null && !mBitmap.isRecycled()) {
FileUtils.saveBitmapToSD(FileUtils.getWaterMarkImagePath() + name + ".jpg",
mBitmap);
path = FileUtils.getWaterMarkImagePath() + name + ".jpg";
}
} else {
path = FileUtils.getWaterMarkImagePath() + name + ".jpg";
}
return path;
}
}
}
调用很简单,只需要调用那几个static方法即可。另外,最后那个saveBitmap那里的几个路径需要针对自己的工程进行修改
本文介绍了一个水印工具类,提供简单的方法来添加图片与文字水印到原始图像上,包括参数设置如透明度、位置等,并支持异步线程执行。适用于多种图像处理场景。
844

被折叠的 条评论
为什么被折叠?



