android大分辨率图片的缩放处理和图片添加水印+文字,水印图片对角线显示

最近在做李宁的一个项目,要求特别高,所以今天记录一下自己遇到的难点,希望对初学者有用!本来想着用android系统图库的原来实现的,但是图片加密解密麻烦,图片也不让放本地。

流转换Bitmap的方法

public Bitmap doBitmapFile(InputStream in, boolean isFlag) {// isFlag是一个标志 true表示是大图  false小图
		Bitmap bitmap = null;//
		BitmapFactory.Options options = null;
		ByteArrayOutputStream outStream = null;
		final int BUFFER_SIZE = 2048;
		if (in == null) {
			return null;
		}
		try {
			outStream = new ByteArrayOutputStream();
			byte[] bytes = new byte[BUFFER_SIZE];
			int len = -1;
			while ((len = in.read(bytes)) != -1) {
			        outStream.write(bytes, 0, len);
				outStream.flush();
			}
			byte[] data = new byte[outStream.toByteArray().length];
			data = outStream.toByteArray();
			options = new BitmapFactory.Options();
			// 这里设置true的时候,decode时候Bitmap返回的为空, 将图片宽高读取放在Options里.
			options.inJustDecodeBounds = true;
			options.inTempStorage = new byte[16 * 1024];
			options.inPreferredConfig = Bitmap.Config.ARGB_8888;
			options.inInputShareable = true;
			options.inPurgeable = true;
			options.inDither = false;
			BitmapFactory.decodeByteArray(data, 0, data.length, options);
			if (isFlag) {// 计算浏览单张图片的缩放比例值
				int totalSize = 0;
				int width = options.outWidth;
				int height = options.outHeight;
				totalSize = width * height * 4;//计算图片内存占用大小
				if (totalSize < 13631488) {
					options.inSampleSize = 1;
				} else {
					int maxNumOfPixels = 1280 * 1280 * 2;
					options.inSampleSize = computeSampleSize(options, -1, maxNumOfPixels);
				}
			} else {// 计算浏览列表显示图片的缩放比例值
				int maxNumOfPixels = MAX_RESOLUTION_A * MAX_RESOLUTION_B * 2;
				options.inSampleSize = computeSampleSize(options, -1, maxNumOfPixels);
				options.outWidth = options.outWidth / options.inSampleSize;
				options.outHeight = options.outHeight / options.inSampleSize;
			}
			options.inJustDecodeBounds = false;
			bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
			return watermarkBitmap(recycleBitmap(bitmap), "水印文字内容", Context, options);
		} catch (OutOfMemoryError e) {
			bitmap = null;
			System.gc();
			Log.e("Eeron", e.getMessage().toString());
			e.printStackTrace();
			return null;
		} catch (Exception e) {
			bitmap = null;
			System.gc();
			Log.e("Eeron", e.getMessage().toString());
			return null;
		} finally {
			closeStream(in);
			closeStream(outStream);
		}
	}

	/**
	 * @Description: 关闭流
	 * @param stream
	 * @return: void
	 */
	private static void closeStream(Closeable stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				Log.e("LiNing", "Could not close stream", e);
			}
		}
	}</span>
水印添加方法:

        /**
	 * @Description: 添加水印
	 * @param bitmap
	 * @param title
	 * @param context
	 * @return
	 * @return: Bitmap
	 */
	public static Bitmap watermarkBitmap(Bitmap bitmap, String title, Context context, Options options) {
		if (bitmap == null) {
			return null;
		}
		Bitmap watermark = BitmapFactory.decodeResource(context.getResources(), R.drawable.add_water_mark, options);
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		// 需要处理图片太大造成的内存超过的问题,这里我的图片很小所以不写相应代码了
		Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
		Canvas cv = new Canvas(newb);
		cv.drawBitmap(bitmap, 0, 0, null);// 在 0,0坐标开始画入src
		// 加入图片
		if (watermark != null) {
			int ww = watermark.getWidth();
			int wh = watermark.getHeight();
			Rect src = new Rect();// 图片
			Rect dst = new Rect();// 屏幕位置及尺寸
			src.left = 0; // 0,0
			src.top = 0;
			src.right = w;// 是桌面图的宽度,
			src.bottom = h;// 是桌面图的高度
			// 下面的 dst 是表示 绘画这个图片的位置
			dst.left = 0; // 绘图的起点X位置
			dst.top = 0; // 相当于 桌面图片绘画起点的Y坐标
			dst.right = ww + w - 60; // 表示需绘画的图片的右上角
			dst.bottom = wh + h - 60; // 表示需绘画的图片的右下角
			cv.drawBitmap(watermark, src, dst, null);// 在src的右下角画入水印
			src = null;
	        dst = null;
		}
		// 加入文字
		if (title != null) {
			String familyName = "宋体";
			Typeface font = Typeface.create(familyName, Typeface.BOLD);
			TextPaint textPaint = new TextPaint();
			textPaint.setColor(Color.RED);
			textPaint.setTypeface(font);
			textPaint.setTextSize(22);
			textPaint.setAlpha(50);
			cv.drawText(title, 40, h - 30, textPaint);
		}
		cv.save(Canvas.ALL_SAVE_FLAG);// 保存
		cv.restore();// 存储
		watermark.recycle();
		bitmap.recycle();
		return recycleBitmap(newb);
	}</span>
Bitmap内存释放方法:

        public static Bitmap recycleBitmap(Bitmap bitmap) {
		if (bitmap == null || bitmap.getConfig() != null) {
			return bitmap;
		}
		Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
		bitmap.recycle();
		return newBitmap;
	}

动态计算options.inSampleSize的方法,这个是我从android系统图库里面弄过来的

        /**
	 * @Description:
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return 动态计算出图片的inSampleSize
	 * @return: int
	 */
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}
		return roundedSize;
	}

private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;
		// Math.ceil(Math.sqrt(w * h / maxNumOfPixels)) :w * h /
		// maxNumOfPixels平方结果的小数部分一律向整数部分进位
		int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
		// Math.floor(w / minSideLength) 将w / minSideLength结果值一律舍去小数,仅保留整数
		int upperBound = (minSideLength == UNCONSTRAINED) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
		if (upperBound < lowerBound) {
			return lowerBound;
		}
		if ((maxNumOfPixels == UNCONSTRAINED) && (minSideLength == UNCONSTRAINED)) {
			return 1;
		} else if (minSideLength == UNCONSTRAINED) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值