2012-12-10 102 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; 
}