2013-12-16 192 views
3

在這裏,我將拍攝的圖像從攝像頭保存到SD卡上。這裏,拍攝的圖像尺寸大於1 MB。在保存到SD卡之前,我想將這個大小減小到接近500kb到600kb。我怎麼能這樣做?在android中減少攝像頭拍攝圖像的尺寸

try 
     { 
      Bitmap mPhoto; 
      mPhoto = android.provider.MediaStore.Images.Media.getBitmap(cr, CheckInGallery.mUri); 
      ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
      mPhoto.compress(Bitmap.CompressFormat.PNG, 100, bytes); 

      File direct = new File(Environment.getExternalStorageDirectory() + "/RetailRun"); 
      String mydate = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()); 
      Toast.makeText(getBaseContext(), "Time :" + mydate, 5000).show(); 

      if(!direct.exists()) 
      { 
       direct.mkdir(); 
       File file = new File(Environment.getExternalStorageDirectory()+File.separator + "/MyImage/image" + mydate +".jpg"); 
       file.createNewFile(); 
       FileOutputStream fo = new FileOutputStream(file); 
       fo.write(bytes.toByteArray()); 
       fo.close(); 
      } 

     else 
      { 
       File file = new File(Environment.getExternalStorageDirectory()+File.separator + "/MyImage/image" + mydate +".jpg"); 
       file.createNewFile(); 
       FileOutputStream fo = new FileOutputStream(file); 
       fo.write(bytes.toByteArray()); 
       fo.close(); 
      } 



     } 

     catch (Exception e) 
     { 
      Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 

回答

1
mPhoto.compress(Bitmap.CompressFormat.PNG, 100, bytes); 

在這個100是質量最好的。如果你想減小尺寸,然後嘗試去除該值

其他方式可能是使用inSampleSize參數BitmapFactory.Options()。這也應該減小尺寸。您可以閱讀緊靠該here

編輯: 一些代碼

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize=2; //4, 8, etc. the more value, the worst quality of image 

Bitmap bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(CheckInGallery.mUri), null, options); 

這應該加載圖像與小質量差。

然後保存圖像

bmp.compress(Bitmap.CompressFormat.PNG, 70, bytes); 
+0

意味着我應該嘗試少於100像80或70? –

+0

是的,這應該有幫助 – Gooziec

+0

Gooziec:你好,仍然我得到相同的圖像大小,> 1 MB ... –

0

設定的高度和位圖的寬度爲特定設備...

@SuppressLint("NewApi") 
    public static int getDeviceWidth(Activity activity) { 
     int deviceWidth = 0; 

     Point size = new Point(); 
     WindowManager windowManager = activity.getWindowManager(); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      windowManager.getDefaultDisplay().getSize(size); 
      deviceWidth = size.x; 
     } else { 
      Display display = windowManager.getDefaultDisplay(); 
      deviceWidth = display.getWidth(); 
     } 
     return deviceWidth; 
    } 

    @SuppressLint("NewApi") 
    public static int getDeviceHeight(Activity activity) { 
     int deviceHeight = 0; 

     Point size = new Point(); 
     WindowManager windowManager = activity.getWindowManager(); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      windowManager.getDefaultDisplay().getSize(size); 
      deviceHeight = size.y; 
     } else { 
      Display display = windowManager.getDefaultDisplay(); 
      deviceHeight = display.getHeight(); 
     } 
     return deviceHeight; 
    } 

這種方法縮小圖像尺寸。其在我的項目工作。

+0

請看看這個問題:http://stackoverflow.com/questions/31646619/captured-image-resolution-is-too-big – Sophie

0
**Reduce captured image size and save ..in kb** 
String imagePath = context.getFilesDir().getAbsolutePath() + File.separatorChar + "FolderName" + File.separatorChar + "ImageFolder" + File.separatorChar + imageName + ".jpg"; 


File prescImagefile = new File(imagePath); 

try 
     { 
      if (prescImagefile.exists() == false) 
      { 
       prescImagefile.getParentFile().mkdirs(); 
       prescImagefile.createNewFile(); 

      } 
     } 
     catch (IOException e) 
     { 
      // Log.e("TAG", "Could not create file.", e); 
     } 
if (prescImagefile != null) 
     { 
      mCapturedImageURI = Uri.fromFile(prescImagefile); 
      if (mCapturedImageURI != null) 
      { 
       Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI); 
       startActivityForResult(cameraIntent, CAMERA_REQUEST); 
      } 
     } 
@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    { 
     if (resultCode == RESULT_OK) 
     { 
      if (requestCode == CAMERA_REQUEST) 
      { 
       try 
       { 
        String path = mCapturedImageURI.getPath(); 
        StoreImage(context, mCapturedImageURI, prescImagefile); 

       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 

      } 

     } 

    } 
public static void StoreImage(Context mContext, Uri imgUri, File imageDir) 
    { 
     Bitmap bm = null; 
     try 
     { 
      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inSampleSize = 2; 
      // bm = Media.getBitmap(mContext.getContentResolver(), imageLoc); 
      bm = BitmapFactory.decodeStream(mContext.getContentResolver().openInputStream(imgUri), null, options); 
      FileOutputStream out = new FileOutputStream(imageDir); 
      bm.compress(Bitmap.CompressFormat.JPEG, 20, out); 
      bm.recycle(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

    } 
0

在閱讀其他答案並沒有準確找到我想要的內容之後,我的方法是獲取適當縮放的位圖。這是Prabu答案的改編。

它可以確保您的圖片是在不變形的照片尺寸的方式縮放:

public saveScaledPhotoToFile() { 
    //Convert your photo to a bitmap 
    Bitmap photoBm = (Bitmap) "your Bitmap image"; 
    //get its orginal dimensions 
    int bmOriginalWidth = photoBm.getWidth(); 
    int bmOriginalHeight = photoBm.getHeight(); 
    double originalWidthToHeightRatio = 1.0 * bmOriginalWidth/bmOriginalHeight; 
    double originalHeightToWidthRatio = 1.0 * bmOriginalHeight/bmOriginalWidth; 
    //choose a maximum height 
    int maxHeight = 1024; 
    //choose a max width 
    int maxWidth = 1024; 
    //call the method to get the scaled bitmap 
    photoBm = getScaledBitmap(photoBm, bmOriginalWidth, bmOriginalHeight, 
      originalWidthToHeightRatio, originalHeightToWidthRatio, 
      maxHeight, maxWidth); 

    /**********THE REST OF THIS IS FROM Prabu's answer*******/ 
    //create a byte array output stream to hold the photo's bytes 
    ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
    //compress the photo's bytes into the byte array output stream 
    photoBm.compress(Bitmap.CompressFormat.JPEG, 40, bytes); 

    //construct a File object to save the scaled file to 
    File f = new File(Environment.getExternalStorageDirectory() 
      + File.separator + "Imagename.jpg"); 
    //create the file 
    f.createNewFile(); 

    //create an FileOutputStream on the created file 
    FileOutputStream fo = new FileOutputStream(f); 
    //write the photo's bytes to the file 
    fo.write(bytes.toByteArray()); 

    //finish by closing the FileOutputStream 
    fo.close(); 
} 

private static Bitmap getScaledBitmap(Bitmap bm, int bmOriginalWidth, int bmOriginalHeight, double originalWidthToHeightRatio, double originalHeightToWidthRatio, int maxHeight, int maxWidth) { 
    if(bmOriginalWidth > maxWidth || bmOriginalHeight > maxHeight) { 
     Log.v(TAG, format("RESIZING bitmap FROM %sx%s ", bmOriginalWidth, bmOriginalHeight)); 

     if(bmOriginalWidth > bmOriginalHeight) { 
      bm = scaleDeminsFromWidth(bm, maxWidth, bmOriginalHeight, originalHeightToWidthRatio); 
     } else if (bmOriginalHeight > bmOriginalWidth){ 
      bm = scaleDeminsFromHeight(bm, maxHeight, bmOriginalHeight, originalWidthToHeightRatio); 
     } 

     Log.v(TAG, format("RESIZED bitmap TO %sx%s ", bm.getWidth(), bm.getHeight())); 
    } 
    return bm; 
} 

private static Bitmap scaleDeminsFromHeight(Bitmap bm, int maxHeight, int bmOriginalHeight, double originalWidthToHeightRatio) { 
    int newHeight = (int) Math.max(maxHeight, bmOriginalHeight * .55); 
    int newWidth = (int) (newHeight * originalWidthToHeightRatio); 
    bm = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true); 
    return bm; 
} 

private static Bitmap scaleDeminsFromWidth(Bitmap bm, int maxWidth, int bmOriginalWidth, double originalHeightToWidthRatio) { 
    //scale the width 
    int newWidth = (int) Math.max(maxWidth, bmOriginalWidth * .75); 
    int newHeight = (int) (newWidth * originalHeightToWidthRatio); 
    bm = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true); 
    return bm; 
} 

這裏有一個對應的鏈接到我的GitHub的要點是:https://gist.github.com/Lwdthe1/2d1cd0a12f30c18db698

0

這是什麼工作我。

public void onImageSelected(){ 
    Uri uri=null; // get the uri of the image result from the intent 
    try { 

     Bitmap bitmap = handleSamplingAndRotationBitmap(this, uri); 
     byte[] bytes = getBytesFromBitmap(bitmap); 
     //getPresenter.upload(bytes); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 


/** 
* returns an aligned bitmap with size not exceeding the MAX_HEIGHT 
* @param context 
* @param selectedImage 
* @return 
* @throws IOException 
*/ 
public Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage) 
     throws IOException { 
    Bitmap decoded = getImageSampleOutput(context,selectedImage); 
    decoded = rotateImageIfRequired(this, decoded, selectedImage); 
    return decoded; 
} 

public Bitmap getImageSampleOutput(Context context, Uri selectedImage) throws IOException { 
    int MAX_HEIGHT = 1200; 
    int MAX_WIDTH = 1600; 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    InputStream imageStream = context.getContentResolver().openInputStream(selectedImage); 
    BitmapFactory.decodeStream(imageStream, null, options); 
    imageStream.close(); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT); 
    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    imageStream = context.getContentResolver().openInputStream(selectedImage); 
    Bitmap img = BitmapFactory.decodeStream(imageStream, null, options); 
    Bitmap decoded = compressImage(img); 
    return decoded; 
} 


/** 
* Used to compress the image to prevent any Memory overflows. 
* @param bitmap 
* @return 
*/ 
public Bitmap compressImage(Bitmap bitmap) { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 
    return BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); 
} 


private static 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) { 

     // Calculate ratios of height and width to requested height and width 
     final int heightRatio = Math.round((float) height/(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will guarantee a final image 
     // with both dimensions larger than or equal to the requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 

     // This offers some additional logic in case the image has a strange 
     // aspect ratio. For example, a panorama may have a much larger 
     // width than height. In these cases the total pixels might still 
     // end up being too large to fit comfortably in memory, so we should 
     // be more aggressive with sample down the image (=larger inSampleSize). 

     final float totalPixels = width * height; 

     // Anything more than 2x the requested pixels we'll sample down further 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 

     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 
    } 
    return inSampleSize; 
} 

private static Bitmap rotateImageIfRequired(Context context, Bitmap img, Uri selectedImage) { 

    // Detect rotation 
    int rotation = getRotation(context, selectedImage); 
    if (rotation != 0) { 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(rotation); 
     Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true); 
     img.recycle(); 
     return rotatedImg; 
    } else { 
     return img; 
    } 
} 

/** 
* Get the rotation of the last image added. 
* 
* @param context 
* @param selectedImage 
* @return 
*/ 
private static int getRotation(Context context, Uri selectedImage) { 

    int rotation = 0; 
    ContentResolver content = context.getContentResolver(); 

    Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
      new String[]{"orientation", "date_added"}, 
      null, null, "date_added desc"); 

    if (mediaCursor != null && mediaCursor.getCount() != 0) { 
     while (mediaCursor.moveToNext()) { 
      rotation = mediaCursor.getInt(0); 
      break; 
     } 
    } 
    mediaCursor.close(); 
    return rotation; 
} 

public byte[] getBytesFromBitmap(Bitmap bmp){ 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    bmp.compress(Bitmap.CompressFormat.JPEG,70,stream); 
    byte[] byteArray = stream.toByteArray(); 
    return byteArray; 
} 

在Samusung Galaxy S7上,我能夠縮小到300kb。

+0

有時Samusung Galaxy S7用於減少零件所以我們應該在減小尺寸之前檢查一個條件以限制最小尺寸... –