Java 图片 滑动 解锁「建议收藏」

Java 图片 滑动 解锁「建议收藏」滑动解锁功能大家都不陌生,类似于如下这种:公司近期也要求实现类似的功能,百度各种文章,总算实现了一个比较糙的版本,保密等原因就不贴完成图了。我觉得难点在于滑块图和背景图的处理。图片处理原理我粗略的理解,图片就是一个二维的直角坐标系的一部分,(x,y)就是对应位置的一个像素点,可以操作某一个像素点,比如改变颜色,设置透明度等。Java中使用BufferedImage完成图…

大家好,又见面了,我是你们的朋友全栈君。

滑动解锁功能大家都不陌生,类似于如下这种:

Java 图片 滑动 解锁「建议收藏」

公司近期也要求实现类似的功能,百度各种文章,总算实现了一个比较糙的版本,保密等原因就不贴完成图了。

我觉得难点在于滑块图和背景图的处理。

图片处理原理

Java 图片 滑动 解锁「建议收藏」

我粗略的理解,图片就是一个二维的直角坐标系的一部分,(x,y)就是对应位置的一个像素点,可以操作某一个像素点,比如改变颜色,设置透明度等。

Java中使用BufferedImage完成图片处理等操作,先来段代码热热身:

/**
* 读取图片获取高宽
*/
String oldFileName = "E:\\images\\black_300_150.png";
BufferedImage image = ImageIO.read(new File(oldFileName));
int height = image.getHeight();
int width = image.getWidth();

在内存中生成图片,并保存到磁盘中:

BufferedImage dest = new BufferedImage(140,120,BufferedImage.TYPE_4BYTE_ABGR);
        try {
            FileOutputStream fos = new FileOutputStream(new File("E:\\images\\piece" + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".png"));
            ImageIO.write(dest, "png", fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

大概就是这样吧,抛个砖引一下各位的玉。

热完身上重点,就一句话:将背景图指定位置的像素值拷贝并设置到滑块图中,并将背景图抠图位置进行处理

具体步骤:

1.创建内存中创建一个指定大小的滑块图。

2.根据背景图宽高和滑块图宽高随机设置一个抠图点。

3.复制背景图的抠图区域的像素值到滑块图上。

4.处理背景图抠图位置。

划块图形状

有多种方式实现,如果几何方面编码足够六,可以使用代码生成形状,也可以直接用美工生成一个透明背景的图片,下面的生成滑块图代码,是我抄来的:

    static int targetLength=55;//小图长
    static int targetWidth=45;//小图宽
    static int circleR=6;//半径
    static int r1=3;//距离点
    private static int[][] getBlockData() {
        int[][] data = new int[targetLength][targetWidth];
        double x2 = targetLength-circleR;
        //随机生成圆的位置
        double h1 = circleR + Math.random() * (targetWidth-3*circleR-r1);
        double po = circleR*circleR;
        double xbegin = targetLength-circleR-r1;
        double ybegin = targetWidth-circleR-r1;
        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                double d3 = Math.pow(i - x2,2) + Math.pow(j - h1,2);
                double d2 = Math.pow(j-2,2) + Math.pow(i - h1,2);
                if ((j <= ybegin && d2 <= po)||(i >= xbegin && d3 >= po)) {
                    data[i][j] = 0;
                }  else {
                    data[i][j] = 1;
                }

            }
        }
        return data;
    }

如你所见,这是个二维数组,刚才说过一个图片就是一个平面直角坐标系,而二维数组就相当于一个图片。

当然也可以根据美工提供的透明背景图片来反向分析出此二维数组,这里利用的原理是图片每个RGB的高8位为0代表透明:

/**
     * 根据切图图片转化为切图数组
     * @param image 切图图片
     */
    public static int[][] convertAryByImage(BufferedImage image) {
        int[][] blockData = null;
        if (image != null) {
            int width = image.getWidth();
            int height = image.getHeight();
            blockData = new int[width][height];
            for (int i = 0; i < width; i++) {
                for (int j = 0; j < height; j++) {
                    int rgb = image.getRGB(i, j);
                    int x = rgb & 0xff000000;
                    blockData[i][j] = x == 0 ? 0 : 1;
                }
            }
        }
        return blockData;
    }

背景图处理

有了上一步的二维数据,那么我们就可以开始抠图了:

/**
* oriImage 原图
  targetImage 滑块图
  templateImage 数组
  x,y 在原图中抠图位置
*/
private static void cutByTemplate(BufferedImage oriImage,BufferedImage targetImage, int[][] templateImage, int x,int y){
        for (int i = 0; i < targetImage.getWidth(); i++) {
            for (int j = 0; j < targetImage.getHeight(); j++) {
                int rgb = templateImage[i][j];
                // 原图中对应位置变色处理
                int rgb_ori = oriImage.getRGB(x + i, y + j);
                if (rgb == 1) {
                    //抠图上复制对应颜色值
                    targetImage.setRGB(i, j, rgb_ori);
                    //原图对应位置颜色变化
                    oriImage.setRGB(x + i, y + j, rgb_ori & 0x363636 );
                }else{
                    //这里把背景设为透明
                    targetImage.setRGB(i, j, rgb_ori & 0x00ffffff);
                }
            }
        }
    }

处理完之后滑块图大概是这个样子的:

Java 图片 滑动 解锁「建议收藏」

原图是这样的:

Java 图片 滑动 解锁「建议收藏」

这里原图的处理,也可以使用高斯模糊(转来的,转侵删):

https://cloud.tencent.com/developer/article/1005568

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150114.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Oracle删除表空间的同时删除数据文件[通俗易懂]

    临时表空间主要用途是在数据库进行排序运算[如创建索引、orderby及groupby、distinct、union/intersect/minus/、sort-merge及join、analyze命令]、管理索引[如创建索引、IMP进行数据导入]、访问视图等操作时提供临时的运算空间,当运算完成之后系统会自动清理。当临时表空间不足时,表现为运算速度异常的慢,并且临时表空间迅速增长到最大空

    2022年4月18日
    159
  • react 路由守卫

    react 路由守卫通过HOC的方式实现路由守卫

    2022年5月11日
    40
  • PostMan的安装和使用教程[通俗易懂]

    PostMan的安装和使用教程[通俗易懂]postman的下载官网:https://www.getpostman.com/downloads/创建账号或者用谷歌浏览器账号登录一个demo了解一下我做的是一个app,后台使用java做的,app通过ajax来请求后台,但是我不知道后台有没有请求成功!因此需要一个测试接口的东西测试我做的接口有没有问题我的app里面的ajax是这样写的api.aja…

    2026年1月17日
    5
  • laravel validate 设置为中文(验证提示为中文)

    laravel validate 设置为中文(验证提示为中文)

    2021年10月23日
    43
  • Best Time to Buy and Sell Stock II

    Best Time to Buy and Sell Stock II

    2022年1月25日
    54
  • linux常用命令菜鸟教程_化妆初学者必备工具

    linux常用命令菜鸟教程_化妆初学者必备工具一.学习Linux终端命令的原因1.Linux刚面世时并没有图形界面,所有的操作全靠命令完成,如磁盘操作、文件存取、目录操作、进程管理、文件权限设定等2.在职场中,大量的服务器维护工作都是在远程通过SSH客户端来完成的,并没有图形界面,所有的维护工作都需要通过命令来完成在职场中,作为后端程序员,必须要或多或少的掌握一些Linux常用的终端命令。3.Linux发行版本的命令大概有200多个,但是常用的命令只有10多个而已二.linux常用指令ls命令…

    2022年9月23日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号