很久没有写笔记了,我决定拾回来。
最近做了一些需求,记录下来,需求是:从手机相册选取一些图片,然后给这些图片添加水印,然后将添加后的图片BitMap转化成byte上传到阿里云,从阿里云拿到地址,然后再将图片地址上传到我们自己的服务器。
其他的我就不多说,我就说一下添加水印的事情,百度网上很多关于添加水印的代码,但是出现一个问题,就是将水印打印到图片上去后,然后图片再到App,显示上去后,不同图片,显示出来的水印大小不一样(如下图),但是老板的要求是不管原始图多大,水印图必须一致大小。
网上很多方法之所以水印大小不一样,原因是原图尺寸大小不一样,然后当显示到App上时,我们的App显示图片时图片的宽和屏幕的宽一样,图片的高就按照比例缩放了,导致的结果是水印也跟着缩放,导致水印大小不一样,这是我解决这个方法的代码。
/**
* 给图片加水印,网上
* 右下角
* @param src 原图
* @param watermark 水印
* @return 加水印的原图
*/
public static Bitmap WaterMask(Bitmap src, Bitmap watermark) {
int w = src.getWidth();
int h = src.getHeight();
Log.i("WaterMask", "原图宽: "+w);
Log.i("WaterMask", "原图高: "+h);
// 设置原图想要的大小
float newWidth = ScreenUtils.getScreenWidth();
float newHeight = h*(newWidth/w);
// 计算缩放比例
float scaleWidth = ( newWidth) / w;
float scaleHeight = (newHeight) / h;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
src = Bitmap.createBitmap(src, 0, 0, w, h, matrix, true);
//根据bitmap缩放水印图片
float w1 = w / 5;
float h1 = (float) (w1 / 5);
//获取原始水印图片的宽、高
int w2 = watermark.getWidth();
int h2 = watermark.getHeight();
//计算缩放的比例
float scalewidth = ((float) w1) / w2;
float scaleheight = ((float) h1) / h2;
Matrix matrix1 = new Matrix();
matrix1.postScale((float) 0.4, (float) 0.4);
watermark = Bitmap.createBitmap(watermark, 0, 0, w2, h2, matrix1, true);
//获取新的水印图片的宽、高
w2 = watermark.getWidth();
h2 = watermark.getHeight();
Bitmap result = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
Canvas cv = new Canvas(result);
//在canvas上绘制原图和新的水印图
cv.drawBitmap(src, 0, 0, null);
//水印图绘制在画布的右下角,距离右边和底部都为20
cv.drawBitmap(watermark, src.getWidth() - w2-20, src.getHeight() - h2-20, null);
cv.save(Canvas.ALL_SAVE_FLAG);
cv.restore();
return result;
}
关键在与下面这段代码:我将所有原图的宽度压缩或放大到屏幕的宽度,然后将图片的高根据图片的宽度和屏幕宽度的比例来缩放就好了。
float newWidth = ScreenUtils.getScreenWidth();
float newHeight = h*(newWidth/w);
// 计算缩放比例
float scaleWidth = ( newWidth) / w;
float scaleHeight = (newHeight) / h;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
src = Bitmap.createBitmap(src, 0, 0, w, h, matrix, true);
这个功能的其他代码:
//将手机上选择的图片地址转成bitmap
//pathName传手机图片的路径,后面的opts传Null就行
public static Bitmap decodeFile(String pathName, Options opts) {
Bitmap bm = null;
InputStream stream = null;
try {
stream = new FileInputStream(pathName);
bm = decodeStream(stream, null, opts);
} catch (Exception e) {
/* do nothing.
If the exception happened on open, bm will be null.
*/
Log.e("BitmapFactory", "Unable to decode stream: " + e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// do nothing here
}
}
}
return bm;
}
将水印转换成bitmap,由于水印是放在我的项目文件夹下,直接将项目文件夹下的图片转成bitMap就行
//第一个参数this.getResources(),第二个参数 R.mipmap.watermark,第三个参数传Null
public static Bitmap decodeResource(Resources res, int id, Options opts) {
Bitmap bm = null;
InputStream is = null;
try {
final TypedValue value = new TypedValue();
is = res.openRawResource(id, value);
bm = decodeResourceStream(res, value, is, null, opts);
} catch (Exception e) {
/* do nothing.
If the exception happened on open, bm will be null.
If it happened on close, bm is still valid.
*/
} finally {
try {
if (is != null) is.close();
} catch (IOException e) {
// Ignore
}
}
if (bm == null && opts != null && opts.inBitmap != null) {
throw new IllegalArgumentException("Problem decoding into existing bitmap");
}
return bm;
}