Bitmap如何压缩在android中工作?

时间:2014-07-22 18:18:06

标签: java android bitmap save

我有一个普遍的问题。 我正在编写一个日志记录应用程序,用户可以选择拍照并将其与其他信息一起保存。所有信息都作为对象存储在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;
    }
}

3 个答案:

答案 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)。这使得很容易理解为什么每个人都这样做,即使他们不必这样做。 :)