2011-12-27 79 views
2

什麼我目前正在做的是以下幾點:Base64編碼和觀看圖像

拍照,將其壓縮到PNG,使用Base64的隱蔽,它通過PHP發送到數據庫。這一切都像一個魅力。我也可以解碼Base64字符串並完美地顯示照片。

但是,問題似乎是,當我在瀏覽器上查看圖片時,它的尺寸與它應該是不一樣的(或者至少我認爲)。

這是我花了編碼,並顯示在瀏覽器中的圖像: enter image description here

無論電話,(還就GALAXY SII測試)的,這個問題仍然存在。你們有什麼想法可能會發生什麼?這裏有一些想法,我有但不知道... 1.壓縮圖像太多 - 或壓縮它時會改變某些東西2.Base64編碼/解碼搞亂了照片,並沒有正確顯示3.當我放置圖像視圖中的圖像會修改大小。

再一次,它看起來像完整的圖像沒有得到發送,因爲沒有辦法一個圖像甚至銀河sII圖像看起來很小。

這裏是我使用的代碼: 安卓

// CONVERT: 
     ByteArrayOutputStream bao = new ByteArrayOutputStream(); 
     picture.compress(Bitmap.CompressFormat.PNG, 100, bao); 
     Log.d(TAG, "AFTER. Height: " + picture.getHeight() + " Width: " + picture.getWidth()); 
     final byte[] ba = bao.toByteArray(); 

     //encode to string 
     String photoTest = Base64.encodeToString(ba, Base64.DEFAULT); 

//Camera on activity for result - save it as a bmp and place in imageview 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == CAMERA_PIC_REQUEST) { 
      // do something 
     } 

     if (resultCode == Activity.RESULT_OK) { 
      Log.d(TAG, "result ok"); 

      Bundle b = data.getExtras(); 
      picture = (Bitmap) b.get("data"); 
      imageView.setImageBitmap(picture); 
     } 
    } 

IMAGE去Android:

<ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="100dp" 
     android:layout_height="100dp" 
     android:src="@drawable/icon"/> 

PHP:

$image = base64_decode($_POST['image_data']); 

謝謝您的幫助!

+1

這是無關Base64以及所有關於如何轉換圖像的信息。如果圖像在解碼時太小,編碼時太小。 Base64以ASCII格式存儲二進制數據 - 解碼時數據完全相同,如果出錯,則啓動時出錯。 – DaveRandom 2011-12-27 17:50:34

+0

感謝您的回覆DaveRandom。如果我理解你寫的是正確的,那麼問題是當傳遞給編碼時圖像大小不是原始大小。所以我想我的下一個問題是否是一種獲得圖像真實大小的方法。 – Splitusa 2011-12-27 17:57:41

+1

我認爲@ Campadrenaline的答案是朝着正確的方向前進 - 我懷疑它是轉換圖像的'picture.compress()'。不要忘記,這不是關於「質量」,因爲這往往是用於壓縮圖像的方式。您遇到的問題是圖像被重新調整大小,或者在您的客戶端代碼的某個位置「重新採樣」。你應該把壓縮代碼拿出來,試着讓它在沒有它的情況下工作,然後開始壓縮。 – DaveRandom 2011-12-27 18:07:18

回答

1

我如何解決它:原來,當你像上面那樣保存照片時,它只返回照片的縮略圖版本而不是全尺寸照片。我必須添加EXTRA_OUTPUT到我的意圖,保存到SD卡,然後壓縮。如果有人有類似的問題,請給我留言。

+0

我有類似的問題,但我不明白你的解決方案是什麼意思。 – Andrew 2013-04-18 19:51:52

1

base64保留完整的二進制數據,它不會調整大小的噱頭。我猜問題線是picture.compress(Bitmap.CompressFormat.PNG, 100, bao);,但這不是我的領域。

+0

感謝您的回覆。糾正我,如果我錯了,但我認爲PNG忽略了壓縮的質量方面,因此從10​​0-0的值不重要。我不知道這個 – Splitusa 2011-12-27 17:59:15

+0

PNG不會忽略質量AFAIK。我的理解是,它基於質量變量運行了多次無損算法(所以它實際上不是質量的折衷,而是編碼/解碼時間的大小)。現在我不太確定。無論如何,在你的圖像預處理流程中,你肯定會遇到問題。一旦它在Base64中,它就基本上是安全的,直到解碼爲止。 – Campadrenalin 2011-12-27 18:35:16

0

我有同樣的問題,這是我如何解決我的問題,這種方法將打開默認的相機應用程序,將圖像保存到臨時文件夾,並將其轉換爲Base64/ByteArray。

1 - 點擊監聽器打開相機應用

// My ImageButton click Listener 
ibt_foto.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 

     String tempDir = Environment.getExternalStorageDirectory() + "/folder/"; 
     String path = Environment.getExternalStorageDirectory() + "/folder/photo1.jpg"; 
     prepareDirectory(); 
     File file = new File(path); 
     Uri outputFileUri = Uri.fromFile(file); 
     Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
     startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); 
    } 
}); 

2 - 創建文件夾

private boolean prepareDirectory() { 
    try { 
     if (makedirs()) { 
      return true; 
     } else { 
      return false; 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_LONG).show(); 
     return false; 
    } 
} 

private boolean makedirs() { 

    File tempdir = new File(tempDir); 
    if (!tempdir.exists()) { 
     tempdir.mkdirs(); 
    } 

    /* 
    // Use this if you want to delete older files 
    if (tempdir.isDirectory()) { 
     File[] files = tempdir.listFiles(); 
     for (File file : files) { 
      if (!file.delete()) { 
       System.out.println("Failed to delete " + file); 
      } 
     } 
    } 
    */ 

    return (tempdir.isDirectory()); 
} 

3 - 從攝像頭應用程序的處理結果

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    System.gc(); 

    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) { 
     if (resultCode == RESULT_OK) { 
      try { 

       // Get image 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize = 3; 
       Bitmap imageBitmap = BitmapFactory.decodeFile(path, options); 

       // Converting to ByteArray and Base64 
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
       boolean validaCompressao = imageBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); 
       byte[] fotoBinario = outputStream.toByteArray(); 

       String encodedImage = Base64.encodeToString(fotoBinario, Base64.DEFAULT); 

       // setting image to my ImageButton 
       ibt_foto.setImageBitmap(imageBitmap); 

      } catch (Exception e) { 
       Toast.makeText(this, "Picture Not taken",Toast.LENGTH_LONG).show();e.printStackTrace(); 
      } 
     } else if (resultCode == RESULT_CANCELED) { 
      Toast.makeText(this, "Picture was not taken 1 ", Toast.LENGTH_SHORT); 
     } else { 
      Toast.makeText(this, "Picture was not taken 2 ", Toast.LENGTH_SHORT); 
     } 
    } 
}