android imageloader加密解密图片

android 项目中开发为了节省周期又或者不重复造轮子都会选择一些开源框架来设计我们的app,而imageloader是加载网络本地图片的一大利器,但是其本身并未提供加密和解密的方法,需要我们从源码中自己改写。


首先简略的说下imageloader的工作原理,在displayImage方法中我们可以看到:


Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);//获软引用的图片
		if (bmp != null && !bmp.isRecycled()) {
			L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);

			if (options.shouldPostProcess()) {
				ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
						options, listener, progressListener, engine.getLockForUri(uri));
				ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo,
						defineHandler(options));
				if (options.isSyncLoading()) {
					displayTask.run();
				} else {
					engine.submit(displayTask);
				}
			} else {
				options.getDisplayer().display(bmp, imageAware, LoadedFrom.MEMORY_CACHE);
				listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp);
			}
		} else {如果没有则主要跑<span style="font-family: Arial, Helvetica, sans-serif;">LoadAndDisplayImageTask方法来检索本地缓存文件或网络下载</span>
			if (options.shouldShowImageOnLoading()) {
				imageAware.setImageDrawable(options.getImageOnLoading(configuration.resources));
			} else if (options.isResetViewBeforeLoading()) {
				imageAware.setImageDrawable(null);
			}

			ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
					options, listener, progressListener, engine.getLockForUri(uri));
			LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo,
					defineHandler(options));
			if (options.isSyncLoading()) {
				displayTask.run();
			} else {
				engine.submit(displayTask);
			}
		}
再追溯到 LoadAndDisplayImageTask文件

bmp = configuration.memoryCache.get(memoryCacheKey);//再次检索
			if (bmp == null || bmp.isRecycled()) {
				bmp = tryLoadBitmap();//尝试从别的地方获取,也就是从文件和网络获取了
				if (bmp == null) return; // listener callback already was fired

				checkTaskNotActual();
				checkTaskInterrupted();

				if (options.shouldPreProcess()) {
					L.d(LOG_PREPROCESS_IMAGE, memoryCacheKey);
					bmp = options.getPreProcessor().process(bmp);
					if (bmp == null) {
						L.e(ERROR_PRE_PROCESSOR_NULL, memoryCacheKey);
					}
				}

				if (bmp != null && options.isCacheInMemory()) {
					L.d(LOG_CACHE_IMAGE_IN_MEMORY, memoryCacheKey);
					configuration.memoryCache.put(memoryCacheKey, bmp);
				}
			} else {
				loadedFrom = LoadedFrom.MEMORY_CACHE;
				L.d(LOG_GET_IMAGE_FROM_MEMORY_CACHE_AFTER_WAITING, memoryCacheKey);
			}
那么,从网络下载到本地, 再从本地取出解析并加载到页面上就是我们关注的地方了,首先我们看到
tryLoadBitmap
方法过程中,会判断diskCache中是否有我们的缓存文件,如果有则解析,没有通过tryCacheImageOnDisk方法以及downloadImage(),resizeAndSaveImage()来缓存到本地并解析。


那么直接看加密和解密的地方。


加密:

查看源码,我们可以看到IoUtils.java中就是我们下载image到本地的关键之处

	public static boolean copyStream(InputStream is, OutputStream os,
			CopyListener listener, int bufferSize) throws IOException {
		int current = 0;
		int total = is.available();
		if (total <= 0) {
			total = DEFAULT_IMAGE_TOTAL_SIZE;
		}
		int read;
		if (shouldStopLoading(listener, current, total))
			return false;
		// while ((count = is.read(bytes, 0, bufferSize)) != -1) {
		// os.write(bytes, 0, count);
		// current += count;
		// if (shouldStopLoading(listener, current, total))
		// return false;
		// }
		while ((read = is.read()) != -1) {
			os.write(read ^ 0x99);//这个随意,右移>>或<<都可
			current++;
			if (shouldStopLoading(listener, current, total))
				return false;
		}
		os.flush();
		return true;
	}
直接在写的方法中,右移之类的改变自己的数据即可


解密:BaseImageDecoder方法中

public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
		Bitmap decodedBitmap;
		ImageFileInfo imageInfo;

		InputStream imageStream = getImageStream(decodingInfo);
		if (imageStream == null) {
			L.e(ERROR_NO_IMAGE_STREAM, decodingInfo.getImageKey());
			return null;
		}
		try {
			imageInfo = defineImageSizeAndRotation(imageStream, decodingInfo);
			imageStream = resetStream(imageStream, decodingInfo);
			Options decodingOptions = prepareDecodingOptions(
					imageInfo.imageSize, decodingInfo);
			decodedBitmap =readBitmap(imageStream, decodingOptions);
//			decodedBitmap = BitmapFactory.decodeStream(imageStream, null,
//					decodingOptions);
		} finally {
			IoUtils.closeSilently(imageStream);
		}

		if (decodedBitmap == null) {
			L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());
		} else {
			decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap,
					decodingInfo, imageInfo.exif.rotation,
					imageInfo.exif.flipHorizontal);
		}
		return decodedBitmap;
	}

	public Bitmap readBitmap(InputStream is,Options decodingOptions) {
		Bitmap bitmap = null;
		List<Byte> list = new ArrayList();
		try {
			int read;
			while ((read = is.read()) > -1) {
				read = read ^ 0X99;
				list.add((byte) read);
			}
			byte[] arr = new byte[list.size()];
			int i = 0;
			for (Byte item : list) {
				arr[i++] = item;
			}
			bitmap = BitmapFactory.decodeByteArray(arr, 0, list.size(),decodingOptions);
			System.out.println(bitmap);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bitmap;
	}
即可。谢谢





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值