Android代码实现 px和mm相互转换,DPI的计算

最近做一个修改图片大小的功能,要求图片的宽度和高度单位可用px,也可用mm,这时需要用到px和mm相互转换。

第一步:px和mm之间转换首先要计算出屏幕的dpi ,

参考文章https://www.cnblogs.com/mixiyou/archive/2013/03/13/2957810.html

DPI计算公式:DPI = 宽 / ((尺寸2 × 宽2) / (宽2 + 高2))1/2 = 长 / ((尺寸2 × 高2) / (宽2 + 高2))1/2

/**
     * 获取DPI,图像每英寸长度内的像素点数
     * DPI = 宽 / ((尺寸2 × 宽2) / (宽2 + 高2))1/2 = 长 / ((尺寸2 × 高2) / (宽2 + 高2))1/2
     * @return
     */
    public float getDPI() {
        //获取屏幕尺寸
        double screenSize = ScreenInchUtils.getScreenInch(activity);
       //获取宽高大小
        int widthPx=activity.getResources().getDisplayMetrics().widthPixels;
        int heightPx=activity.getResources().getDisplayMetrics().heightPixels;
        float dpi=(float)(widthPx/Math.sqrt((screenSize*screenSize*widthPx*widthPx)/(widthPx*widthPx+heightPx*heightPx)));
        return dpi;
    }

计算出dpi后可以用下面的转换方式

1、输入以px为单位的值得到mm

 //px转毫米
    public int pxWidthToMm(int value) {
        orignWidth=value;
        float inch = value / getDPI();
        int c_value = (int)(inch * 25.4f);
        return c_value;
    }

    //px转毫米
    public int pxHeightToMm(int value) {
        orignHeight=value;
        float inch = value / getDPI();
        int c_value = (int)(inch * 25.4f);
        return c_value;
    }

2、mm 转px(不要急,注意看下面的解释和改变的方法)

 //毫米转px
    public int mmToPx(int value) {
        float inch = value / 25.4f;
        int c_value = (int)(inch * getDPI());
        return c_value;
    }

注意:使用mmToPx这种方式,会发现每次切换值都在变化,是因为小数点转成了int ,再从int计算为float会有误差。为了避免值不断切换,我添加了orignWidth和orignHeight两个参数用来记录初始值,并将mm转px的方法改变为如下:

 public int mmWidthToPx(){
        return orignWidth;
    }

    public int mmHeightToPx(){
        return orignHeight;
    }

获取屏幕尺寸的ScreenInchUtils:

public class ScreenInchUtils {
    private static double mInch = 0;

    public static double getScreenInch(Activity activity) {
        if (mInch != 0.0d) {
            return mInch;
        }

        try {
            int realWidth = 0, realHeight = 0;
            Display display = activity.getWindowManager().getDefaultDisplay();
            DisplayMetrics metrics = new DisplayMetrics();
            display.getMetrics(metrics);
            if (Build.VERSION.SDK_INT >= 17) {
                Point size = new Point();
                display.getRealSize(size);
                realWidth = size.x;
                realHeight = size.y;
            } else if (Build.VERSION.SDK_INT < 17
                    && Build.VERSION.SDK_INT >= 14) {
                Method mGetRawH = Display.class.getMethod("getRawHeight");
                Method mGetRawW = Display.class.getMethod("getRawWidth");
                realWidth = (Integer) mGetRawW.invoke(display);
                realHeight = (Integer) mGetRawH.invoke(display);
            } else {
                realWidth = metrics.widthPixels;
                realHeight = metrics.heightPixels;
            }

            mInch = formatDouble(Math.sqrt((realWidth / metrics.xdpi) * (realWidth / metrics.xdpi) + (realHeight / metrics.ydpi) * (realHeight / metrics.ydpi)), 1);


        } catch (Exception e) {
            e.printStackTrace();
        }

        return mInch;
    }


    /**
     * Double类型保留指定位数的小数,返回double类型(四舍五入)
     * newScale 为指定的位数
     */
    public static double formatDouble(double d, int newScale) {
        BigDecimal bd = new BigDecimal(d);
        return bd.setScale(newScale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值