版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Bitmap在Android項(xiàng)目中的作用是什么
這期內(nèi)容當(dāng)中在下將會(huì)給大家?guī)碛嘘P(guān)Bitmap在Android項(xiàng)目中的作用是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。Bitmap簡介位圖文件(Bitmap),擴(kuò)展名可以是.bmp或者.dib。位圖是Windows標(biāo)準(zhǔn)格式圖形文件,它將圖像定義為由點(diǎn)(像素)組成,每個(gè)點(diǎn)可以由多種色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位真彩圖片,其所占存儲(chǔ)字節(jié)數(shù)為:1024×768×32/(8*1024)=3072KB位圖文件圖像效果好,但是非壓縮格式的,需要占用較大存儲(chǔ)空間,不利于在網(wǎng)絡(luò)上傳送。jpg/png格式則恰好彌補(bǔ)了位圖文件的缺點(diǎn)。在Android中計(jì)算bitmap的大?。篵itmap.getByteCount()(返回byte)掃盲:1M=1024KB=1024*1024byte一般1920X1080尺寸的圖片在內(nèi)存中的大小,1920x1080x4=2025kb=1.977539M乘以4位的原因是在安卓系統(tǒng)中bitmap圖片一般是以ARGB_8888(ARGB分別代表的是透明度,紅色,綠色,藍(lán)色,每個(gè)值分別用8bit來記錄,也就是一個(gè)像素會(huì)占用4byte,共32bit。)來進(jìn)行存儲(chǔ)的。Android中圖片有四種顏色格式ARGB_8888占位算法:8+8+8+8=321bit
0/1;最小單位1byte=8bit
10101010
(0-255)00000000
11111111說明:ARGB_8888:ARGB分別代表的是透明度,紅色,綠色,藍(lán)色,每個(gè)值分別用8bit來記錄,也就是一個(gè)像素會(huì)占用4byte,共32bit.ARGB_4444:ARGB的是每個(gè)值分別用4bit來記錄,一個(gè)像素會(huì)占用2byte,共16bit.RGB_565:R=5bit,G=6bit,B=5bit,不存在透明度,每個(gè)像素會(huì)占用2byte,共16bit.ALPHA_8:該像素只保存透明度,會(huì)占用1byte,共8bit.在實(shí)際應(yīng)用中而言,建議使用ARGB_8888以及RGB_565。如果你不需要透明度,那么就選擇RGB_565,可以減少一半的內(nèi)存占用.Bitmap的回收在安卓3.0以前Bitmap是存放在堆中的,我們只要回收堆內(nèi)存即可在安卓3.0以后Bitmap是存放在內(nèi)存中的,我們需要回收native層和Java層的內(nèi)存官方建議我們3.0以后使用recycle方法進(jìn)行回收,該方法也可以不主動(dòng)調(diào)用,因?yàn)槔厥掌鲿?huì)自動(dòng)收集不可用的Bitmap對(duì)象進(jìn)行回收recycle方法會(huì)判斷Bitmap在不可用的情況下,將發(fā)送指令到垃圾回收器,讓其回收native層和Java層的內(nèi)存,則Bitmap進(jìn)入dead狀態(tài)recycle方法是不可逆的,如果再次調(diào)用getPixels()等方法,則獲取不到想要的結(jié)果LruCache原理LruCache是個(gè)泛型類,內(nèi)部采用LinkedHashMap來實(shí)現(xiàn)緩存機(jī)制,它提供get方法和put方法來獲取緩存和添加緩存,其最重要的方法trimToSize是用來移除最少使用的緩存和使用最久的緩存,并添加最新的緩存到隊(duì)列中計(jì)算inSampleSize
public
static
int
calculateInSampleSize(BitmapFactory.Options
options,
int
reqWidth,
int
reqHeight)
{
final
int
width
=
options.outWidth;
final
int
height
=
options.outHeight;
int
inSampleSize
=
1;
if
(width
>
reqWidth
||
height
>
reqHeight)
{
if
(width
>
height)
{
inSampleSize
=
Math.round((float)
height
/
(float)
reqHeight);
}
else
{
inSampleSize
=
Math.round((float)
width
/
(float)
reqWidth);
}
}
return
inSampleSize;
}縮略圖
public
static
Bitmap
thumbnail(String
path,
int
maxWidth,
int
maxHeight,boolean
autoRotate)
{
BitmapFactory.Options
options
=
new
BitmapFactory.Options();
options.inJustDecodeBounds
=
true;
Bitmap
bitmap
=
BitmapFactory.decodeFile(path);
options.inJustDecodeBounds
=
false;
int
sampleSize
=
calculateInSampleSize(options,maxWidth,maxHeight);
options.inSampleSize
=sampleSize;
options.inPreferredConfig
=
Bitmap.Config.RGB_565;
options.inPurgeable
=true;
options.inInputShareable
=
true;
if(bitmap
!=null&&!bitmap.isRecycled()){
bitmap.recycle();
}
bitmap
=
BitmapFactory.decodeFile(path,options);
return
bitmap;
}保存Bitmappublic
static
String
save(Bitmap
bitmap,
Bitmap.CompressFormat
format,
int
quality,File
desFile)
{
try{
FileOutputStream
out
=
new
FileOutputStream(desFile);
if(press(format,quality,out)){
out.flush();
out.close();
}
if(bitmap!=null&&!bitmap.isRecycled()){
bitmap.recycle();
}
return
desFile.getAbsolutePath();
}catch
(FileNotFoundException
e){
e.printStackTrace();
}
catch
(IOException
e)
{
e.printStackTrace();
}
return
null;
}保存到SD卡public
static
String
save(Bitmap
bitmap,
Bitmap.CompressFormat
format,
int
quality,Context
context)
{
if(!Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED)){
return
null;
}
File
dir
=
new
File(Environment.getExternalStorageDirectory()+
"/"+context.getPackageName());
if(!dir.exists()){
dir.mkdir();
}
File
desFile
=
new
File(dir,
UUID.randomUUID().toString());
return
save(bitmap,format,quality,desFile);
}壓縮一、質(zhì)量壓縮質(zhì)量壓縮方法:在保持像素的前提下改變圖片的位深及透明度等,來達(dá)到壓縮圖片的目的:1、bitmap圖片的大小不會(huì)改變2、bytes.length是隨著quality變小而變小的。這樣適合去傳遞二進(jìn)制的圖片數(shù)據(jù),比如分享圖片,要傳入二進(jìn)制數(shù)據(jù)過去,限制500kb之內(nèi)。public
static
Bitmap
compressImage(Bitmap
image)
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream();
//
把ByteArrayInputStream數(shù)據(jù)生成圖片
Bitmap
bitmap
=
null;
press(Bitmap.CompressFormat.JPEG,
5,
baos);
byte[]
bytes
=
baos.toByteArray();
//
把壓縮后的數(shù)據(jù)baos存放到bytes中
bitmap
=
BitmapFactory.decodeByteArray(bytes,
0,
bytes.length);
if
(bitmap
!=
null)
{
loga(bitmap,
baos.toByteArray());
}
return
bitmap;
}
//
質(zhì)量壓縮方法,options的值是0-100,這里100表示原來圖片的質(zhì)量,不壓縮,把壓縮后的數(shù)據(jù)存放到baos中
press(Bitmap.CompressFormat.JPEG,
100,
baos);
int
options
=
90;
//
循環(huán)判斷如果壓縮后圖片是否大于500kb,大于繼續(xù)壓縮
while
(baos.toByteArray().length
/
1024
>
100)
{
//
重置baos即清空baos
baos.reset();
//
這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中
press(Bitmap.CompressFormat.JPEG,
options,
baos);
//
每次都減少10
if(options
==
1){
break;
}else
if
(options
<=
10)
{
options
-=
1;
}
else
{
options
-=
10;
}
}二、采樣率壓縮設(shè)置inSampleSize的值(int類型)后,假如設(shè)為n,則寬和高都為原來的1/n,寬高都減少,內(nèi)存降低。上面的代碼沒用過options.inJustDecodeBounds=true;因?yàn)槲沂枪潭▉砣拥臄?shù)據(jù),為什么這個(gè)壓縮方法叫采樣率壓縮?是因?yàn)榕浜蟟nJustDecodeBounds,先獲取圖片的寬、高(這個(gè)過程就是取樣)。然后通過獲取的寬高,動(dòng)態(tài)的設(shè)置inSampleSize的值。當(dāng)inJustDecodeBounds設(shè)置為true的時(shí)候,BitmapFactory通過decodeResource或者decodeFile解碼圖片時(shí),將會(huì)返回空(null)的Bitmap對(duì)象,這樣可以避免Bitmap的內(nèi)存分配,但是它可以返回Bitmap的寬度、高度以及MimeType。用法int
inSampleSize
=
getScaling(bitmap);
bitmap
=
samplingRateCompression(path,inSampleSize);
private
Bitmap
samplingRateCompression(String
path,
int
scaling)
{
BitmapFactory.Options
options
=
new
BitmapFactory.Options();
options.inSampleSize
=
scaling;
Bitmap
bitmap
=
BitmapFactory.decodeFile(path,
options);
int
size
=
(bitmap.getByteCount()
/
1024
/
1024);
Log.i("wechat",
"壓縮后圖片的大小"
+
(bitmap.getByteCount()
/
1024
/
1024)
+
"M寬度為"
+
bitmap.getWidth()
+
"高度為"
+
bitmap.getHeight());
return
bitmap;
}
/**
*
獲取縮放比例
*
@param
bitmap
*
@return
*/
private
int
getScaling(Bitmap
bitmap)
{
//設(shè)置目標(biāo)尺寸(以像素的寬度為標(biāo)準(zhǔn))
int
Targetsize
=
1500;
int
width
=
bitmap.getWidth();
int
height
=
bitmap.getHeight();
//選擇最大值作為比較值(保證圖片的壓縮大?。?/p>
int
handleValue
=
width
>
height
?
width
:
height;
//循環(huán)計(jì)算壓縮比
int
i
=
1;
while
(handleValue
/
i
>
Targetsize)
{
i++;
}
}三、縮放法壓縮,效果和方法2一樣Android中使用Matrix對(duì)圖像進(jìn)行縮放、旋轉(zhuǎn)、平移、斜切等變換的。Matrix是一個(gè)3*3的矩陣,其值對(duì)應(yīng)如下:|scaleX,
skewX,
translateX||skewY,
scaleY,
translateY||0
,
0,
scale|Matrix提供了一些方法來控制圖片變換:setTranslate(floatdx,floatdy):控制Matrix進(jìn)行位移。setSkew(floatkx,floatky):控制Matrix進(jìn)行傾斜,kx、ky為X、Y方向上的比例。setSkew(floatkx,floatky,floatpx,floatpy):控制Matrix以px、py為軸心進(jìn)行傾斜,kx、ky為X、Y方向上的傾斜比例。setRotate(floatdegrees):控制Matrix進(jìn)行depress角度的旋轉(zhuǎn),軸心為(0,0)。setRotate(floatdegrees,floatpx,floatpy):控制Matrix進(jìn)行depress角度的旋轉(zhuǎn),軸心為(px,py)。setScale(floatsx,floatsy):設(shè)置Matrix進(jìn)行縮放,sx、sy為X、Y方向上的縮放比例。setScale(floatsx,floatsy,floatpx,floatpy):設(shè)置Matrix以(px,py)為軸心進(jìn)行縮放,sx、sy為X、Y方向上的縮放比例。注意:以上的set方法,均有對(duì)應(yīng)的post和pre方法,Matrix調(diào)用一系列set,pre,post方法時(shí),可視為將這些方法插入到一個(gè)隊(duì)列.當(dāng)然,按照隊(duì)列中從頭至尾的順序調(diào)用執(zhí)行.其中pre表示在隊(duì)頭插入一個(gè)方法,post表示在隊(duì)尾插入一個(gè)方法.而set表示把當(dāng)前隊(duì)列清空,并且總是位于隊(duì)列的最中間位置.當(dāng)執(zhí)行了一次set后:pre方法總是插入到set前部的隊(duì)列的最前面,post方法總是插入到set后部的隊(duì)列的最后面private
Bitmap
ScalingCompression(Bitmap
bitmap)
{
Matrix
matrix
=
new
Matrix();
matrix.setScale(0.25f,
0.25f);//縮放效果類似于方法2
Bitmap
bm
=
Bitmap.createBitmap(bitmap,
0,
0,
bitmap.getWidth(),
bitmap.getHeight(),
matrix,
true);
Log.i("wechat",
"壓縮后圖片的大小"
+
(bm.getByteCount()
/
1024
/
1024)
+
"M寬度為"
+
bm.getWidth()
+
"高度為"
+
bm.getHeight());
return
bm;
}四、Bitmap.Config原圖尺寸:4M轉(zhuǎn)化為FileBitmap大小ALPHA_86.77M45MARGB_44449.37M22MARGB_88886.77M45MRGB_5658.13M22M一般情況下默認(rèn)使用的是ARGB8888,由此可知它是最占內(nèi)存的,因?yàn)橐粋€(gè)像素占32位,8位=1字節(jié),所以一個(gè)像素占4字節(jié)的內(nèi)存。假設(shè)有一張480x800的圖片,如果格式為ARGB8888,那么將會(huì)占用1500KB的內(nèi)存。private
Bitmap
bitmapConfig(String
path)
{
BitmapFactory.Options
options
=
new
BitmapFactory.Options();
options.inPreferredConfig
=
Bitmap.Config.RGB_565;
Bitmap
bm
=
BitmapFactory.decodeFile(path,
options);
Log.i("wechat",
"壓縮后圖片的大小"
+
(bm.getByteCount()
/
1024f
/
1024f)
+
"M寬度為"
+
bm.getWidth()
+
"高度為"
+
bm.getHeight());
return
bm;
}五、Bitmap提供的:createScaledBitmap方法Bitmap.createScaledBitmap(src,
dstWidth,
dstHeight,
filter);參數(shù)說明:src
用來構(gòu)建子集的源位圖dstWidth
新位圖期望的寬度dstHeight
新位圖期望的高度filter
為true則選擇抗鋸齒補(bǔ)充抗鋸齒的知識(shí)點(diǎn)在Android中,目前,我知道有兩種出現(xiàn)鋸齒的情況。1、當(dāng)我們用Canvas繪制位圖的時(shí)候,如果對(duì)位圖進(jìn)行了選擇,則位圖會(huì)出現(xiàn)鋸齒。2、在用View的RotateAnimation做動(dòng)畫時(shí)候,如果View當(dāng)中包含有大量的圖形,也會(huì)出現(xiàn)鋸齒。我們分別以這兩種情況加以考慮。用Canvas繪制位圖的的情況。在用Canvas繪制位圖時(shí),一般地,我們使用drawBitmap函數(shù)家族,在這些函數(shù)中,都有一個(gè)Paint參數(shù),要做到防止鋸齒,我們就要使用到這個(gè)參數(shù)。如下:首先在你的構(gòu)造函數(shù)中,需要?jiǎng)?chuàng)建一個(gè)Paint。PaintmPaint=newPaint();然后,您需要設(shè)置兩個(gè)參數(shù):1)mPaint.setAntiAlias(Booleanaa);2)mPaint.setBitmapFilter(true)。第一個(gè)函數(shù)是用來防止邊緣的鋸齒,(true時(shí)圖像邊緣相對(duì)清晰一點(diǎn),鋸齒痕跡不那么明顯,false時(shí),寫上去的字不飽滿,不美觀,看地不太清楚)。第二個(gè)函數(shù)是用來對(duì)位圖進(jìn)行濾波處理。最后,在畫圖的時(shí)候,調(diào)用drawBitmap函數(shù),只需要將整個(gè)Paint傳入即可。有時(shí)候,當(dāng)你做RotateAnimation時(shí),你會(huì)發(fā)現(xiàn),討厭的鋸齒又出現(xiàn)了。這個(gè)時(shí)候,由于你不能控制位圖的繪制,只能用其他方法來實(shí)現(xiàn)防止鋸齒。另外,如果你畫的位圖很多。不想每個(gè)位圖的繪制都傳入一個(gè)Paint。還有的時(shí)候,你不可能控制每個(gè)窗口的繪制的時(shí)候,您就需要用下面的方法來處理——對(duì)整個(gè)Canvas進(jìn)行處理。1)在您的構(gòu)造函數(shù)中,創(chuàng)建一個(gè)Paint濾波器。PaintFlagsDrawFiltermSetfil=newPaintFlagsDrawFilter(0,Paint.FILTERBITMAPFLAG);第一個(gè)參數(shù)是你要清除的標(biāo)志位,第二個(gè)參數(shù)是你要設(shè)置的標(biāo)志位。此處設(shè)置為對(duì)位圖進(jìn)行濾波。2)當(dāng)你在畫圖的時(shí)候,如果是View則在onDraw當(dāng)中,如果是ViewGroup則在dispatchDraw中調(diào)用如下函數(shù)。canvas.setDrawFilter(mSetfil);另外,在Drawable類及其子類中,也有函數(shù)setFilterBitmap可以用來對(duì)Bitmap進(jìn)行濾波處理,這樣,當(dāng)你選擇Drawable時(shí),會(huì)有抗鋸齒的效果。private
Bitmap
createScaledBitmap(Bitmap
bitmap)
{
Bitmap
bm
=
Bitmap.createScaledBitmap(bitmap,
200,
200,
true);
Log.i("wechat",
"壓縮后圖片的大小"
+
(bm.getByteCount()
/
1024)
+
"KB寬度為"
+
bm.getWidth()
+
"高度為"
+
bm.getHeight());
return
bm;
}六、輔助方法(上述方法的):通過路徑獲取bitmap的方法1、利用BitmapFactory解析文件,轉(zhuǎn)換為Bitmapbitmap
=
BitmapFactory.decodeFile(path);2、自己寫解碼,轉(zhuǎn)換為Bitmap過程,同樣需使用BitmapFactory.decodeByteArray(buf,0,len);代碼如下:private
Bitmap
getBitmapByPath(String
path)
{
if
(!new
File(path).exists())
{
System.err.println("getBitmapByPath:
文件不存在");
return
null;
}
byte[]
buf
=
new
byte[1024
*
1024];//
1M
Bitmap
bitmap
=
null;
try
{
FileInputStream
fis
=
new
FileInputStream(path);
int
len
=
fis.read(buf,
0,
buf.length);
bitmap
=
BitmapFactory.decodeByteArray(buf,
0,
len);
//當(dāng)bitmap為空的時(shí)候,說明解析失敗
if
(bitmap
==
null)
{
System.out.println("文件長度:"
+
len);
System.err.println("path:
"
+
path
+
"
無法解析!!!");
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
return
bitmap;
}保存圖片private
void
savaPictrue(Bitmap
bitmap)
{
File
file
=
new
File("storage/emulated/0/DCIM/Camera/test.jpg");
FileOutputStream
stream
=
null;
try
{
stream
=
new
FileOutputStream(file);
press(Bitmap.CompressFormat.JPEG,
100,
stream);
Log.e("圖片大?。?,
fi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 合伙協(xié)議書和合伙合同
- 2025年粵人版九年級(jí)歷史上冊(cè)月考試卷
- 2025年外研銜接版七年級(jí)物理下冊(cè)月考試卷含答案
- 2025年粵教滬科版九年級(jí)歷史下冊(cè)階段測試試卷含答案
- 2025年牛津上海版選擇性必修3生物上冊(cè)階段測試試卷含答案
- 2025年滬科版七年級(jí)生物上冊(cè)階段測試試卷
- 2025年粵教新版選修四地理下冊(cè)月考試卷
- 2025年滬教版選修歷史下冊(cè)月考試卷
- 2025年滬教新版八年級(jí)歷史下冊(cè)月考試卷含答案
- 二零二五版苗圃場技術(shù)員園藝研發(fā)聘用合同書4篇
- SYT 6968-2021 油氣輸送管道工程水平定向鉆穿越設(shè)計(jì)規(guī)范-PDF解密
- 冷庫制冷負(fù)荷計(jì)算表
- 肩袖損傷護(hù)理查房
- 設(shè)備運(yùn)維管理安全規(guī)范標(biāo)準(zhǔn)
- 辦文辦會(huì)辦事實(shí)務(wù)課件
- 大學(xué)宿舍人際關(guān)系
- 2023光明小升初(語文)試卷
- GB/T 14600-2009電子工業(yè)用氣體氧化亞氮
- 申請(qǐng)使用物業(yè)專項(xiàng)維修資金征求業(yè)主意見表
- 房屋買賣合同簡單范本 房屋買賣合同簡易范本
- 無抽搐電休克治療規(guī)范
評(píng)論
0/150
提交評(píng)論