Android實現(xiàn)圖片壓縮示例代碼
核心思想是通過BitmapFactory.Options來縮放圖片,主要是用到了它的inSampleSize參數(shù)(采樣率)
當inSampleSize為1的時候,采樣后的圖片大小為圖片的原始大??;
當inSampleSize為2的時候,采樣后的圖片的寬和高是原來的1/2,也就是說,它的像素點是原來的1/4,占的內存自然就是原來的1/4了。以此類推。
當inSampleSize小于1的時候,效果和等于1的時候是一樣的。
壓縮流程如下:
1.BitmapFactory.Options 的inJustDecodeBounds參數(shù)設置為true(這個時候BitmapFactory只是解析圖片的原始寬高,并不會去加載圖片)。
2.從BitmapFactory.Options 中取出圖片的原始寬高,outWidth,outHeight。
3.根據自己的需要設置合適的采樣率。
4.BitmapFactory.Options 的inJustDecodeBounds參數(shù)設置為false,然后就可以加載圖片了。
下面我們看代碼:
public Bitmap decodeSampledBitmapFromBytes(byte[] bytes,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
}
public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
if(reqWidth == 0 || reqHeight == 0){
return 1;
}
final int width = options.outWidth;
final int height = options.outHeight;
int inSampleSize = 1;
if( width > reqWidth || height > reqHeight){
final int halfWidth = width / 2;
final int halfHeight = height / 2;
while ((halfWidth / inSampleSize) >= reqWidth && (halfHeight / inSampleSize) >= reqHeight){
inSampleSize *=2;
}
}
return inSampleSize;
}
如此一來,就完成了一張圖片的壓縮。另外,BitmapFactory還有其它的decode方法,我們也可以仿照上面的來寫。
public Bitmap decodeSampledBitmapFromResource(Resources res,int resId,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res,resId,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res,resId,options);
}
public Bitmap decodeSampledBitmapFromDescrptor(FileDescriptor fd,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd,null,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(fd,null,options);
}
接下來結合一個小demo來實現(xiàn)一個完整的流程
先把圖片壓縮類封裝起來
public class ImageResizer {
private static final String TAG = "ImageResizer";
public ImageResizer(){}
public Bitmap decodeSampledBitmapFromResource(Resources res,int resId,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res,resId,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res,resId,options);
}
public Bitmap decodeSampledBitmapFromBytes(byte[] bytes,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap a = BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
Log.d(TAG, "before bitmap : " + a.getRowBytes() * a.getHeight());
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
Log.d(TAG, "after bitmap : " + b.getRowBytes() * b.getHeight());
return b;
}
public Bitmap decodeSampledBitmapFromDescrptor(FileDescriptor fd,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd,null,options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(fd,null,options);
}
public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
if(reqWidth == 0 || reqHeight == 0){
return 1;
}
final int width = options.outWidth;
final int height = options.outHeight;
int inSampleSize = 1;
if( width > reqWidth || height > reqHeight){
final int halfWidth = width / 2;
final int halfHeight = height / 2;
while ((halfWidth / inSampleSize) >= reqWidth && (halfHeight / inSampleSize) >= reqHeight){
inSampleSize *=2;
}
}
return inSampleSize;
}
}
然后就可以拿來用了:
activity_main2.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.yuan.test.Main2Activity">
<ImageView
android:id="@+id/main2Iv"
android:layout_width="200dp"
android:layout_height="200dp" />
</RelativeLayout>
Main2Activity.Java
public class Main2Activity extends AppCompatActivity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
testHttp(iv);
}
private void testHttp(final ImageView iv) {
new Thread(new Runnable() {
@Override
public void run() {
String urlString = "https://static.pexels.com/photos/295818/pexels-photo-295818.jpeg";
HttpURLConnection urlConnection = null;
InputStream in = null;
ByteArrayOutputStream outStream = null;
try {
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = urlConnection.getInputStream();
byte[] buffer = new byte[1024];
int len;
outStream = new ByteArrayOutputStream();
while ((len = in.read(buffer)) != -1){
outStream.write(buffer,0,len);
}
final byte[] data = outStream.toByteArray();
runOnUiThread(new Runnable() {
@Override
public void run() { //在主線程加載UI
iv.setImageBitmap(new ImageResizer().decodeSampledBitmapFromBytes(data,200,200));
}
});
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(urlConnection !=null){
urlConnection.disconnect();
}
if(in != null){
in.close();
}
if(outStream != null){
outStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
private void initView() {
iv = (ImageView) findViewById(R.id.main2Iv);
}
}
最后記得獲取網絡權限
運行的結果:
壓縮前后的bitmap大小對比

壓縮前后的bitmap大小對比
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android使用ViewPager實現(xiàn)啟動引導頁
這篇文章主要為大家詳細介紹了Android使用ViewPager實現(xiàn)第一次啟動引導頁,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07
Android編程實現(xiàn)兩個Activity相互切換而不使用onCreate()的方法
這篇文章主要介紹了Android編程實現(xiàn)兩個Activity相互切換而不使用onCreate()的方法,結合實例形式分析了多個Activity切換而不重新創(chuàng)建的操作技巧,需要的朋友可以參考下2017-01-01

