2017-04-19 6 views
-1

私のAndroidアプリケーションでは、画像圧縮のようなwhatsappを使用しています。その後、圧縮された画像ビットマップをBase64エンコーディングを使用して文字列に変換します。 5メガバイトの画像を保存し、それを60kbまたは70kbの別の場所に保存し、Base64でエンコードされた文字列は500kbまたは600kbの同じ画像を撮影しています。圧縮された画像を同じサイズの文字列に変換する方法はありますか?下は私のコードです。Android:圧縮された画像を最小サイズの文字列に変換する方法

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; 

    } 

ここで圧縮された画像は、サイズが60キロバイトまたは70キロバイトのですが、私は、データベースにその撮影500キロバイトまたは600kb.HowをstrBitmapを保存するとき、私は文字列に同じサイズで圧縮されたビットマップを変換することができます。

+0

これをチェックしてください:http://stackoverflow.com/questions/11402329/base64-encoded-image-size –

+1

@FAЯAƸしかし、それは約37%大きいと言いますが、それは私の場合はそうではありません。 – KJEjava48

+0

現在**単純な文字列**を持っています。つまり、各バイトは1バイトで重み付けされています。試してみてください**圧縮**(それは何とかそれをクランチしないでください)。失われた圧縮を取り戻すことができます(文字列は非常に妥協できます)。 –

答えて

2

あなたのイメージには大きな違いがあります。

Base64でエンコードされた文字列は、PNG

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

これは、サイズの違いを説明することができているときにファイルとして保存した画像はJPEG

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

として格納されています。もう1つのことは、bitmapImgが両方の圧縮の間でその内容を変更したということです。

+0

png形式とjpeg形式のサイズの違いはありますか? – KJEjava48

+0

大きなサイズの違いがあります。 JPGがPNGより大きい場合もあります。しかし、あなたの5MBを起動すると、それはあまり起こりそうもありません。 – tynn

+0

どうすればPNG形式のビットマップを小さなサイズの文字列に変換できますか? – KJEjava48

関連する問題