我有一个普遍的问题。 我正在编写一个日志记录应用程序,用户可以选择拍照并将其与其他信息一起保存。所有信息都作为对象存储在arraylist中,但是我很难将图像保存为文件作为对象的一部分。我终于发现Bitmap不是可序列化的,所以这就是一个问题所在。到目前为止,我想要做的就是将位图保存在自己的arraylist中,以便我可以使用与对象arraylist相同的位置调用特定的位图,并且可以在ImageViewer上设置位图。 在我保存Bitmaps的所有发现中,我看到每个人都在压缩它们并解码它们。我的问题是,为什么必须将位图压缩(或者它)保存到文件中?
以防万一这会让我的问题更有意义,这是我的代码:
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;
}
}
答案 0 :(得分:3)
位图没有被压缩,但压缩它们实现了两个目标:它将它们序列化并使它们变小。
位图只是......位图......尽管很简单,但请考虑一下:
如果您的图像为1000 x 1000,并且每个像素使用短的颜色表示颜色。 (这只是一个例子,所以和我一起滚动)。现在想象一下这张照片中的每个像素都是白色的。
如果您在没有压缩的情况下对其进行序列化,那么该文件将存储如下内容: 高度:1000,宽度:1000,含量:白,白,白,白,白,白,白,白,.........
序列化取决于所使用的算法,但我们假设您使用LZW的变体并使用一个int来指示集合中的像素数和颜色。在这种情况下,您必须保存到压缩文件的所有内容都是height:1000,width:1000,content:1000000xWHITE。这可以很容易地保存在几个字节中。
答案 1 :(得分:1)
位图是可序列化的(事实上位图是序列化)。只需将其转换为Base64。
所以基本上你可以压缩它,将它写入文件或序列化它。
答案 2 :(得分:1)
它不需要压缩,但保存它们未压缩是一种非常非常糟糕的做法,除非你有特殊的理由不这样做。
Bitmaps的一个优势 - 以及Android应用程序使用它们的原因 - 是它们完全未压缩,基本上只是一堆描述图像的位。现在,这意味着格式非常简单,解码速度非常快,这使得它们非常适合面向UI的任何内容,包括Android应用程序。如果您正在绘制PNG或JPEG而不是位图,那么您的应用将 更慢。
然而,就所使用的存储空间而言,这种简单性和完全缺乏压缩也使其成为迄今为止最大图像格式。简单地通过即使是最不具侵入性的JPEG或PNG压缩器传递你的位图也会将尺寸缩小几个数量级,代价是基本没有质量(JPEG)或完全没有质量损失(PNG)。这使得很容易理解为什么每个人都这样做,即使他们不必这样做。 :)