[英]How does Bitmap compress work in android?
我有一個一般性的問題。 我正在編寫一個日志記錄應用程序,用戶可以在其中選擇拍照並與其他信息一起保存。 所有信息都作為對象存儲在arraylist中,但是我很難將圖像作為對象的一部分保存到文件中。 我終於弄清楚了位圖是不可序列化的,所以這就是一個問題所在。 現在,我要做的就是將位圖保存在自己的arraylist中,以便可以使用與對象arraylist相同的位置調用特定的位圖,並且可以在ImageViewer上設置位圖。 在保存位圖的所有發現中,我看到每個人都在對其進行壓縮和解碼。 我的問題是,為什么必須將位圖壓縮(或將其保存到文件中)?
以防萬一這將使我的問題更有意義,這是我的代碼:
package com.example.ticklist;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
public class DataProvider {
private static final String ROUTES = "routes";
private static final String PICS = "pictures";
static Bitmap photo;
static ArrayList<Bitmap> bList;
public static boolean writeRoute(Route r, Bitmap img){
ArrayList<Route> list = getRoutes();
ArrayList<Bitmap> bmlist = getPictures();
list.add(r);
bmlist.add(img);
FileOutputStream fos;
FileOutputStream fosp;
try {
fos = TicklistMain.getContext().openFileOutput(ROUTES, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
fosp = TicklistMain.getContext().openFileOutput(PICS, Context.MODE_PRIVATE);
ObjectOutputStream oosp = new ObjectOutputStream(fosp);
oos.writeObject(list);
oosp.writeObject(bmlist);
oos.close();
oosp.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public static ArrayList<Route> getRoutes(){
FileInputStream fis;
ArrayList<Route> list = null;
try {
fis = TicklistMain.getContext().openFileInput(ROUTES);
ObjectInputStream ois = new ObjectInputStream(fis);
list = (ArrayList<Route>) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
list = new ArrayList<Route>();
} catch (StreamCorruptedException e) {
list = new ArrayList<Route>();
e.printStackTrace();
} catch (IOException e) {
list = new ArrayList<Route>();
e.printStackTrace();
} catch (ClassNotFoundException e) {
list = new ArrayList<Route>();
e.printStackTrace();
}
return list;
}
public static ArrayList<Bitmap> getPictures(){
FileInputStream fis;
ArrayList<Bitmap> bmlist = null;
try {
fis = TicklistMain.getContext().openFileInput(PICS);
ObjectInputStream ois = new ObjectInputStream(fis);
bmlist = (ArrayList<Bitmap>) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
bmlist = new ArrayList<Bitmap>();
} catch (StreamCorruptedException e) {
bmlist = new ArrayList<Bitmap>();
e.printStackTrace();
} catch (IOException e) {
bmlist = new ArrayList<Bitmap>();
e.printStackTrace();
} catch (ClassNotFoundException e) {
bmlist = new ArrayList<Bitmap>();
e.printStackTrace();
}
return bmlist;
}
public static Bitmap getPicture(int position){
ArrayList<Bitmap> bList = getPictures();
photo = bList.get(position);
return photo;
}
}
以及我所說的位置:
package com.example.ticklist;
import java.util.ArrayList;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class SendList extends ListFragment {
AddRope ar = new AddRope();
Bitmap bm;
private static final String TAG = TicklistMain.class.getName();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return super.onCreateView( inflater, container, savedInstanceState);
//View rootView = inflater.inflate( R.layout.mylistfrag_layout, container, false);
//return rootView;
}
@Override
public void onActivityCreated(Bundle b) {
super.onActivityCreated(b);
ArrayList<Route> list = DataProvider.getRoutes();
ArrayAdapter<Route> adapter = new ArrayAdapter<Route>(getActivity(),
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter);
} //onActivity
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
ArrayList<Route> list = DataProvider.getRoutes();
ArrayList<Bitmap> pList = DataProvider.getPictures();
Log.d(TAG, "position " + position);
bm = pList.get(position - 1);
Route routeDetail = list.get(position);
RouteDetail fragment = new RouteDetail();
fragment.loadData(routeDetail);
fragment.loadPicture(bm);
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.ticklist_container, fragment);
ft.addToBackStack(null);
ft.commit();
}
}
和詳細視圖:
package com.example.ticklist;
import com.example.ticklist.R;
import android.app.Fragment;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class RouteDetail extends Fragment{
TextView routeName, routeGrade, routeDate, routeComments;
ImageView img;
private Route r;
private Bitmap bmp;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.route_detail,
container, false);
routeName = (TextView) view.findViewById(R.id.routeName);
routeGrade = (TextView) view.findViewById(R.id.routeGrade);
routeDate = (TextView) view.findViewById(R.id.routeDate);
routeComments = (TextView) view.findViewById(R.id.routeComments);
img = (ImageView) view.findViewById(R.id.routeImage);
routeName.setText(r.getName());
routeGrade.setText(r.getGrade());
routeDate.setText(r.getDate());
routeComments.setText(r.getComments());
img.setImageBitmap(bmp);
return view;
}
public void loadData(Route routeDetail) {
// TODO Auto-generated method stub
this.r = routeDetail;
}
public void loadPicture(Bitmap img){
this.bmp = img;
}
}
位圖不必進行壓縮,但是壓縮它們可以實現兩個目標:序列化它們並使它變小。
位圖只是..位圖...就這么簡單,考慮一下:
如果您具有1000 x 1000的圖像,並且每個像素都使用short表示一種顏色。 (這只是一個例子,所以和我一起滾動)。 現在,假設該圖片中的每個像素都是白色。
如果在不壓縮的情況下序列化了該文件,則文件將存儲以下內容:height:1000,width:1000,content:WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,.........
序列化取決於所使用的算法,但是假設您使用LZW的一種變體,並使用一個int表示集合中有多少像素和顏色。 在這種情況下,您只需要保存到壓縮文件中即可:height:1000,width:1000,content:1000000xWHITE。 可以很容易地保存在幾個字節中。
位圖是可序列化的(實際上位圖是序列化的)。 只需將其轉換為Base64。
因此,基本上您可以壓縮它,將其寫入文件或序列化。
不必壓縮它,但是將它們保存為未壓縮是非常非常糟糕的做法,除非您有特定的理由不這樣做。
位圖的一個優點(以及Android應用程序使用它們的原因)是,它們完全未被壓縮,實質上只是一堆描述圖像的位。 現在,這意味着該格式非常簡單且可以快速解碼,這使得它們非常適合任何面向UI的應用程序,包括Android應用程序。 如果您要繪制的是PNG或JPEG而不是位圖,則您的應用程序會慢很多 。
但是,這種簡單性和完全沒有壓縮也使其成為迄今為止使用的存儲空間最大的圖像格式。 只需將位圖甚至通過侵入性最小的JPEG或PNG壓縮器,就可以將大小減小多個數量級,而代價是基本上沒有質量(JPEG)或絕對沒有質量損失(PNG)。 這使得很容易理解為什么每個人都這樣做,即使他們不必這樣做。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.