【问题标题】:Is it a good idea to store bitmap as BLOB in Sqlite?在 Sqlite 中将位图存储为 BLOB 是个好主意吗?
【发布时间】:2015-09-14 20:03:42
【问题描述】:

如果我在我的 sqlite 数据库中存储了太多位图(作为 BLOB),在检索它们时我会得到奇怪的异常(即使是 Throwable,我也无法捕获,但我每次都可以在 LogCat 中看到它):

Failed to read row 2, column 0 from a CursorWindow which has 2 rows, 8 columns

当我不存储 BLOB 时,我不会遇到此类异常。也许我应该将图像存储在手机内存中并将这些图像保存在数据库 uris 中?

有什么问题?谁能告诉我?

【问题讨论】:

    标签: android sqlite bitmap


    【解决方案1】:

    通常在您的数据库中存储位图/图像通常不是一个好主意,它根本没有效率。

    您应该将位图保存为图像并将路径存储在数据库中。

    这已在this question 上讨论过。


    编辑:

    但是...如果您真的出于某种原因想要存储它,您也可以尝试将图像编码为 Base64 String,并将其存储在您的数据库中。

    Android 为此提供了Base64 class。尝试使用以下sn-p进行编码:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); // Could be Bitmap.CompressFormat.PNG or Bitmap.CompressFormat.WEBP
    byte[] bai = baos.toByteArray();
    
    String base64Image = Base64.encodeToString(bai, Base64.DEFAULT);
    
    // Call your method to save this string on the DB here.
    

    您必须对其进行解码尝试以下操作:

    byte[] data = Base64.decode(base64Image, Base64.DEFAULT);
    Bitmap bm;
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inMutable = true;
    bm = BitmapFactory.decodeByteArray(data, 0, data.length, opt);
    
    // Now do whatever you want with the Bitmap.
    

    您可以查看Bitmaphere 的文档。

    【讨论】:

    【解决方案2】:
      profile_images.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
    
    
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                    photoPickerIntent.setType("image/*");
                    startActivityForResult(photoPickerIntent, SELECT_PHOTO);
    
                }
            });
    
    
      protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
            super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    
            switch(requestCode) {
                case SELECT_PHOTO:
                    if(resultCode == RESULT_OK){
                        Uri selectedImage = imageReturnedIntent.getData();
                        try {
                            Bitmap bmp = decodeUri(selectedImage);
                            profile_images.setImageBitmap(bmp);
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                            byte[] byteArray = stream.toByteArray();
    
                            insertUser(byteArray);
    
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
            }
        }
    public void insertUser(byte[] logoImage ){
        SQLiteDatabase db               =   dbs.getWritableDatabase();
    
        String delSql                       =   "DELETE FROM Image";
        SQLiteStatement delStmt         =   db.compileStatement(delSql);
        delStmt.execute();
    
        String sql                      =   "INSERT INTO Image (CODE,Img) VALUES(?,?)";
        SQLiteStatement insertStmt      =   db.compileStatement(sql);
        insertStmt.clearBindings();
        insertStmt.bindLong(1, 1);
        insertStmt.bindBlob(2,logoImage);
        //   insertStmt.bindBlob(3, this.accImage);
        insertStmt.executeInsert();
        db.close();
    }
    
    
    
      public Bitmap getCurrentBitmap() {
            SQLiteDatabase db       =   dbs.getWritableDatabase();
            String sql              =   "SELECT * FROM Image";
            Cursor cursor           =   db.rawQuery(sql, new String[]{});
            Bitmap bmp=null;
            if(cursor.moveToFirst()){
                //this.accId             = cursor.getInt(0);
                //  this.accName           = cursor.getString(1);
                byte[] logoImage       = cursor.getBlob(1);
    
                bmp = BitmapFactory.decodeByteArray(logoImage, 0, logoImage.length);
            }
            if (cursor != null && !cursor.isClosed()) {
                cursor.close();
            }
            db.close();
            if(cursor.getCount() == 0){
                return null;
            } else {
                return bmp;
            }
        }
    
    
        private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
    
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
    
            // The new size we want to scale to
            final int REQUIRED_SIZE = 140;
        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
                    || height_tmp / 2 < REQUIRED_SIZE) {
                break;
            }
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }
    
        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
    
    }
    

    你可以按照上面给出的方法做到这一点。

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多