【问题标题】:picture isn't saved properly into the database (as BLOB)图片未正确保存到数据库中(作为 BLOB)
【发布时间】:2011-07-23 22:58:17
【问题描述】:

我尝试将图片作为 BLOB 保存到数据库中,但它没有正确存储在数据库中。

传递的 byte[] 是正确的,有 4300 个字符,而在数据库中它只有 12 个字符。 这就是存储在数据库中的内容:[B@43e7be68

这是我的 SQL_INSERT 的代码:

public boolean SQL_INSERT_PICTURE(PictureDatatype type) {
    try{
        this.db = openHelper.getWritableDatabase();
        Log.d(TAG, "Insert picture");
        System.out.println("insert picture");
        db.execSQL("DELETE FROM picture " +
                "where " + LinkPic + " = '" + type.getLink() + "'");
        db.execSQL("INSERT OR REPLACE INTO picture " +
                "( " + NamePic + ", " + LinkPic + ", " + PicturePic + ") " +
                "VALUES ('" + type.getName() + "', '" + type.getLink() +"', '" + 
                type.getPicture() +"')");

        System.out.println("size of the picture (bytearray): " + type.getPicture().length);
        System.out.println("the picture: " + type.getPicture());
        System.out.println("insert complete");
        db.close();
        return true;
    }
        catch(SQLException s){
            System.out.println("Insert failed");
            db.close();
            return false;
        }
}

我的问题是为什么没有正确的字节 [] 存储在数据库中,或者我该怎么做? 如果您需要更多信息或代码,请告诉我。

谢谢 柯比

【问题讨论】:

  • 只是一个旁注。您不应该将图片 (BLOB) 保存到数据库中,因为它会使 CPU 更密集地执行诸如将二进制文件转换回媒体类型之类的任务:) 为什么不将图片的路径保存到数据库中
  • 旁注:如果您要插入或替换,则无需先删除图片...
  • 另外,使用字符串连接组装 SQL 语句是 SQL 注入利用的可靠途径 --- 不要这样做!去看看使用绑定参数的 execSQL() 版本;你可以做db.execSQL("DELETE FROM picture where LinkPic = ?", new Object[] { type.getLink() });。它更快、更容易阅读,并且完全使您免受 SQL 注入问题的影响。
  • 好的解决了。将带有 Base64 的图片转换为字符串,然后将字符串保存在数据库中并且它可以工作。如果你愿意,我可以发布源代码。

标签: android database sqlite blob image


【解决方案1】:

使用此代码将图像转换为可以存储为 BLOB 的 ByteArray:

    private byte[] getBitmapAsByteArray(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // Middle value is quality, but PNG is lossless, so it's ignored.
        bitmap.compress(CompressFormat.PNG, 0, outputStream);
        return outputStream.toByteArray();
    }

    private byte[] getBitmapAsByteArray(Bitmap bitmap) {
        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        ByteBuffer byteBuffer = ByteBuffer.allocate(width * height * 4);

        bitmap.copyPixelsToBuffer(byteBuffer);
        return byteBuffer.array();
    }

第一个选项应该始终有效。第二个选项假定每像素 32 位(ARGB_8888 格式),因此 4 字节。如果您的位图是另一种格式(例如 565),则需要进行一些修改。

当你从数据库中读取图像数据时,这样做:

   public Bitmap loadIcon(long iconId) {
       // Prepare the cursor to read from database....
       byte[] bitmapData = cursor.getBlob(cursor.getColumnIndex(Columns.Icons.DATA));

       return BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length);
   }

确保在执行“create table”SQL 语句时数据库被定义为 BLOB。

【讨论】:

    【解决方案2】:

    哎呀,看起来你正试图将一个 byte[] 数组传递给一个字符串。

    出于多种原因(安全性和性能),以这种方式组装 SQL 字符串是一个非常糟糕的主意。

    关于准备好的语句,请参阅这两个问题,以及如何将值绑定到语句而不必连接您的 SQL:

    insert a picture into database(sqlite) with java code. what should i do?

    Java Exception Error - Sqlite preparedStatement.setBlob

    【讨论】:

      猜你喜欢
      • 2013-12-05
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 2017-11-30
      相关资源
      最近更新 更多