document.write("");

ZXING 修复预览页面变形问题

ZXING之前都用的好好的,结果在一个Android11的设备上翻了车 (基于全屏预览的情况下)

扫码页面预览效果变形,

在网上找了一些代码,修改后发现无效,不适用我这边的设备,

最后想着,预览结果变形,就是预览Size用的不太对,最后找到了调整预览Size的方法,修改了一下,经测试,Android 11 Android 7都正常显示

先全局搜索一下代码, findBestPreviewSizeValue 该方法是获取最佳预览Size的方法 

ZXING

private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {
        Point res = Util.getPoint(previewSizeValueString);
        if (null != res) {
            return res;
        }
        return null;
    }

相关工具类方法

/**
     * 获取最佳分辨率
     */
    public static Point getPoint(CharSequence previewSizeValueString) {
        Pattern COMMA_PATTERN = Pattern.compile(",");
        String[] lists = COMMA_PATTERN.split(previewSizeValueString);
        Size[] querys = new Size[lists.length];
        int i = 0;
        for (String data: lists ) {
            String[] datas = data.split("x");
            int width =   Integer.parseInt(datas[1]);
            int height =   Integer.parseInt(datas[0]);
            Size size = new Size(width,height);
            querys[i] = size;
            i++;
        }
        int width = Util.getScreenSize(context, true)[0];
        int height = Util.getScreenSize(context, true)[1];
        Size size = Util.chooseSize(querys,querys, width,height);
        Point point = new Point(size.getHeight(), size.getWidth());
        return point;
    }
    
    
     /**
     * 获取屏幕的宽高,(此方法来自于 autolayout)
     */
    public static int[] getScreenSize(Context context, boolean useDeviceSize) {
        int[] size = new int[2];
        WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display d = w.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        d.getMetrics(metrics);
        int widthPixels = metrics.widthPixels;
        int heightPixels = metrics.heightPixels;

        if (!useDeviceSize) {
            size[0] = widthPixels;
            size[1] = heightPixels - getStatusBarHeight(context);

            return size;
        }
        if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
            try {
                widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
                heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
            } catch (Exception ignored) {
            }
        if (Build.VERSION.SDK_INT >= 17)
            try {
                Point realSize = new Point();
                Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
                widthPixels = realSize.x;
                heightPixels = realSize.y;
            } catch (Exception ignored) {
            }
        size[0] = widthPixels;
        size[1] = heightPixels;
        return size;
    }
    
      /**
     * 获取状态栏高度,(此方法来自于 autolayout)
     */
    public static int getStatusBarHeight(Context context) {
        int result = 0;
        try {
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = context.getResources().getDimensionPixelSize(resourceId);
            }
        } catch (Resources.NotFoundException e) {
            e.printStackTrace();
        }
        return result;
    }
    
     /**
     * Camera 获取合适的尺寸(如果有相同尺寸,优先选择)
     */
    public static Size chooseSize(Size[] preChoices, Size[] picChoices, int width, int height) {
        // Collect the supported resolutions that are at least as big as the preview Surface
        List<Size> choices = new ArrayList<>();
        // 部分设备 预览与拍照的分辨率不一致,故先获取一致的分辨率
        for (Size pre: preChoices) {
            for (Size pic: picChoices ) {
                if (pre.getHeight() == pic.getHeight() && pre.getWidth() == pic.getWidth()) {
                    choices.add(pre);
                }
            }
        }
        if (choices.size() == 0) {
            return preChoices[0];
        }
        int ReqTmpWidth = width;
        int ReqTmpHeight = height;
        //先查找preview中是否存在与surfaceview相同宽高的尺寸
        for (Size size : choices) {
            if ((size.getWidth() == ReqTmpWidth) && (size.getHeight() == ReqTmpHeight)) {
                return size;
            }
        }
        // 获取与传入的宽高比最接近的size
        float reqRatio = ((float) ReqTmpWidth) / ReqTmpHeight;
        float curRatio, deltaRatio;
        float deltaRatioMin = Float.MAX_VALUE;
        Size retSize = null;
        for (Size size : choices) {
            curRatio = ((float) size.getWidth()) / size.getHeight();
            deltaRatio = Math.abs(reqRatio - curRatio);
            if (deltaRatio < deltaRatioMin) {
                deltaRatioMin = deltaRatio;
                retSize = size;
            }
        }
        return retSize != null ? retSize : choices.get(0);
    }

 

posted @ 2021-12-17 10:48  人间春风意  阅读(186)  评论(0编辑  收藏  举报