图片加水印
图片加水印
我尝试了两种实现水印的方式
1、一个轻量级是我文字和图片水印框架
2、通过Canvas绘制水印
轻量级的我就不做笔记了,因为很简单就能实现你想要的水印,留意内存溢出就好。
下面主要记录下第二种方式加水印。
效果图如下:
正文
//打开相机
openCamera(this);
/**
* 打开相机
*/
private void openCamera(Activity activity) {
//獲取系統版本
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (tvResult.getText().toString().length() > 0) {
//执行拍照前,应该先判断SD卡是否存在
String SDState = Environment.getExternalStorageState();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//"android.media.action.IMAGE_CAPTURE"
if (SDState.equals(Environment.MEDIA_MOUNTED)) {
File file = new File(FileUtil.getInstance().getImageFile( tvResult.getText().toString()));
if (!file.exists()) {
file.mkdirs();
}
// 从文件中创建uri
imageUri = Uri.fromFile(file);
if (currentapiVersion < 24) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra(FILE_PATH, file.getAbsoluteFile());
} else {
//兼容android7.0 使用共享文件的形式
ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
}
startActivityForResult(intent, TAKE_PICTURE);
Log.d("tag", "filepath = " + file.getAbsoluteFile());
} else {
Toast.makeText(this, getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "请先进行扫描或输入条形码", Toast.LENGTH_SHORT).show();
}
}
有人会说打开相机需要这么繁琐的代码吗?其实不需要,只是我的业务需要获取图片的路径,安卓碎片重,高版本的注重用户隐私的保护,相片就是用户隐私,所以需要区别对待。
获取图片路径:
/**
* 选择图片后,获取图片的路径
*
* @param requestCode
* @param data
*/
private void doPhoto(int requestCode, Intent data) {
/**
* 获取到的图片路径
*/
String picPath = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");// HH:mm:ss
// 获取当前时间
Date date = new Date(System.currentTimeMillis());
String dateStr = simpleDateFormat.format(date).toString();
if (requestCode == TAKE_PICTURE) {
String[] pojo = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(imageUri, pojo, null, null, null);
if (cursor != null) {
int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);
cursor.moveToFirst();
picPath = cursor.getString(columnIndex);
cursor.close();
} else { //小米4上取不到图片路径
try {
String[] strPaths = imageUri.toString().split("//");
picPath = strPaths[1];
} catch (Exception e) {
e.printStackTrace();
}
}
if (picPath != null && (picPath.toLowerCase().endsWith(".png") || picPath.toLowerCase().endsWith(".jpg"))) {
if (picPath == null || picPath.equals("")) {
Toast.makeText(this, "请重新拍照", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "pic = " + picPath, Toast.LENGTH_SHORT).show();
Bitmap bm = null;
try {
bm = FileUtil.getInstance().getImage(picPath, btnOpenCamera.getWidth(), btnOpenCamera.getHeight()); //获取限定宽高的bitmap,不限定则容易占用内存过大及OOM
if (bm == null) {
Toast.makeText(this, "请重新拍照", Toast.LENGTH_SHORT).show();
} else {
if (addWatermarkBitmap(bm, dateStr, btnOpenCamera.getWidth(), btnOpenCamera.getHeight())) {
Toast.makeText(this, "水印生成成功,文件已保存在 " + FileUtil.getInstance().IMAGE_PATH, Toast.LENGTH_SHORT).show();
}
}
} catch (OutOfMemoryError e) {
e.printStackTrace();
if (bm != null) {
bm.recycle();
}
System.gc();
}
} else {
Toast.makeText(this, "请重新拍照", Toast.LENGTH_LONG).show();
}
}
}
然后调用加水印并保存
private boolean addWatermarkBitmap(Bitmap bitmap, String str, int w, int h) {
int destWidth = w; //此处的bitmap已经限定好宽高
int destHeight = h;
Log.v("tag", "width = " + destWidth + " height = " + destHeight);
Bitmap icon = Bitmap.createBitmap(destWidth, destHeight, Bitmap.Config.ARGB_8888); //定好宽高的全彩bitmap
Canvas canvas = new Canvas(icon);//初始化画布绘制的图像到icon上
Paint photoPaint = new Paint(); //建立画笔
photoPaint.setDither(true); //获取跟清晰的图像采样
photoPaint.setFilterBitmap(true);//过滤一些
Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());//创建一个指定的新矩形的坐标
Rect dst = new Rect(0, 0, destWidth, destHeight);//创建一个指定的新矩形的坐标
canvas.drawBitmap(bitmap, src, dst, photoPaint);//将photo 缩放或则扩大到 dst使用的填充区photoPaint
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);//设置画笔
textPaint.setTextSize(destWidth / 20);//字体大小
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);//采用默认的宽度
textPaint.setAntiAlias(true); //抗锯齿
textPaint.setStrokeWidth(1);
textPaint.setAlpha(30);
// textPaint.setStyle(Paint.Style.STROKE); //空心
textPaint.setColor(Color.WHITE);//采用的颜色
// textPaint.setShadowLayer(1f, 0f, 3f, Color.LTGRAY);
// textPaint.setShadowLayer(3f, 1, 1,getResources().getColor(android.R.color.white));//影音的设置
canvas.drawText(str, destWidth / 2, destHeight - 45, textPaint);//绘制上去字,开始未知x,y采用那只笔绘制
// canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.save();
canvas.restore();
bitmap.recycle();
btnOpenCamera.setImageBitmap(icon);
return FileUtil.getInstance().saveMyBitmap(icon, tvResult.getText().toString()); //保存至文件
// return true;
}
我在这个重点是实现功能。over,完成。返回显示不难,难在难在加水印,然后保存,代码中也可以看出,添加的水印是自己在控件上方画中来的,然后更具控件的大小新生成一张图保存。主要是其中的一句话:
Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());//创建一个指定的新矩形的坐标
Rect dst = new Rect(0, 0, destWidth, destHeight);//创建一个指定的新矩形的坐标
canvas.drawBitmap(bitmap, src, dst, photoPaint);//将photo 缩放或则扩大到 dst使用的填充区photoPaint
那样先拍照的图片就在Canvas上面了,然后通过画笔Paint 在上面写字,保存图片:
Bitmap icon = Bitmap.createBitmap(destWidth, destHeight, Bitmap.Config.ARGB_8888); //定好宽高的全彩bitmap
Canvas canvas = new Canvas(icon);//初始化画布绘制的图像到icon上
文章中若有侵犯他*益,请及时通知我,我也只是做作笔记。