public File compress(@NonNull File file, long maxsize) throws IOException, NullPointerException, IllegalArgumentException {
        if (!file.exists()) {
            throw new IllegalArgumentException("file not found : " + file.getAbsolutePath());
        }
        if (!isLegalFile(file)) {
            throw new IllegalArgumentException("file is not a legal file : " + file.getAbsolutePath());
        }
        if (mOutFileFile == null) {
            throw new NullPointerException("the external cache dir is null");
        }
        BitmapFactory.Options checkOptions = new BitmapFactory.Options();
        checkOptions.inJustDecodeBounds = true;
        String absPath = file.getAbsolutePath();
        int angle = BoxingExifHelper.getRotateDegree(absPath);
        BitmapFactory.decodeFile(absPath, checkOptions);

        if (checkOptions.outWidth <= 0 || checkOptions.outHeight <= 0) {
            throw new IllegalArgumentException("file is not a legal bitmap with 0 with or 0 height : " + file.getAbsolutePath());
        }
        int width = checkOptions.outWidth;
        int height = checkOptions.outHeight;
        File outFile = createCompressFile(file);
        if (outFile == null) {
            throw new NullPointerException("the compressed file create fail, the compressed path is null.");
        }
        if (!isLargeRatio(width, height)) {
            int[] display = getCompressDisplay(width, height);
            Bitmap bitmap = compressDisplay(absPath, display[0], display[1]);
            Bitmap rotatedBitmap = rotatingImage(angle, bitmap);
            if (bitmap != rotatedBitmap) {
                bitmap.recycle();
            }
            saveBitmap(rotatedBitmap, outFile);
            rotatedBitmap.recycle();
            compressQuality(outFile, maxsize, 20);
        } else {
            if (checkOptions.outHeight >= MAX_HEIGHT && checkOptions.outWidth >= MAX_WIDTH) {
                checkOptions.inSampleSize = 2;
            }
            checkOptions.inJustDecodeBounds = false;
            Bitmap originBitmap = BitmapFactory.decodeFile(absPath, checkOptions);
            Bitmap rotatedBitmap = rotatingImage(angle, originBitmap);
            if (originBitmap != rotatedBitmap) {
                originBitmap.recycle();
            }
            saveBitmap(originBitmap, outFile);
            rotatedBitmap.recycle();
            compressQuality(outFile, MAX_LIMIT_SIZE_LONG, 50);
        }
        BoxingLog.d("compress suc: " + outFile.getAbsolutePath());
        return outFile;
    }
@param file file to compress.
@param maxsize the proximate max size for compression, not for the image with large ratio.
@return may be a little bigger than expected for performance.
boxing/src/main/java/com/bilibili/boxing/utils/ImageCompressor.java