Android如何将相机拍摄的图片保存到数据库并在另一个Activity中通过列表视图显示?

6
我使用相机拍照并希望将其存储在数据库(SQLite)中。 存储的照片必须在另一个活动中以列表视图的形式显示,就像这个这个。 我正在使用以下代码拍摄照片,但如何将照片存储到数据库中并在另一个活动中显示,请帮忙提供任何想法......

谢谢....

这是拍照的代码:

  public class PhotoActivity extends Activity {
    private static final int CAMERA_REQUEST = 1888; 
    public ImageView imageView;  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.photoactivity);

        this.imageView = (ImageView)this.findViewById(R.id.imageView1);          

        Button B = (Button) this.findViewById(R.id.camera);
        B.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                startActivityForResult(cameraIntent, CAMERA_REQUEST); 
            }
        });
    }    
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if (requestCode == CAMERA_REQUEST) {  
            Bitmap photo = (Bitmap) data.getExtras().get("data");   
            imageView.setImageBitmap(photo);                

        }       
    }
}

位图不应直接保存在数据库中,而应保存在SD卡上。在数据库中,您只能保存对位图的引用。直接将位图保存在数据库中将对性能产生巨大影响。 - Ewoks
我正在为ListView扩展BaseAdapter,在其中onActivityResult()方法的代码应该是什么? - Andie
3个回答

7

嗨,朋友们。我已经找到了上述问题的解决方法。这里发布我的完整源代码,以便其他人可以使用此解决方法。

1.创建一个活动,即CameraPictureActivity。

            public class CameraPictureActivity extends Activity {
                Button addImage;
                ArrayList<Contact> imageArry = new ArrayList<Contact>();
                ContactImageAdapter imageAdapter;
                private static final int CAMERA_REQUEST = 1;

                ListView dataList;
                byte[] imageName;
                int imageId;
                Bitmap theImage;
                DataBaseHandler db;

                /** Called when the activity is first created. */
                @Override
                public void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.main);
                    dataList = (ListView) findViewById(R.id.list);
                    /**
                     * create DatabaseHandler object
                     */
                    db = new DataBaseHandler(this);
                    /**
                     * Reading and getting all records from database
                     */
                    List<Contact> contacts = db.getAllContacts();
                    for (Contact cn : contacts) {
                        String log = "ID:" + cn.getID() + " Name: " + cn.getName()
                                + " ,Image: " + cn.getImage();

                        // Writing Contacts to log
                        Log.d("Result: ", log);
                        // add contacts data in arrayList
                        imageArry.add(cn);

                    }
                    /**
                     * Set Data base Item into listview
                     */
                    imageAdapter = new ContactImageAdapter(this, R.layout.screen_list,
                            imageArry);
                    dataList.setAdapter(imageAdapter);

                    /**
                     * open dialog for choose camera
                     */

                    final String[] option = new String[] {"Take from Camera"};
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                            android.R.layout.select_dialog_item, option);
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);

                    builder.setTitle("Select Option");
                    builder.setAdapter(adapter, new DialogInterface.OnClickListener() {

                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            Log.e("Selected Item", String.valueOf(which));
                            if (which == 0) {
                                callCamera();
                            }


                        }
                    });
                    final AlertDialog dialog = builder.create();

                    addImage = (Button) findViewById(R.id.btnAdd);

                    addImage.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            dialog.show();
                        }
                    });

                }

                /**
                 * On activity result
                 */
                @Override
                protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                    if (resultCode != RESULT_OK)
                        return;

                    switch (requestCode) {
                    case CAMERA_REQUEST:

                        Bundle extras = data.getExtras();

                        if (extras != null) {
                            Bitmap yourImage = extras.getParcelable("data");
                            // convert bitmap to byte
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            yourImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
                            byte imageInByte[] = stream.toByteArray();

                            // Inserting Contacts
                            Log.d("Insert: ", "Inserting ..");
                            db.addContact(new Contact("Android", imageInByte));
                            Intent i = new Intent(CameraPictureActivity.this,
                                    CameraPictureActivity.class);
                            startActivity(i);
                            finish();

                        }
                        break;
                    }
                }

                /**
                 * open camera method
                 */
                public void callCamera()
                {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(intent, CAMERA_REQUEST);
                    intent.setType("image/*");
                    intent.putExtra("crop", "true");
                    intent.putExtra("aspectX", 0);
                    intent.putExtra("aspectY", 0);
                    intent.putExtra("outputX", 250);
                    intent.putExtra("outputY", 200);
                }
                }

2.创建DataBaseHandler类。

             public class DataBaseHandler extends SQLiteOpenHelper 
             {

            // All Static variables
            // Database Version
            private static final int DATABASE_VERSION = 1;

            // Database Name
            private static final String DATABASE_NAME = " Camera_imagedb";

            // Contacts table name
            private static final String TABLE_CONTACTS = " Camera_contacts";

            // Contacts Table Columns names
            private static final String KEY_ID = "id";
            private static final String KEY_NAME = "name";
            private static final String KEY_IMAGE = "image";

            public DataBaseHandler(Context context) {
                super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }

            // Creating Tables
            @Override
            public void onCreate(SQLiteDatabase db) {
                String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
                        + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                        + KEY_IMAGE + " BLOB" + ")";
                db.execSQL(CREATE_CONTACTS_TABLE);
            }

            // Upgrading database
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                // Drop older table if existed
                db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

                // Create tables again
                onCreate(db);
            }

            /**
             * All CRUD(Create, Read) Operations
             */

            public// Adding new contact
            void addContact(Contact contact) {
                SQLiteDatabase db = this.getWritableDatabase();

                ContentValues values = new ContentValues();
                values.put(KEY_NAME, contact._name); // Contact Name
                values.put(KEY_IMAGE, contact._image); // Contact Phone

                // Inserting Row
                db.insert(TABLE_CONTACTS, null, values);
                db.close(); // Closing database connection
            }

            // Getting single contact
            Contact getContact(int id) {
                SQLiteDatabase db = this.getReadableDatabase();

                Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
                        KEY_NAME, KEY_IMAGE }, KEY_ID + "=?",
                        new String[] { String.valueOf(id) }, null, null, null, null);
                if (cursor != null)
                    cursor.moveToFirst();

                Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
                        cursor.getString(1), cursor.getBlob(1));

                // return contact
                return contact;

            }

            // Getting All Contacts
            public List<Contact> getAllContacts() {
                List<Contact> contactList = new ArrayList<Contact>();
                // Select All Query
                String selectQuery = "SELECT  * FROM contacts ORDER BY name";

                SQLiteDatabase db = this.getWritableDatabase();
                Cursor cursor = db.rawQuery(selectQuery, null);
                // looping through all rows and adding to list
                if (cursor.moveToFirst()) {
                    do {
                        Contact contact = new Contact();
                        contact.setID(Integer.parseInt(cursor.getString(0)));
                        contact.setName(cursor.getString(1));
                        contact.setImage(cursor.getBlob(2));
                        // Adding contact to list
                        contactList.add(contact);
                    } while (cursor.moveToNext());
                }
                // close inserting data from database
                db.close();
                // return contact list
                return contactList;
            }
            }

3.创建另一个名为Contact的类

        public class Contact 
        {

            // private variables
            int _id;
            String _name;
            byte[] _image;

            // Empty constructor
            public Contact() {

            }

            // constructor
            public Contact(int keyId, String name, byte[] image) {
                this._id = keyId;
                this._name = name;
                this._image = image;

            }
            public Contact(String name, byte[] image) {
                this._name = name;
                this._image = image;

            }
            public Contact(int keyId) {
                this._id = keyId;

            }

            // getting ID
            public int getID() {
                return this._id;
            }

            // setting id
            public void setID(int keyId) {
                this._id = keyId;
            }

            // getting name
            public String getName() {
                return this._name;
            }

            // setting name
            public void setName(String name) {
                this._name = name;
            }

            // getting phone number
            public byte[] getImage() {
                return this._image;
            }

            // setting phone number
            public void setImage(byte[] image) {
                this._image = image;
            }
        }

4.创建一个适配器,即ContactImageAdapter

        public class ContactImageAdapter extends ArrayAdapter<Contact>{
             Context context;
                int layoutResourceId;   
               // BcardImage data[] = null;
                ArrayList<Contact> data=new ArrayList<Contact>();
                public ContactImageAdapter(Context context, int layoutResourceId, ArrayList<Contact> data) {
                    super(context, layoutResourceId, data);
                    this.layoutResourceId = layoutResourceId;
                    this.context = context;
                    this.data = data;
                }

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View row = convertView;
                    ImageHolder holder = null;

                    if(row == null)
                    {
                        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                        row = inflater.inflate(layoutResourceId, parent, false);

                        holder = new ImageHolder();
                        holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
                        holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
                        row.setTag(holder);
                    }
                    else
                    {
                        holder = (ImageHolder)row.getTag();
                    }

                    Contact picture = data.get(position);
                    holder.txtTitle.setText(picture._name);
                    //convert byte to bitmap take from contact class

                    byte[] outImage=picture._image;
                    ByteArrayInputStream imageStream = new ByteArrayInputStream(outImage);
                    Bitmap theImage = BitmapFactory.decodeStream(imageStream);
                    holder.imgIcon.setImageBitmap(theImage);
                   return row;

                }

                static class ImageHolder
                {
                    ImageView imgIcon;
                    TextView txtTitle;
                }
            }

5.最后创建xml文件main和screen_list。

5.1 main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffff"
        android:orientation="vertical" >

        <Button
            android:id="@+id/btnAdd"
            android:layout_width="fill_parent"
            android:layout_height="60dp"
            android:text="Add Image" />

        <ListView
            android:id="@+id/list"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="0.55"
            android:cacheColorHint="#00000000" >
        </ListView>

    </LinearLayout>

5.2 屏幕清单.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/imgIcon"
        android:layout_width="200dp"
        android:layout_height="200dp"
       android:scaleType="fitXY"
        android:gravity="center_vertical" />

    <TextView
        android:id="@+id/txtTitle"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:textSize="14dp"
        android:text="@string/hello"
        android:textColor="#000000"
        android:layout_marginLeft="7dp" />

</LinearLayout>

6. 输出如下所示。 enter image description here enter image description here


3

创建数据库帮助类,就像这个一样。

在捕获图像时,将图像转换为字节并插入到数据库中:

Imagehelper help=new Imagehelper(this);

    if (requestCode == CAMERA_REQUEST) {  
                        Bitmap photo = (Bitmap) data.getExtras().get("data");   
                        imageView.setImageBitmap(photo);
                        ByteArrayOutputStream stream = new ByteArrayOutputStream();
                        photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
                        byte[] byteArray = stream.toByteArray();

                        help.insert(byteArray);
    }

从数据库中检索表单:
Imagehelper help=new Imagehelper(this);

       Cursor c= help.getAll();
       int i=0;
       if(c.getCount()>0)
       {  
           Bitmap[]  array=new Bitmap[c.getCount()];
           c.moveToFirst();
           while(c.isAfterLast()==false)
           {

               byte[] bytes=c.getBlob(c.getColumnIndex("imageblob"));

            array[i]=BitmapFactory.decodeByteArray(bytes, 0, 0);
            c.moveToNext();
            i++;
            }
           Log.e("Bitmap length",""+array.length);
       }

将此位图数组传递给ListView。

@Xylian 你可以从 Media 中获取所捕获图片的缩略图。查看这个SO答案 - Abhi
不要将位图保存在SQLite数据库中,绝对不行。只需将图像的引用存储在数据库中即可。 - Ewoks
@Ewoks 朋友,请仔细阅读问题,我已经回答了它,你说的是最佳实践。 - Abhi
@Abhi“伙计”,如果有人为了礼貌而提出更好的问题,你不应该给出错误的建议。相反,如果有人遇到问题并请求帮助,但是走了错误的方向,你至少应该提到这是错误的方向和错误的解决方案。这将有助于他和其他阅读此内容的人节省时间。当然,如果你知道那是错误的,就要说出来。 - Ewoks
@Ewoks,如果你在下面的问题中写下评论,我会非常感激你。 - Abhi

2

我不确定是否应该将位图本身保存在sqlite数据库中。 但是使用Blob时是可能的。Blob需要一个byte[]。

您可以通过保存位图(使用compress)并再次读取文件来获得字节数组。 http://developer.android.com/reference/android/graphics/Bitmap.html

Bitmap b;
File f = new File (...);
FileOutputStream fs = new FileOutputStream (f);
b.compress(JPEG, 85, fs);
fs.close ();
// Reread the file f into a byte []

或者

Bitmap b;
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
b.compress(JPEG, 85, baos);
baos.close ();
byte[] blob = baos.toByteArray ();
b.compress(JPEG, 85, baos)

或者您可以将位图序列化为ByteArrayOutputStream(使用ObjectOutputStream)

Bitmap b;
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
ObjectOutputStream oos = new ObjectOutputStream (baos);
oos.write (b);
oos.close ();
baos.close ();
byte[] blob = baos.toByteArray ();

然而,将位图保存为文件(JPG或PNG)可能更有意义,因为它们可能会变得更大。数据库只会保存有关该图像的路径信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接