2016-04-28 19 views
0

私はカスタムカメラから撮影した画像を圧縮するのにWhatsapp like image compression codeを使用しています。後の圧縮圧縮画像がぼやけて見える

画像は、かすんで(少しフェードアウト)に見える、それはサイズ

Compress.java

public Bitmap compressImage(String imageUri) { 

       String filePath = getRealPathFromURI(imageUri); 
       Bitmap scaledBitmap = null; 

       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 bmp = 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 
         bmp = BitmapFactory.decodeFile(filePath, options); 
       } catch (OutOfMemoryError exception) { 
         exception.printStackTrace(); 

       } 
       try { 
         scaledBitmap = 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(scaledBitmap); 
       canvas.setMatrix(scaleMatrix); 
       canvas.drawBitmap(bmp, middleX - bmp.getWidth()/2, middleY - bmp.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); 
         Log.d("EXIF", "Exif: " + orientation); 
         Matrix matrix = new Matrix(); 
         if (orientation == 6) { 
           matrix.postRotate(90); 
           Log.d("EXIF", "Exif: " + orientation); 
         } else if (orientation == 3) { 
           matrix.postRotate(180); 
           Log.d("EXIF", "Exif: " + orientation); 
         } else if (orientation == 8) { 
           matrix.postRotate(270); 
           Log.d("EXIF", "Exif: " + orientation); 
         } 
         scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, 
           scaledBitmap.getWidth(), scaledBitmap.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. 
         scaledBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 

       } catch (FileNotFoundException e) { 
         e.printStackTrace(); 
       } 
       return getCompressesBitmap(filename); 
     } 

     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; 

     } 

     private String getRealPathFromURI(String contentURI) { 
       Uri contentUri = Uri.parse(contentURI); 
       Cursor cursor = mContext.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 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; 
     } 

     public Bitmap getCompressesBitmap(String path) { 
       Bitmap bitmapImage = BitmapFactory.decodeFile(path); 
       int nh = (int) (bitmapImage.getHeight() * (512.0/bitmapImage.getWidth())); 
       Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true); 
       return scaled; 
     } 

これまでの任意の解決策とともに、その品質を緩めているように見えますか?

答えて

1

あなたのカメラの画像はすでに圧縮されていると思います。圧縮コードが正常に機能したので、カスタムカメラで高品質の画像キャプチャを設定します。私はそれをテストしました。

+0

no。私のカメラの画像サイズは3 MB以上です。圧縮されていないことを意味します –

+0

私のコードを投稿します –

+0

投稿してください:) –

0

上記のソリューションで変更できるものは、縮小画像の幅と高さのハードコードされた値です。あなたのアプリのSharedPreferencesでアプリが起動するたびに、電話の幅と高さをピクセル単位で保存する関数を作成してみてください。スケールダウンされたビットマップの幅と高さを設定するコードでは、これらの値を使用してください。これにより、メモリ不足の例外を発生させずに最良の圧縮を実行することなく、デバイスのハードウェア仕様に応じて最適な縮尺でイメージが表示されます。

+0

私はscaledBitmap.compress(Bitmap.CompressFormat.JPEG、80、out)を変更しました。これをscaledBitmap.compress(Bitmap.CompressFormat.PNG、100、out)に設定します。 。どんな違いが反映されるべきですか? –

+0

PNG形式の画像を圧縮することは、PNGがロスレスであるため役に立ちません。 –

+0

画面のサイズと利用可能なピクセル数の観点からビットマップ圧縮を行う必要があります。 –

関連する問題