1. Bitmap位圖
<!-- 對應於代碼中的對象時BitmapDrawable -->
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"
android:antialias="true" //抗鋸齒
android:tileMode="mirror"
//repeat:使圖片平鋪顯示,mirror:使用圖片又有鏡像又有平鋪顯示,clamp:複製邊緣的顏色,disabled:爲默認選項
android:filter="true" //位圖過濾
android:dither="true" //啓用或禁用抖動的位圖
android:gravity="center" //設置圖片的繪製位置 >
</bitmap>
2.selector背景選擇器
使用:1.在ListView中配置android:listSelector="@drawable/list_item_bg"
2.在listview的item中添加屬性android:background=“@drawable/list_item_bg"
3.代碼中使用 Drawable drawable = getResources().getDrawable(R.drawable.list_item_bg);
ListView.setSelector(drawable);android:cacheColorHint="@android:color/transparent"
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 默認時的背景圖片 -->
<item android:drawable="@drawable/pic1" />
<!-- 沒有焦點時的背景圖片 -->
<item android:state_window_focused="false" android:drawable="@drawable/pic1" />
<!-- 非觸摸模式下獲得焦點並單擊時的背景圖片 -->
<item android:state_focused="true" android:state_pressed="true" android:drawable= "@drawable/pic2" />
<!-- 觸摸模式下單擊時的背景圖片 -->
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/pic3" />
<!--選中時的圖片背景 -->
<item android:state_selected="true" android:drawable="@drawable/pic4" />
<!--獲得焦點時的圖片背景 -->
<item android:state_focused="true" android:drawable="@drawable/pic5" />
</selector>
3.shape控件顯示屬性
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 實心,就是填充的意思 -->
<solid
android:color="#ffeaeaea"/>
<!-- 漸變,android:angle是漸變角度,漸變默認的模式爲android:type="linear",即線性漸變,
可以指定漸變爲徑向漸變,android:type="radial",徑向漸變需要指定半徑android:gradientRadius="50"-->
<gradient
android:startColor="#ffeaeaea"
android:endColor="#ffeaeaea"
android:angle="270.0"
android:type="linear"
android:centerY="0.5" />
<padding
android:left="7.0dip"
android:top="7.0dip"
android:right="7.0dip"
android:bottom="7.0dip" />
<!-- 圓角,android:radius爲角的弧度,值越大角越圓 -->
<corners
android:radius="6.0dip" />
<!-- 描邊,把描邊弄成虛線的形式,設置方式爲:android:dashWidth="5dp" 橫線寬度 android:dashGap="3dp" 隔開的距離 -->
<stroke
android:color="#ffeaeaea"/>
</shape>
4.讀取本地圖片轉爲Bitmap
public class FileToBitmap {
public static Bitmap getBitmapFromFile(File dst, int width, int height) {
if (null != dst && dst.exists()) {
BitmapFactory.Options opts = null;
if (width > 0 && height > 0) {
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(dst.getPath(), opts);
final int minSideLength = Math.min(width, height);
opts.inSampleSize = computeSampleSize(opts, minSideLength,
width * height);
opts.inJustDecodeBounds = false;
opts.inInputShareable = true;
opts.inPurgeable = true;
}
try {
return BitmapFactory.decodeFile(dst.getPath(), opts);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
}
return null;
}
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;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
}
參考文章:http://www.tuicool.com/articles/63emAv
http://blog.csdn.net/haozipi/article/details/47183543?ref=myread
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498&fromuid=6 Bitmap 究竟佔多大內存
5.圖片上傳
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
new Runnable() {
public void run() {
int res = 0;
String BOUNDARY = UUID.randomUUID().toString(); // 邊界標識 隨機生成
String PREFIX = "--", LINE_END = "\r\n";
String CONTENT_TYPE = "multipart/form-data"; // 內容類型
try {
URL url = new URL(Content.SERVICE_URL + urlString);
L.i(TAG, "url:" + url);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setReadTimeout(Content.CONNECT_TIMEOUT);
conn.setConnectTimeout(Content.CONNECT_TIMEOUT);
conn.setDoInput(true); // 允許輸入流
conn.setDoOutput(true); // 允許輸出流
conn.setUseCaches(false); // 不允許使用緩存
conn.setRequestMethod("POST"); // 請求方式
conn.setRequestProperty("Charset", "UTF-8"); // 設置編碼
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE
+ ";boundary=" + BOUNDARY);
if (file != null) {
DataOutputStream dos = new DataOutputStream(
conn.getOutputStream());
StringBuffer sb = new StringBuffer();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""
+ file.getName() + "\"" + LINE_END);
sb.append("Content-Type: application/octet-stream; charset="
+ "UTF-8" + LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
InputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
dos.write(LINE_END.getBytes());
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)
.getBytes();
dos.write(end_data);
dos.flush();
res = conn.getResponseCode();
L.i(TAG, "response code:" + res);
if (res == 200) {
L.i(TAG, "request success");
InputStream input = conn.getInputStream();
StringBuffer sb1 = new StringBuffer();
int ss;
while ((ss = input.read()) != -1) {
sb1.append((char) ss);
}
result = sb1.toString();
L.i(TAG, "result : " + result);
Message msg = new Message();
msg.what = 1;
msg.obj = sb1.toString();
handler2.sendMessage(msg);
} else {
L.i(TAG, "request error");
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.run();
}
6.圖片下載
public class InternetTest {
// 讀取的方法
public byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; // 用數據裝
int len = -1;
while ((len = inStream.read(buffer)) != -1) {
outstream.write(buffer, 0, len);
}
outstream.close();
inStream.close();
// 關閉流一定要記得。
return outstream.toByteArray();
}
@Test
public void getImage() throws Exception {
//要下載的圖片的地址,
String urlPath = "http://t2.gstatic.com/images?q=tbn:9g03SOE7gW2gEM:http://dev.10086.cn/cmdn/supesite";
URL url = new URL(urlPath);//獲取到路徑
// http協議連接對象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");// 這裏是不能亂寫的,詳看API方法
conn.setConnectTimeout(6 * 1000);
// 別超過10秒。
System.out.println(conn.getResponseCode());
if (conn.getResponseCode() == 200) {
InputStream inputStream = conn.getInputStream();
byte[] data = readStream(inputStream);
File file = new File("smart.jpg");// 給圖片起名子
FileOutputStream outStream = new FileOutputStream(file);//寫出對象
outStream.write(data);// 寫入
outStream.close(); // 關閉流
}
}
}
7.圖片壓縮
第一:我們先看下質量壓縮方法:
private Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//質量壓縮方法,這裏100表示不壓縮,把壓縮後的數據存放到baos中
int options = 100;
while ( baos.toByteArray().length / 1024>100) { //循環判斷如果壓縮後圖片是否大於100kb,大於繼續壓縮
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//這裏壓縮options%,把壓縮後的數據存放到baos中
options -= 10;//每次都減少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把壓縮後的數據baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream數據生成圖片
return bitmap;
}
第二:圖片按比例大小壓縮方法(根據路徑獲取圖片並壓縮):
private Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此時返回bm爲空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//現在主流手機比較多是800*480分辨率,所以高和寬我們設置爲
float hh = 800f;//這裏設置高度爲800f
float ww = 480f;//這裏設置寬度爲480f
//縮放比。由於是固定比例縮放,只用高或者寬其中一個數據進行計算即可
int be = 1;//be=1表示不縮放
if (w > h && w > ww) {//如果寬度大的話根據寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的話根據寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//設置縮放比例
//重新讀入圖片,注意此時已經把options.inJustDecodeBounds 設回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//壓縮好比例大小後再進行質量壓縮
}
第三:圖片按比例大小壓縮方法(根據Bitmap圖片壓縮):
private Bitmap comp(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if( baos.toByteArray().length / 1024>1024) {//判斷如果圖片大於1M,進行壓縮避免在生成圖片(BitmapFactory.decodeStream)時溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//這裏壓縮50%,把壓縮後的數據存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//現在主流手機比較多是800*480分辨率,所以高和寬我們設置爲
float hh = 800f;//這裏設置高度爲800f
float ww = 480f;//這裏設置寬度爲480f
//縮放比。由於是固定比例縮放,只用高或者寬其中一個數據進行計算即可
int be = 1;//be=1表示不縮放
if (w > h && w > ww) {//如果寬度大的話根據寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的話根據寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//設置縮放比例
//重新讀入圖片,注意此時已經把options.inJustDecodeBounds 設回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//壓縮好比例大小後再進行質量壓縮
}
8.圖片分辨率減少方法,防止OOM
public Bitmap getBitmapFromFile(File dst, int width, int height) {
if (null != dst && dst.exists()) {
BitmapFactory.Options opts = null;
if (width > 0 && height > 0) {
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(dst.getPath(), opts);
// 計算圖片縮放比例
final int minSideLength = Math.min(width, height);
opts.inSampleSize = computeSampleSize(opts, minSideLength,
width * height);
opts.inJustDecodeBounds = false;
opts.inInputShareable = true;
opts.inPurgeable = true;
}
try {
return BitmapFactory.decodeFile(dst.getPath(), opts);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
}
return null;
}
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;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math
.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
9.打開相機照片和本機相冊選擇圖片
1、PopActivity
File file = new File(Content.CACHE_PATH + "/"+System.currentTimeMillis()+".png");
if(!file.exists())
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uri = Uri.fromFile(file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TAKE_PHOTO);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
switch (requestCode) {
case TAKE_PHOTO:
intent.setData(uri);
cropBitmap(uri);
break;
public void cropBitmap(Uri mUri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(mUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("outputFormat", "png");
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
switch (requestCode) {
case CROP_PICTURE:
if(mark==2){
if(data.getData()!=null){
intent.setData(data.getData());
}else{
intent.putExtras(data.getExtras());
}
}else{
intent.putExtras(data.getExtras());
}
setResult(RESULT_OK, intent);
finish();
break;
2、Activity
@Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
// TODO Auto-generated method stub
super.onActivityResult(arg0, arg1, arg2);
case TAKE_PHOTO:
if (arg2 != null) {
Bitmap one = null;
Uri photoUri = arg2.getData();
L.i(TAG, "photoUri#" + arg2);
if (photoUri.toString().contains("content://media")) {
Cursor cursor = getContentResolver().query(photoUri, null,
null, null, null);
cursor.moveToFirst();
String picturePath = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
one = Util.getDiskBitmap(picturePath);
cursor.close();
iv3.setImageBitmap(one);
String picPath = Util.saveBitmap(
"" + System.currentTimeMillis(), Util.comp(one));
String semd = Util.bitmaptoString(one);
L.i(TAG, "p#" + picPath);
new ImageUpLoader("postImg/picture?uid=" + uid, picPath,
handler2).start();
} else {
Bundle extra = arg2.getExtras();
if (extra != null) {
one = (Bitmap)extra.get("data");
}
iv3.setImageBitmap(ImageToRound.toRoundBitmap(one));
String picPath = Util.saveBitmap(
"" + System.currentTimeMillis(), Util.comp(one));
L.i(TAG, "p:"+picPath);
new ImageUpLoader("postImg/picture?uid=" + uid, picPath,
handler2).start();
}
}
break;
12.Android-Universal-Image-Loader 圖片異步加載類庫的使用
http://blog.csdn.net/vipzjyno1/article/details/23206387
1、
private ImageLoader imageLoader;
private DisplayImageOptions options;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
options = new DisplayImageOptions.Builder()
.showStubImage(Content.NO_PHOTO)
.showImageForEmptyUri(Content.NO_PHOTO)
.showImageOnFail(Content.NO_PHOTO).cacheInMemory(true)
.cacheOnDisc(true).bitmapConfig(Bitmap.Config.ARGB_8888)
.build();
imageLoader.displayImage(url2, vh.touImageView, options);
2、
public static void initImageLoader(Context context) {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
context).threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.discCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.writeDebugLogs().build();
ImageLoader.getInstance().init(config);
}
3、Configuration所有配置簡介
.memoryCacheExtraOptions(480, 800) //即保存的每個緩存文件的最大長寬
.threadPriority(Thread.NORM_PRIORITY - 2) //設置圖片加載線程的優先級,默認爲Thread.NORM_PRIORITY-1 線程池中線程的個數 注:如果設置了taskExecutor或者taskExecutorForCachedImages 此設置無效
.threadPoolSize(3) // 設置顯示圖片線程池大小,默認爲3 注:如果設置了taskExecutor或者taskExecutorForCachedImages 此設置無效
.denyCacheImageMultipleSizesInMemory() // 設置拒絕緩存在內存中一個圖片多個大小 默認爲允許,(同一個圖片URL)根據不同大小的imageview保存不同大小圖片
.memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //緩存策略
.memoryCacheSize(50 * 1024 * 1024) //設置內存緩存的大小
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) // 設置硬盤緩存文件名生成規範 默認爲new HashCodeFileNameGenerator()
.diskCacheSize(200 * 1024 * 1024) //磁盤緩存大小
.tasksProcessingOrder(QueueProcessingType.LIFO) //工作隊列 設置圖片加載和顯示隊列處理的類型 默認爲QueueProcessingType.FIFO 注:如果設置了taskExecutor或者taskExecutorForCachedImages 此設置無效
.diskCacheFileCount(200) //緩存的文件數量
.diskCache(new UnlimitedDiskCache(cacheDir)) //自定義緩存路徑
.taskExecutor(DefaultConfigurationFactory.createExecutor(3,Thread.NORM_PRIORITY - 1, QueueProcessingType.FIFO)) // 設置自定義加載和顯示圖片的線程池
.taskExecutorForCachedImages(DefaultConfigurationFactory.createExecutor(3,Thread.NORM_PRIORITY - 1, QueueProcessingType.FIFO)) // 設置自定義加載和顯示內存緩存或者硬盤緩存圖片的線程池
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)) // 設置內存緩存 默認爲一個當前應用可用內存的1/8大小的LruMemoryCache
.memoryCacheSize(2 * 1024 * 1024) // 設置內存緩存的最大大小 默認爲一個當前應用可用內存的1/8
.memoryCacheSizePercentage(13) // 設置內存緩存最大大小佔當前應用可用內存的百分比 默認爲一個當前應用可用內存的1/8
.discCache(new UnlimitedDiscCache(StorageUtils.getCacheDirectory(getApplicationContext()))) // 設置硬盤緩存默認爲StorageUtils.getCacheDirectory(getApplicationContext())即/mnt/sdcard/android/data/包名/cache/
.discCacheSize(50 * 1024 * 1024) // 設置硬盤緩存的最大大小
.discCacheFileCount(100) // 設置硬盤緩存的文件的最多個數
.imageDownloader(new HttpClientImageDownloader(getApplicationContext(),new DefaultHttpClient())) // 設置圖片下載器 默認爲 DefaultConfigurationFactory.createBitmapDisplayer()
.imageDecoder(DefaultConfigurationFactory.createImageDecoder(false)) // 設置圖片解碼器 ,默認爲DefaultConfigurationFactory.createImageDecoder(false)
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // 設置默認的圖片顯示選項 ,默認爲DisplayImageOptions.createSimple()
.writeDebugLogs() // 打印DebugLogs
.build(); // 建立
4、DisplayImageOptions所有配置簡介
.showImageOnLoading(R.drawable.ic_chat_def_pic) // 設置圖片加載時的默認圖片
.showImageOnFail(R.drawable.ic_chat_def_pic_failure) // 設置圖片加載失敗的默認圖片
.showImageForEmptyUri(R.drawable.ic_chat_def_pic) // 設置圖片URI爲空時默認圖片
.resetViewBeforeLoading(false) // 設置是否將View在加載前復位
.delayBeforeLoading(100) // 設置延遲部分時間纔開始加載 默認爲0
.cacheInMemory(true) // 設置添加到內存緩存 默認爲false
.cacheOnDisc(true) // 設置添加到硬盤緩存 默認爲false
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // 設置規模類型的解碼圖像 默認爲ImageScaleType.IN_SAMPLE_POWER_OF_2
.bitmapConfig(Bitmap.Config.ARGB_8888) // 設置位圖圖像解碼配置 默認爲Bitmap.Config.ARGB_8888
.decodingOptions(new Options()) // 設置選項的圖像解碼
.displayer(new FadeInBitmapDisplayer(300)) // 設置自定義顯示器 默認爲DefaultConfigurationFactory.createBitmapDisplayer()
.handler(new Handler()) // 設置自定義的handler 默認爲new Handler()
.build(); // 建立
13、基於LruCache的圖片緩存
http://blog.csdn.net/u013064109/article/details/51756551
14、openCV4android
http://blog.csdn.net/hbl_for_android/article/details/51941106 openCV4android常用變換(一)
http://blog.csdn.net/hbl_for_android/article/details/51989105 opencv4android常用變換(二)