移动互联网开发教学案例学习-11

2021SC@SDUSC

目录

案例——draw_compare

scaleBitmap方法

isLookLikePaintColor方法

checkNearItemIsHit方法

isOutSide方法


案例——draw_compare

scaleBitmap方法

    public static Bitmap scaleBitmap(Bitmap target, int w, int h) {
        if (target == null || target.isRecycled()) return target;
        int width = target.getWidth(), height = target.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(((float) w / width), ((float) h / height));
        return Bitmap.createBitmap(target, 0, 0, width, height, matrix, true);
    }

该方法用于目标bitmap进行缩放。参数target为目标bitmap,w为新的宽度,h为新的高度,返回值为缩放后的bitmap。 

这里首先要进行判断,判断target是否为空,以及是否已经被回收,如果是,则直接返回target。否则,则进行下面的操作。实例化width为target的宽,height为target的高。创建一个新的Matrix对象,通过调用matrix的postScale方法完成对图像的缩放。

Android matrix.postScale的用法:

public boolean postScale(float sx,float sy,float px,float py)

者个api的第一个参数sx是x轴的缩放大小,第二个参数sy是y轴的缩放大小,px、py是缩放的中心位置。 这个中心点不一定在图片的中心位置,有可能在图片的外面。例如下面的图中:

我们现在用到的是只有前两个参数的形式,较为简单。

 除了postScale之外,还有preScale、setScale两个操作。它们在内部都是通过修改MSCALE_X、MSCALE_Y来实现的。那么它们有什么区别呢?

1)setScale(sx,sy),首先会将该Matrix设置为对角矩阵,即相当于调用reset()方法,然后再设置该Matrix的MSCALE_X和MSCALE_Y直接设置为sx,sy的值;

2)preSclae(sx,sy),不会重置Matrix,而是直接与Matrix之前的MSCALE_X和MSCALE_Y值结合起来(相乘),M'=M*S(sx,sy);

3)postScale(sx,sy),和preScale的操作一样。但是它们的执行顺序有区别。

isLookLikePaintColor方法

    private static boolean isLookLikePaintColor(int r, int g, int b) {
        for (int[] color : mPaintColors) {
            int dither = 10; //允许色值的抖动范围是10 (max = 255)
            int redDither = Math.abs(color[0] - r);
            int greenDither = Math.abs(color[1] - g);
            int blueDither = Math.abs(color[2] - b);
            if (redDither < dither && greenDither < dither && blueDither < dither)
                return true;
        }
        return false;
    }

该方法主要用于根据色值判断和目标颜色是否近似。如果色值得抖动小于10,就返回true。

Math.abs()方法返回参数的绝对值。

checkNearItemIsHit方法

    private static boolean checkNearItemIsHit(int nearCount, int[][] targetPixels, Point currentPos) {
        //先初始化数据
        int length = nearCount * 2 + 1;
        int[][] state = new int[length][length];
        int verticalCount = targetPixels.length;
        int horizontalCount = targetPixels[0].length;

        Queue<Point> queue = new ArrayDeque<>(); //这个是应该查找的点的队列
        queue.offer(new Point(nearCount, nearCount)); //当前pos先入队
        state[nearCount][nearCount] = 1; //标记该点无效(已经被用过)
        while (!queue.isEmpty()) { //有任务未完成
            Point header = queue.poll(); //队头出队
            List<Point> directions = getCanArrivePos(state, header); //获取队头周边8个可到达的点 (注意是可到达,不包括已经走过的点)
            //遍历获取到的周边点
            for (int i = 0; i < directions.size(); i++) {
                Point direction = directions.get(i);
                //调整坐标
                int x = direction.x < length ? currentPos.x - direction.x : currentPos.x + direction.x;
                int y = direction.y < length ? currentPos.y - direction.y : currentPos.y + direction.y;
                //检查越界
                if (!isOutside(direction.x, direction.y, verticalCount, horizontalCount)
                        && !isOutside(x, y, verticalCount, horizontalCount)) {
                    //等于1表示查找到了匹配的点
                    if (targetPixels[y][x] == 1)
                        return true;
                        //否则将这个点入队,需要查找这个点的周围
                    else
                        queue.offer(direction);
                }
            }
        }
        //任务队列为空,且还没返回,自然是找不到了
        return false;
    }

该方法以广度优先的遍历方法,以currentPos为起点,来查找现金滚nearCount个像素点的色值是否近似于目标颜色。参数nearCount为需要查找周边像素的个数,targetPixels为色值表,cuurrentPos为当前坐标。返回值为是否查找到。

首先进行数据的初始化。定义quene为应该查找的点的队列,当前pos先入队。将state[nearCount][nearCount]标记为无效(已经被用过了)。然后检查如果有任务未完成,则进入while循环。while循环中的主要操作为队头出队,然后获取队头周边8个可到达的点(不包括已经走过的点)。遍历获取到的周边点,调整坐标,然后用isOutSide来检查越界。如果未越界,则判断targetPixels[y][x]是否等于1,如果是则返回true,否则将这个点入队,需要查找这个点的周围的点。最终如果任务队列为空,还未返回时,则说明未找到,返回false。

isOutSide方法

    private static boolean isOutside(int x, int y, int verticalCount, int horizontalCount) {
        return x < 0 || y < 0 || x > horizontalCount - 1 || y > verticalCount - 1;
    }

该函数用于检查目标pos是否越界。通过参数中的坐标与边界的对比可以判断是否越界。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值