一、相關概念
1、Drawable就是一個可畫的對象,其可能是一張位圖(BitmapDrawable),也可能是一個圖形(ShapeDrawable),還有可能是一個圖層(LayerDrawable),我們根據畫圖的需求,創建相應的可畫對象
2、Canvas畫布,繪圖的目的區域,用於繪圖
3、Bitmap位圖,用於圖的處理
4、Matrix矩陣
5、paint畫筆
獲取Bitmap的方法:
一、 使用BitmapFactory解析圖片
// --> 使用BitmapFactory解析圖片
public void myUseBitmapFactory(Canvas canvas){
// 定義畫筆
Paint paint = new Paint();
// 獲取資源流
Resources rec = getResources();
InputStream in = rec.openRawResource(R.drawable.haha);
// 設置圖片
Bitmap bitmap =BitmapFactory.decodeStream(in);
// 繪製圖片
canvas.drawBitmap(bitmap, 0,20, paint);
}
二、 使用BitmapDrawable解析圖片
// --> 使用BitmapDrawable解析圖片
public void myUseBitmapDrawable(Canvas canvas){
// 定義畫筆
Paint paint = new Paint();
// 獲得資源
Resources rec = getResources();
// BitmapDrawable
BitmapDrawable bitmapDrawable = (BitmapDrawable) rec.getDrawable(R.drawable.haha);
// 得到Bitmap
Bitmap bitmap = bitmapDrawable.getBitmap();
// 在畫板上繪製圖片
canvas.drawBitmap(bitmap, 20,120,paint);
}
三、 使用InputStream和BitmapDrawable繪製
// --> 使用InputStream和BitmapDrawable解析圖片
public void myUseInputStreamandBitmapDrawable(Canvas canvas){
// 定義畫筆
Paint paint = new Paint();
// 獲得資源
Resources rec = getResources();
// InputStream得到資源流
InputStream in = rec.openRawResource(R.drawable.haha);
// BitmapDrawable 解析數據流
BitmapDrawable bitmapDrawable = new BitmapDrawable(in);
// 得到圖片
Bitmap bitmap = bitmapDrawable.getBitmap();
// 繪製圖片
canvas.drawBitmap(bitmap, 100, 100,paint);
}
-----------------------------------------
bitMap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.image);
SD卡中的圖片
Bitmap bmp = BitmapFactory.decodeFile("/sdcard/testBitmap/testImg.png")
把bitmap保存在SD卡中
File fImage = new File("/sdcard/testBitmap/testImg.png");
fImage.createNewFile();
FileOutputStream iStream = new FileOutputStream(fImage);
bmp.compress(CompressFormat.PNG, 100, iStream);
iStream.close();
fImage.close();
iStream =null;
fImage =null;
//寫到輸出流裏,就保存到文件了。
使用網絡中的圖片
//圖片的鏈接地址
String imgURLStr = "http://tx.bdimg.com/sys/portrait/item/990e6271796a7a6c170c.jpg";
URL imgURL = new URL(imgURLStr);
URLConnection conn = imgURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
//下載圖片
Bitmap bmp = BitmapFactory.decodeStream(bis);
//關閉Stream
bis.close();
is.close();
imgURL =null;
1)轉換爲BitmapDrawable對象顯示位圖
// 轉換爲BitmapDrawable對象
BitmapDrawable bmpDraw=new BitmapDrawable(bmp);
// 顯示位圖
ImageView iv2 = (ImageView)findViewById(R.id.ImageView02);
iv2.setImageDrawable(bmpDraw);
2)使用Canvas類顯示位圖
canvas.drawBitmap(bmp, 0, 0, null);
縮放位圖
1)將一個位圖按照需求重畫一遍,畫後的位圖就是我們需要的了,與位圖的顯示幾乎一樣:drawBitmap(Bitmap bitmap, Rect src, Rect
dst, Paint paint)。
2)在原有位圖的基礎上,縮放原位圖,創建一個新的位圖:CreateBitmap(Bitmap source, int x, int y, int width, int height,
Matrix m, boolean filter)
3)藉助Canvas的scale(float sx, float sy) ,不過要注意此時整個畫布都縮放了。
4)藉助Matrix:
Matrix matrix=new Matrix();
matrix.postScale(0.2f, 0.2f);
Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);
canvas.drawBitmap(dstbmp, 10, 10, null);
旋轉位圖
藉助Matrix或者Canvas來實現。
Matrix matrix=new Matrix();
matrix.postRotate(45);
Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(), bmp.getHeight(),matrix,true);
canvas.drawBitmap(dstbmp, 10, 10, null);
//釋放bitmap資源,如在分頁加載bitmap時候,如果加載下一頁要先清理緩存中的上一頁內容 就會用
if (!dstbmp.isRecycled()) {
dstbmp.recycle();
}
如:
for(int i = 0; i < list.size(); i++){
Bitmap bitmap = loadImageFromUrl(list.get(i));
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(bitmap);
mImages[i] = imageView;
}
這裏對於Bitmap就沒有很好回收和利用,就有可能出現out of memory問題,因爲是循環,所以Bitmap就可以放到外部,讓程序重複利用,而不需要每次都創建一個新的Bitmap對象,
而且如果在內部作好資源回收利用的話,那就不用擔心內存溢出了。
Bitmap bitmap = null
for(int i = 0; i < list.size(); i++){
bitmap = loadImageFromUrl(list.get(i));
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(bitmap);
mImages[i] = imageView;
if(!bitmap.isRecycled() && bitmap != null){
bitmap.recycle();
bitmap = null;
}
}
bitmap與byte轉換
Bitmap-->byte[]:
public static byte[] Bitmap2Bytes(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
byte[]-->Bitmap:
public static Bitmap Bytes2Bimap(byte[] b) {
if (b.length == 0) {
return null;
}
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
Drawable轉爲bitmap
public static Bitmap drawableToBitmap(Drawable drawable) {
try {
Bitmap bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
// canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
Drawable d=xxx; //xxx根據自己的情況獲取drawableBitmapDrawable bd = (BitmapDrawable) d;
Bitmap bm = bd.getBitmap();
bitmap 轉爲 Drawable
因爲BtimapDrawable是Drawable的子類,最終直接使用bd對象即可
Bitmap bm=xxx; //xxx根據你的情況獲取
BitmapDrawable bd=BitmapDrawable(bm);
帶倒影的圖片
public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
final int reflectionGap = 4;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w,
h / 2, matrix, false);
Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2),
Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapWithReflection);
canvas.drawBitmap(bitmap, 0, 0, null);
Paint deafalutPaint = new Paint();
canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint);
canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
0x00ffffff, TileMode.CLAMP);
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, h, w, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
獲得圓角的圖片:
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Paint類常用方法:
void setARGB(int a, int r, int g, int b) 設置Paint對象顏色,參數一爲alpha透明通道
void setAlpha(int a) 設置alpha不透明度,範圍爲0~255
void setAntiAlias(boolean aa) //是否抗鋸齒
void setColor(int color) //設置顏色,這裏Android內部定義的有Color類包含了一些常見顏色定義
void setFakeBoldText(boolean fakeBoldText) //設置僞粗體文本
void setLinearText(boolean linearText) //設置線性文本
PathEffect setPathEffect(PathEffect effect) //設置路徑效果
Rasterizer setRasterizer(Rasterizer rasterizer) //設置光柵化
mShader = new LinearGradient(0, 0, 100, 70, new int[] {
Color.RED, Color.GREEN, Color.BLUE },
null, Shader.TileMode.MIRROR);
Shader setShader(Shader shader) //設置陰影 void setTextAlign(Paint.Align align) //設置文本對齊
void setTextScaleX(float scaleX) //設置文本縮放倍數,1.0f爲原始
void setTextSize(float textSize) //設置字體大小
Typeface setTypeface(Typeface typeface) //設置字體,Typeface包含了字體的類型,粗細,還有傾斜、顏色等。
void setUnderlineText(boolean underlineText) //設置下劃線