2017-04-19 63 views
-1

轉換爲字符串在我使用WhatsApp的像的圖像壓縮之後,我使用Base64編碼壓縮後的圖像位圖轉換爲字符串我的Android應用程序,我注意到的是,當我壓縮一個5MB的圖像,並將其保存在另一個位置它只是60KB或類似的和Base64編碼字符串正在500KB或600KB的同一圖像70KB的東西,爲什麼它的這樣呢?有什麼辦法將壓縮的圖像轉換爲字符串,其大小相同。下面是我的代碼。安卓:如何壓縮圖像與最小尺寸

Bitmap bitmapImg; 

    if (requestCode == FILE_SELECT_CODE) { 
     if(data!= null) { 
      try { 
       Uri selectedImageUri = data.getData(); 
       String mimeType = getContentResolver().getType(selectedImageUri); 

       compressImage(selectedImageUri); 

      // Converting compressed bitmap to string 
       ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); 
       bitmapImg.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS); 
       String strBitmap = Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT); 

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

    } 

    private String compressImage(Uri selImageUri) { 
     String fileStrName = null; 
     bitmapImg = null; 
     try { 
      String filePath = getRealPathFromURI(selImageUri); 
      BitmapFactory.Options options = new BitmapFactory.Options(); 

    //  by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If 
    //  you try the use the bitmap here, you will get null. 
      options.inJustDecodeBounds = true; 
      Bitmap bmpTemp = BitmapFactory.decodeFile(filePath, options); 

      int actualHeight = options.outHeight; 
      int actualWidth = options.outWidth; 

    //  max Height and width values of the compressed image is taken as 816x612 

      float maxHeight = 816.0f; 
      float maxWidth = 612.0f; 
      float imgRatio = actualWidth/actualHeight; 
      float maxRatio = maxWidth/maxHeight; 

    //  width and height values are set maintaining the aspect ratio of the image 

      if (actualHeight > maxHeight || actualWidth > maxWidth) { 
       if (imgRatio < maxRatio) { 
        imgRatio = maxHeight/actualHeight; 
        actualWidth = (int) (imgRatio * actualWidth); 
        actualHeight = (int) maxHeight; 
       } else if (imgRatio > maxRatio) { 
        imgRatio = maxWidth/actualWidth; 
        actualHeight = (int) (imgRatio * actualHeight); 
        actualWidth = (int) maxWidth; 
       } else { 
        actualHeight = (int) maxHeight; 
        actualWidth = (int) maxWidth; 
       } 
      } 

    //  setting inSampleSize value allows to load a scaled down version of the original image 

      options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); 
    //  inJustDecodeBounds set to false to load the actual bitmap 

      options.inJustDecodeBounds = false; 

    //  this options allow android to claim the bitmap memory if it runs low on memory 

      options.inPurgeable = true; 
      options.inInputShareable = true; 
      options.inTempStorage = new byte[16 * 1024]; 

      try { 
    //   load the bitmap from its path 

       bmpTemp = BitmapFactory.decodeFile(filePath, options); 
      } catch (OutOfMemoryError exception) { 
       exception.printStackTrace(); 
      } 
      try { 
       bitmapImg = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); 
      } catch (OutOfMemoryError exception) { 
       exception.printStackTrace(); 
      } 

      float ratioX = actualWidth/(float) options.outWidth; 
      float ratioY = actualHeight/(float) options.outHeight; 
      float middleX = actualWidth/2.0f; 
      float middleY = actualHeight/2.0f; 

      Matrix scaleMatrix = new Matrix(); 
      scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); 

      Canvas canvas = new Canvas(bitmapImg); 
      canvas.setMatrix(scaleMatrix); 
      canvas.drawBitmap(bmpTemp, middleX - bmpTemp.getWidth()/2, middleY - bmpTemp.getHeight()/2, new Paint(Paint.FILTER_BITMAP_FLAG)); 

    //  check the rotation of the image and display it properly 

      ExifInterface exif; 
      try { 
       exif = new ExifInterface(filePath); 

       int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); 
       Matrix matrix = new Matrix(); 
       if (orientation == 6) { 
        matrix.postRotate(90); 
       } else if (orientation == 3) { 
        matrix.postRotate(180); 
       } else if (orientation == 8) { 
        matrix.postRotate(270); 
       } 
       bitmapImg = Bitmap.createBitmap(bitmapImg, 0, 0, bitmapImg.getWidth(), bitmapImg.getHeight(), matrix, true); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      FileOutputStream out = null; 
      String filename = getFilename(); 
      try { 
       out = new FileOutputStream(filename); 

    //   write the compressed bitmap at the destination specified by filename. 
       bitmapImg.compress(Bitmap.CompressFormat.JPEG, 80, out); 

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

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

     return fileStrName; 
    } 

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

     if (height > reqHeight || width > reqWidth) { 
      final int heightRatio = Math.round((float) height/ (float) reqHeight); 
      final int widthRatio = Math.round((float) width/(float) reqWidth); 
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
     } 
     final float totalPixels = width * height; 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 
     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 

     return inSampleSize; 
    } 

    private String getRealPathFromURI(Uri contentUri) { 
     Cursor cursor = getContentResolver().query(contentUri, null, null, null, null); 
     if (cursor == null) { 
      return contentUri.getPath(); 
     } else { 
      cursor.moveToFirst(); 
      int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
      return cursor.getString(index); 
     } 
    } 

    public String getFilename() { 
     File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images"); 
     if (!file.exists()) { 
      file.mkdirs(); 
     } 
     String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg"); 
     return uriSting; 

    } 

這裏的壓縮圖像的大小爲60KB或70KB的,但是當我strBitmap保存到數據庫其採取500KB或600kb.How我可以轉換壓縮位具有相同大小的字符串。

+0

看看這個:http://stackoverflow.com/questions/11402329/base64-encoded-image-size –

+1

@FAЯAƸ但它有說它的大約37%,但它不像我的情況.. – KJEjava48

+0

當前,你有一個**純字符串**,這意味着每個字節加權一個完整的字節。嘗試**壓縮它**(不知何故壓縮它)。你會恢復丟失的壓縮(字符串是高度comprimible)。 –

回答

2

有沒有在你的圖像一個很大的不同,雖然。

您存儲爲文件的圖像保存爲JPEG

bitmapImg.compress(Bitmap.CompressFormat.JPEG, 80, out); 

而Base64編碼字符串是一個PNG

bitmapImg.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS); 

這可以解釋的大小差異。另一件事可能是,bitmapImg也改變了它在兩次壓縮之間的內容。

+0

png和jpeg格式有那麼大的尺寸差異嗎? – KJEjava48

+0

他們可以有這麼大的差異。也可能發生JPG比PNG更大的情況。但是從5MB開始,這不太可能。 – tynn

+0

那麼如何將PNG格式的位圖轉換爲小尺寸的字符串? – KJEjava48