2013-12-19 37 views
0

这是一件令人头疼的事情,也许有人可以澄清一些情况。我使用的相机意图拍摄照片(当然,真正的任意数量的照片),像这样:SQLite数据库Blob字段与Android文件系统

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()); 
    } 

简单的东西真的。正如您所看到的,我使用的是options.inSampleSize,并且在压缩时降低了质量,以减小最终图像的大小,从而通过XMPP数据包保留小图像捕获以发送回hq。

这里有趣的部分! 在文件系统上,生成的图像大小约为50Kb,可能会多一点,但不能超过60Kb。这很好,通过XMPP发送,我可以处理并显示在我也写过的定制连接客户端中。

我认为最好保留这些图片,以防发送失败,但不希望它们在文件系统中丢失,因此在本地设备数据库中添加了BLOB字段。我想知道是否可以直接从上述数据库发送它们,并彻底取消文件系统,所以我试了一下,突然我的客户端机器人发送/接收图像。奇怪!经过一番挖掘,我发现保存在db BLOB中的图像现在(惊人地)是原始大小的3倍。相同的尺寸(486x684)和相同的质量(因为我adb拉了几个测试对SD卡上存储的)。

谁能告诉我为什么这样?我一直在使用BLOB字段多年,从未见过如此剧烈的文件大小增长。几个Kb在这里和那里,当然,但不是从50(ish)Kb跳到160Kb以上?

非常感谢。

回答

1

后,您可以压缩图像的图像转换为字节数组,而不是使用一个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(); 
+0

您是否建议这样做,而不是说在数据库中存储路径引用,然后回退到使用文件系统?我可以每周处理数以千计的图像,并且宁可在设备上保留一小部分图像,而不是膨胀数据库,如果涉及到数据库。 – LokiSinclair

+1

不是,主要是因为如果图像没有存储在私人共享中,您不能保证该文件仍在设备上。例如,用户删除图像。这会导致意外的崩溃。但是接下来你可以创建一个私人共享文件夹并将它们保存在那个文件夹中而不是在公共文件系统中。 –