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

来源:互联网 发布:信用卡垫还 app 源码 编辑:程序博客网 时间:2024/06/08 15:51

申明: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 bitmapBitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 截取特定大小的图片// 创建一个新的和SRC长度宽度一样的位图Canvas cv = new Canvas(newb);// draw src intocv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src// draw watermark intocv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印// save all clipcv.save(Canvas.ALL_SAVE_FLAG);// 保存// storecv.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 inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, 400, 200);// Decode bitmap with inSampleSize setoptions.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 0
原创粉丝点击