【问题标题】:Compress image android压缩图像android
【发布时间】:2017-12-11 14:35:32
【问题描述】:


我有一个应用程序,您可以在其中拍照或从图库中选择图像。 拍摄/选择一次的照片必须上传到服务器。
我的问题是,由于不同的设备具有不同的尺寸和分辨率,压缩后的图像应该加载到服务器上的原始尺寸还是应该放大然后压缩?
为所有设备缩放图像的最佳方法是什么?

现在当用户通过相机或画廊拍照时,我正在使用此算法

private void setPic() throws IOException {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, options);
        // Calculate inSampleSize
        int sampleSize = calculateInSampleSize(options, 720, 720);
        Log.d("UserPanel", "Samplesize: " + sampleSize);
        Log.d("SquareImage", ""+image.getWidth());
        options.inSampleSize = sampleSize;

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPreferredConfig= Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options);
        Log.d("UserPanel", "Bytebitmap: " + bitmap.getByteCount());
        ExifInterface exif = new ExifInterface(mCurrentPhotoPath);
        String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;

        int rotationAngle = 0;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;

        Matrix matrix = new Matrix();
        matrix.setRotate(rotationAngle, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, options.outWidth, options.outHeight, matrix, true);
        Log.d("UserPanel", "Bytebitmaprotate: " + rotatedBitmap.getByteCount());
        MediaStore.Images.Media.insertImage(getContentResolver(), rotatedBitmap, imageFileName, "");
        File fdelete = new File(mCurrentPhotoPath);
        if (fdelete.delete()) Log.d("UserPanel", "Delete");
        imageToServer = getStringImage(rotatedBitmap);
    }

这是calculateSampleSize

public 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;
        Log.d("UserPanel", "Width: " + width + " height: " + height);
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

为了压缩图像,我将大小固定为 100KB

private String getStringImage(Bitmap bmp) {
        int compressQuality = 100;
        int streamLength = 0;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        do{
            ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
            Log.d("compressBitmap", "Quality: " + compressQuality);
            bmp.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream);
            byte[] bmpPicByteArray = bmpStream.toByteArray();
            streamLength = bmpPicByteArray.length;
            compressQuality -= 5;
            Log.d("compressBitmap", "Size: " + streamLength/1024+" kb");
        }while (streamLength >= 100000);
        bmp.compress(Bitmap.CompressFormat.JPEG, compressQuality, baos);
        byte[] imageBytes = baos.toByteArray();
        Log.d("UserPanel", "Bytebitmap compress: " + imageBytes.length);
        String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
        return encodedImage;
    }

【问题讨论】:

    标签: android image scaling image-scaling image-compression


    【解决方案1】:

    尝试使用此类压缩图像

    import android.content.Context;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.media.ExifInterface;
    import android.net.Uri;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.util.Log;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    public class CompressImage {
    
        Context mContext;
    
        public CompressImage(Context context) {
            this.mContext = context;
        }
    
        public String compressImage(String imageUri) throws IOException {
    
            String filePath = getRealPathFromURI(imageUri);
            if(filePath == null)
            {
                filePath = 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 = imageUri;
            File oldfile = new File(imageUri);
            if (oldfile.exists()) {
                oldfile.delete();
            }
            try {
                out = new FileOutputStream(filename);
    
    //          write the compressed bitmap at the destination specified by filename.
                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            return filename;
    
        }
    
        public String getFilename() throws IOException {
    //        File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
    //        if (!file.exists()) {
    //            file.mkdirs();
    //        }
    //        String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
    
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                    .format(new Date());
            String imageFileName = "twice_" + timeStamp + "_";
            File storageDir = Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            File image = File.createTempFile(imageFileName, /* prefix */
                    ".jpg", /* suffix */
                    storageDir /* directory */
            );
    
    //        ChatRoomFragment.picturePath= image.getAbsolutePath();
            return image.getAbsolutePath();
    
        }
    
        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;
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      相关资源
      最近更新 更多