2013-12-19 48 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

不是,主要是因爲如果圖像沒有存儲在私人共享中,您不能保證該文件仍在設備上。例如,用戶刪除圖像。這會導致意外的崩潰。但是接下來你可以創建一個私人共享文件夾並將它們保存在那個文件夾中而不是在公共文件系統中。 –