SQLite DB Blob字段与Android文件系统

SQLite DB Blob字段与Android文件系统,android,image,sqlite,blob,Android,Image,Sqlite,Blob,这是导致头颅撕裂的原因,也许有人能解释一下情况。我用相机拍摄一张照片(当然,任何数量的照片都可以),就像这样: ImageView imgPhoto = (ImageView)findViewById(R.id.imgButtonPhoto); imgPhoto.setBackgroundColor(Color.rgb(71,117,255)); imgPhoto.setOnClickListener(new View.OnClickListener() {

这是导致头颅撕裂的原因,也许有人能解释一下情况。我用相机拍摄一张照片(当然,任何数量的照片都可以),就像这样:

    ImageView imgPhoto = (ImageView)findViewById(R.id.imgButtonPhoto);
    imgPhoto.setBackgroundColor(Color.rgb(71,117,255));
    imgPhoto.setOnClickListener(new View.OnClickListener()
    {           
        @Override
        public void onClick(View v) 
        {   
            ++snapNumber; 

            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            lastPicSaved = String.valueOf(gd.getDeliveryId()) + "_" + String.valueOf(snapNumber) + ".jpg";
            Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), lastPicSaved));             

            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(intent, GooseConsts.IMAGE_CAPTURE_INTENT);           
        }
    });
一旦活动完成,我会这样做:

    case GooseConsts.IMAGE_CAPTURE_INTENT:
        try 
        {
            String newCompressedImage = Environment.getExternalStorageDirectory() + "/" + lastPicSaved;

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 4;   
            //options.inDensity = DisplayMetrics.DENSITY_MEDIUM;

            Bitmap b = BitmapFactory.decodeFile(newCompressedImage, options);
            FileOutputStream fos;

            fos = new FileOutputStream(newCompressedImage);
            b.compress(CompressFormat.JPEG, 60, fos);

            fos.flush();
            fos.close();

            Image i = new Image();
            i.setReported(0);
            i.setReportedFull(0);
            i.setImage(newCompressedImage);
            //i.setImageData(b);

            dbHelper.insertImageReference(i, gd.getDeliveryId());   
    }
简单的东西。如您所见,我正在使用
选项。inSampleSize
并在压缩时降低质量,以减小最终图像的大小,从而保持一个小的图像捕获,通过XMPP数据包发送回hq

有趣的部分来了 在文件系统上,生成的映像大小约为50Kb,可能稍大一点,但不会超过60Kb。这很好,它通过XMPP发送,我可以在我编写的自定义连接客户端中处理和显示它

我想最好是保留图像,以防由于任何原因发送失败,但不希望它们在文件系统中丢失,因此在本地设备数据库中添加了一个
BLOB
字段。我想知道我是否可以直接从上述数据库发送它们并完全删除文件系统,所以我尝试了一下,突然没有图像被我的客户端bot发送/接收。奇怪!经过一番挖掘,我注意到保存到db
BLOB
中的图像现在(令人惊讶地)是原始图像的3倍大。相同的尺寸(486x684)和相同的质量(我已经拉了一些来测试存储在SD卡上的)

谁能告诉我为什么会这样?我已经使用BLOB字段很多年了,以前从未见过文件大小有如此大的增长。当然,这里和那里都有几个Kb,但不是从50 Kb跳到160Kb以上


非常感谢。

压缩图像后,将图像转换为字节数组,而不是使用blob

Bitmap b = BitmapFactory.decodeFile(newCompressedImage, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 60, stream);
byte [] byteArray = stream.toByteArray();
这将使文件大小保持在最小值。当然,您必须将字节数组转换回位图进行显示。但这应该是直截了当的

我相信字节数组的大小是有限制的。将其初始化为

byte [] byteArray = new byte [1024];
// then
byteArray = stream.toByteArray();

您是否建议这样做,而不是说,在数据库中存储一个路径引用,然后返回到使用文件系统?我可能每周要处理数千张图像,如果涉及到ofc,我宁愿在设备上保留一个小的内存,而不是增加一个db。这不是真的,主要是因为如果图像没有存储在私有共享中,你不能保证文件仍然在设备上。例如,用户删除图像。这将导致意外的崩溃。但是,您也可以创建一个私有共享文件夹,并将它们保存在该文件夹中,而不是保存在公共文件系统中。