Android压缩图片并保持不失真的高效方法以及为图片添加水印

申明:1、本人有点懒,在设置控件id以及命名时,并不规范,望见谅!2、本人菜鸟一枚,还望路过的大神指点为谢!

本文主要内容:1、使用两张图片合成水印。 2、将文字直接绘制到图片上。3、获取手机或sd卡上的图片,压缩并显示。

好了,废话不多说,直接上代码,在代码中都有详细的注释

以下是使用两张图片合成水印

        /**
	 * 使用两张图片合成水印的方法
	 * 
	 * @param src
	 *            主图片
	 * @param watermark
	 *            水印图片
	 * @return
	 */
	private Bitmap myCreateBitmap(Bitmap src, Bitmap watermark) {
		if (src == null) {
			return null;
		}
		int w = src.getWidth();
		int h = src.getHeight();
		int ww = watermark.getWidth();
		int wh = watermark.getHeight();
		// create the new blank bitmap
		Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 截取特定大小的图片
		// 创建一个新的和SRC长度宽度一样的位图
		Canvas cv = new Canvas(newb);
		// draw src into
		cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src
		// draw watermark into
		cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印
		// save all clip
		cv.save(Canvas.ALL_SAVE_FLAG);// 保存
		// store
		cv.restore();// 存储
		return newb;
	}

以下是将文字直接绘制到图片上,myCreateBitmap(Bitmap src, String str)方法的第二个参数是通过调用getViewBitmap(View v)返回的

        /**
	 * 将文字直接绘制到图片上
	 * 
	 * @param src
	 * @param str
	 * @return
	 */
	private Bitmap myCreateBitmap(Bitmap src, String str) {
		Time t = new Time();
		t.setToNow();// 当前时间
		int w = src.getWidth();
		int h = src.getHeight();
		String mstrTitle = t.hour + ":" + t.minute + ":" + t.second;
		str = str + mstrTitle;
		Bitmap bmpTemp = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 截取特定大小的图片
		Canvas canvas = new Canvas(bmpTemp);
		Paint p = new Paint();
		String familyName = "宋体";
		Typeface font = Typeface.create(familyName, Typeface.BOLD);
		p.setColor(Color.BLUE);
		p.setTypeface(font);
		p.setTextSize(22);
		canvas.drawBitmap(src, 0, 0, p);// 绘制在src的左上角
		canvas.drawText(str, 0, 40, p);
		canvas.save(Canvas.ALL_SAVE_FLAG);
		canvas.restore();
		return bmpTemp;
	}

	/**
	 * 获取要添加水印的位图
	 * 
	 * @param v
	 * @return
	 */
	private Bitmap getViewBitmap(View v) {
		v.clearFocus();
		v.setPressed(false);

		// 保存原设置
		boolean willNotCache = v.willNotCacheDrawing();
		// 不使用缓存绘制
		v.setWillNotCacheDrawing(false);

		// Reset the drawing cache background color to fully transparent
		// for the duration of this operation
		// 保存原背景
		int color = v.getDrawingCacheBackgroundColor();

		// 去View背景
		v.setDrawingCacheBackgroundColor(0);

		if (color != 0) {
			v.destroyDrawingCache();
		}
		// 重建缓存
		v.buildDrawingCache();
		Bitmap cacheBitmap = v.getDrawingCache();
		if (cacheBitmap == null) {
			Log.i("info", "cacheBitmap is null");
			return null;
		}

		Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
		// Restore the view 恢复视图
		v.destroyDrawingCache();// 清理视图缓存
		v.setWillNotCacheDrawing(willNotCache);// 恢复原设置
		v.setDrawingCacheBackgroundColor(color);// 设置View背景

		return bitmap;
	}

以下是压缩图片的方法

        /**
	 * 根据路径获得图片并压缩,返回bitmap用于显示
	 * 
	 * @param filePath
	 * @return
	 */
	public Bitmap getSmallBitmap(String filePath) {
		final BitmapFactory.Options options = new BitmapFactory.Options();
		/* 设置为true,可以不把图片读到内存中,但依然可以计算出图片的大小,这正是我们需要的 */
		options.inJustDecodeBounds = true;
		File file = new File(filePath);
		InputStream is = null;
		try {
			if (file.exists()) {

				is = new FileInputStream(file);
				// BitmapFactory.decodeFile(filePath, options);
				BitmapFactory.decodeStream(is, null, options);

				// Calculate inSampleSize
				options.inSampleSize = calculateInSampleSize(options, 400, 200);

				// Decode bitmap with inSampleSize set
				options.inJustDecodeBounds = false;

				Log.i("info", "options.inSampleSize=" + options.inSampleSize);
				// 这样重新获取一个新的is输入流,就可以解决decodeStream(is,null, options)返回null的问题
				is = new FileInputStream(file);

				Bitmap bm = BitmapFactory.decodeStream(is, null, options);
				return bm;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 计算图片的缩放值
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		/* 压缩一张图片。我们需要知道这张图片的原始大小,然后根据我们设定的压缩比例进行压缩。 */
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;
		/*
		 * 1、如果图片的原始高度或者宽带大约我们期望的宽带和高度,我们需要计算出缩放比例的数值。否则就不缩放
		 * 2、如果使用大的值作位压缩倍数,则压缩出来的图片大小会小于我们设定的值
		 * 3、如果使用小的值作位压缩倍数,则压缩出来的图片大小会大于我们设定的值
		 */
		if (height > reqHeight || width > reqWidth) {
			final int heightRatio = Math.round((float) height / (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}
		return inSampleSize;
	}
注:1、以上就是主要的实现代码,至于整个运行之后的效果图就贴出来,可以自己动手建一个小Demo,看看效果。

        2、如果实在不想自己创建那么也可以点击这里下载,demo中有定义的有几个方法以及Base64.java,本文中未提到,只是觉得可能在一些相关图片处理的项目会用到,所以一同写进去了。



后补:这里有篇文章讲的很详细http://blog.csdn.net/moubenmao_jun/article/details/20055189

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值