2012-12-10 156 views
2

使用StackOverflow和其他有用網站的資源,我成功地創建了一個應用程序,可以在Android手機上上傳相機應用程序拍攝的圖像。唯一的問題是,我現在使用的手機拍攝的照片質量非常高,導致漫長的等待上傳時間。如何降低Android上字節格式圖像的質量?

我讀過關於將圖像從jpeg轉換爲較低速率(較小的尺寸或只是網頁友好的尺寸),但我現在使用的代碼將捕獲的圖像保存爲一個字節(請參閱下面的代碼)。有沒有辦法以圖像的形式降低圖像的質量,或者是否需要找到一種方法將圖像轉換回jpeg,降低圖像質量,然後再以字節形式放回圖像?

這裏是代碼片段我的工作:

if (Intent.ACTION_SEND.equals(action)) { 

     if (extras.containsKey(Intent.EXTRA_STREAM)) { 
      try { 

       // Get resource path from intent callee 
       Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM); 

       // Query gallery for camera picture via 
       // Android ContentResolver interface 
       ContentResolver cr = getContentResolver(); 
       InputStream is = cr.openInputStream(uri); 
       // Get binary bytes for encode 
       byte[] data = getBytesFromFile(is); 

       // base 64 encode for text transmission (HTTP) 
       int flags = 1; 
       byte[] encoded_data = Base64.encode(data, flags); 
       // byte[] encoded_data = Base64.encodeBase64(data); 
       String image_str = new String(encoded_data); // convert to 
                   // string 

       ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 

       nameValuePairs.add(new BasicNameValuePair("image", 
         image_str)); 

       HttpClient httpclient = new DefaultHttpClient(); 
       HttpPost httppost = new HttpPost(
         "http://xxxxx.php"); 
       httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
       HttpResponse response = httpclient.execute(httppost); 
       String the_string_response = convertResponseToString(response); 
       Toast.makeText(UploadImage.this, 
         "Response " + the_string_response, 
         Toast.LENGTH_LONG).show(); 
      } catch (Exception e) { 
       Toast.makeText(UploadImage.this, "ERROR " + e.getMessage(), 
         Toast.LENGTH_LONG).show(); 
       System.out.println("Error in http connection " 
         + e.toString()); 
      } 
     } 
    } 
} 

回答

4

對於Web應用程序,你肯定不需要這樣的相機產生5+ MP圖像;圖像分辨率是圖像大小的主要因素,所以我建議您使用BitmapFactory類來生成下采樣位圖。

特別是,看看BitmapFactory.decodeByteArray(),並傳遞給它一個BitmapFactory.Options參數,表明你想要一個下采樣位圖。

// your bitmap data 
byte[] rawBytes = .......... ; 

// downsample factor 
options.inSampleSize = 4; // downsample factor (16 pixels -> 1 pixel) 

// Decode bitmap with inSampleSize set 
return BitmapFactory.decodeByteArray(rawBytes, 0, rawBytes.length, options); 

欲瞭解更多信息,看看上有效地顯示位圖在Android培訓課程和BitmapFactory參考:

http://developer.android.com/training/displaying-bitmaps/index.html

http://developer.android.com/reference/android/graphics/BitmapFactory.html

+0

對於inSampleSize,將在繼續通過縮小4倍的樣品即使相機的分辨率是很小的? –

+1

理想情況下,您應該根據需要計算下采樣因子 - 您可以首先通過解碼邊界(這是選項參數中的一個選項)來檢查圖像的維度,然後可以計算出您需要的下采樣因子,然後對其進行解碼真正使用這個因素。看看顯示位圖課程(第一個鏈接),它具有真正有用的示例代碼。 –

2

告訴解碼器子樣本圖像,將較小的版本加載到內存中,在BitmapFactory.Options對象中將inSampleSize設置爲true。例如,分辨率爲2048x1536且用inSampleSize爲4解碼的圖像會生成大約512x384的位圖。將其加載到內存中時,對於完整映像使用0.75MB而不是12MB(假定ARGB_8888的位圖配置)。看到這個

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

public Bitmap decodeSampledBitmapFromResource(
    String pathName) { 
int reqWidth,reqHeight; 
reqWidth =Utils.getScreenWidth(); 
reqWidth = (reqWidth/5)*2; 
reqHeight = reqWidth; 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
// BitmapFactory.decodeStream(is, null, options); 
BitmapFactory.decodeFile(pathName, options); 
// Calculate inSampleSize 
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 
// Decode bitmap with inSampleSize set 
options.inJustDecodeBounds = false; 
return BitmapFactory.decodeFile(pathName, options); 
} 

    public int calculateInSampleSize(BitmapFactory.Options options, 
    int reqWidth, int reqHeight) { 
// Raw height and width of image 
final int height = options.outHeight; 
final int width = options.outWidth; 
int inSampleSize = 1; 

if (height > reqHeight || width > reqWidth) { 
    if (width > height) { 
    inSampleSize = Math.round((float) height/(float) reqHeight); 
    } else { 
    inSampleSize = Math.round((float) width/(float) reqWidth); 
    } 
} 
return inSampleSize; 
}