java项目抠图功能实现

2023-11-20

java项目抠图功能

  项目中需要一个上传文字签名并且抠掉背景图的功能,当初第一次听到这个需求时,差点惊掉下巴,我压根都不会觉得java里能实现这功能。但是既然客户需要,那就照办吧。
  经过这次功能的实现,我也更加坚定了一个想法,再奇葩的需求,也要先找找方法,不要果断拒绝,要相信Java天下第一,天下第一能有解决不了的事吗?(其实我现在内心已经对学python蠢蠢欲动了,嘿嘿~~~)

1.效果图

  经过我一番的搜索加改造,与前端小伙伴做了下边的效果。(整的跟PS一样,顿时有了高大上的感觉)
在这里插入图片描述
  功能比较简单,上传图片给后端,后端返回抠完图的路径。
  原图如下:
在这里插入图片描述
  上传这个图之后,先框选范围、旋转好方向,注意,框选、旋转图片都是前端的操作,这些前端都有方法,如下图:
在这里插入图片描述
  当设置好之后,则点击抠图,即可看到下图的效果,已经变成了透明的。在这一步操作上,抠图就调用了本次java提供的抠图接口。

在这里插入图片描述

2.扣图接口

  以下是抠图接口,在该接口里前端将裁剪后的图片传送到后端,在该接口里,后端将会把前端传过来的图片传给PictureUtils.transApla(restore,169)方法,在该方法里,将会进行抠图并再保存,保存后将该处理好的图片路径返回给前端,前端直接展示即可。详细步骤如下:

  1. 前端上传图片到面板上,此时并没有调用后端接口,仅由前端加载。
  2. 因为用户上传的图片大小方向都不固定,因此也要考虑一些旋转、裁剪功能,因此这里我们也加入了这些常用功能,经过旋转、裁剪,定好了范围。注意到这里都是前端自己完成。
  3. 当处理好之后,再调用裁剪接口,也就是下边的代码所写,重点只是PictureUtils.transApla(restore,169)方法。

  如下是裁剪接口:

/**
     * 签名图扣掉背景色
     * @param request
     * @return
     */
    @RequestMapping(value = "/signHandle",method = RequestMethod.POST)
    public Object getPsPictureSign(HttpServletRequest request){
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        String fileName = null;
        String msg = null;
        String result = "";
        try {
            //获取文件
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            if(fileMap == null || fileMap.isEmpty()){
                return addResultMapMsg(false,"未上传签名图片");
            }
            MultipartFile multipartFile = null;//获取文件名
            for (Map.Entry<String, MultipartFile> set : fileMap.entrySet()) {
                multipartFile = set.getValue();// 文件名
                String uploadfileName = multipartFile.getOriginalFilename();
                String suffix = uploadfileName.substring(uploadfileName.lastIndexOf(".")+1).toLowerCase();
                if(!uploadSuffix.contains(suffix)){
                    return addResultMapMsg(false,"只能上传 png、jpg 图片格式");
                }
            }
            //先将文件保存到服务器中,然后操作文件
            String fileOriginalName = multipartFile.getOriginalFilename();
            String resultStr = File.separator + "pictureTmp" + File.separator  + File.separator + fileOriginalName.substring(0,fileOriginalName.lastIndexOf(".")+1) +".png";
            fileName = realPath + resultStr;
            File restore = new File(fileName);
            if(!restore.getParentFile().exists()){
                restore.getParentFile().mkdirs();
            }
            //System.out.println(3+"=="+fileName);
            multipartFile.transferTo(restore);
            // 抠图工具类
            PictureUtils.transApla(restore,169); // 169为灰色的rcb色值
            result = resultStr;
        } catch (Exception e) {
            e.printStackTrace();
            msg = "处理失败";
        }
        if(!StringUtils.isEmpty(msg)){ //说明上传有错
            return addResultMapMsg(false,msg);
        }else {
            return addResultMapMsg(true,result.replace("\\","/"));
        }
    }

  以下是封装好的工具类,可以直接用,另外,因为使用的方法java直接就有,不需要引用额外的jar包。
  如下是工具类方法:

package znxd.lxynzl.controller.photoshop;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.regex.Pattern;

/**
 * Created by lingsf on 2020/6/16.
 */
public class PictureUtils {
    public static int color_range = 210;
    public static Pattern pattern = Pattern.compile("[0-9]*");

    public static boolean isNo(String str) {
        return pattern.matcher(str).matches();
    }

    /**
     *
     * @param file 保存后要处理的png文件
     * @param rcb  要扣掉的rcb色值
     */
    public static void transApla(File file,int rcb){
        InputStream is=null;
        try {
            is = new FileInputStream(file);
            // 如果是MultipartFile类型,那么自身也有转换成流的方法:is = file.getInputStream();
            BufferedImage bi = ImageIO.read(is);
            Image image = (Image) bi;
            ImageIcon imageIcon = new ImageIcon(image);
            BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(),
                    BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
            g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
            int alpha = 0;
            color_range = 255 - rcb; // 0
            for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage
                    .getHeight(); j1++) {
                for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage
                        .getWidth(); j2++) {
                    int rgb = bufferedImage.getRGB(j2, j1);
                    if (colorInRange(rgb)) {
                        alpha = 0;
                    } else {
                        alpha = 255;
                    }
                    rgb = (alpha << 24) | (rgb & 0x00ffffff);
                    bufferedImage.setRGB(j2, j1, rgb);
                }
            }


            g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
            ImageIO.write(bufferedImage, "png", file);// 直接输出文件
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(is!=null){
                try{
                    is.close();
                }catch (Exception e){}
            }
        }
    }

    public static boolean colorInRange(int color) {
        int red = (color & 0xff0000) >> 16;
        int green = (color & 0x00ff00) >> 8;
        int blue = (color & 0x0000ff);
        if (red >= color_range && green >= color_range && blue >= color_range) {
            return true;
        }
        return false;
    }

}

3.总结

  整体功能还是比较简单,后端只提供了一个接口,主要的解决办法,使用了swing的色素替换的方法,就是将固定的色值替换为透明色素,因此功能图上提示用户,尽量用白底黑字的签名上传。
  当然你们也看到了,上边的我写的签名图,拍出来也并不是白底黑字,照样也能抠图成功。

前端vue下载地址:百度网盘 提取码:nvt2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java项目抠图功能实现 的相关文章

随机推荐

  • 020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

    020 STM32学习笔记 Fatfs文件系统 二 移植与测试 上节学习了FatFs文件系统的相关知识 这节内容继续学习在STM32上如何移植FatFs文件系统 并且实现文件的创建 读 写与删除等功能 各位看官觉得还行的话点点赞 收藏一下呗
  • FastDFS-01-单机和集群搭建

    我是码赛客1024 本节我们一起搭建FastDFS 一 介绍 FastDFS是一个开源的轻量级分布式文件系统 它对文件进行管理 功能包括 文件存储 文件同步 文件访问 文件上传 文件下载 等 解决了大容量存储和负载均衡的问题 特别适合以文件
  • 对象创建的几个步骤

    对象创建的几个步骤 一 先把要创建的对象的类信息加载进内存 二 在内存开辟空间 1 如果内存是规整的 则使用指针碰撞 2 如果不规整 则会维护一个空闲列表 内存是否规整根据具体的垃圾回收算法来决定 三 开辟空间需要解决并发问题 在堆中创建对
  • shell脚本一键安装JDK及配置环境变量

    这是我学了半天shell写出来的 不适合大神看 为什么我要写这样安装JDK并配置环境变量的脚本呢 因为我和linux打交道还是比较多的 然而每次都要安装JDK 配置环境变量 这样的事情对于刚接触linux的人来说是很乐意做的 但是接触多了
  • 浏览器请求队列机制-请求为什么会阻塞

    前言 最近遇到一个问题 我1个站点链接2个后端服务 但1个后端服务有问题 导致访问超时 但请求接口都是分开的 自认为一个服务站点请求超时 不会影响到另外一个请求的 但不是 全部请求都发不出去 为什么呢 是不是浏览器有请求机制管理 正常情况前
  • html理解MVC模型与MVVM模型底层实现

    一 MVC模型的底层实现 1 1 相关代码 div div
  • python基础编程小实例13——手机通讯录

    本文更新于2022 05 18 bug已修复 编程语言 python3 9 题目 可以在通讯录中通过姓名查看相关联系人的联系方式等信息 也可以在其中新增联系人 或修改 删除联系人信息 本实例要求编写程序 实现具备添加 查看 修改以及删除联系
  • react 上传文件(多选)功能入的坑

    1 这里报错是因为onChange的this指向不对 解决方法在constructor中写 this onChange this onChange bind this 或者在绑定事件的时候写 onChange this onChange b
  • Unity Animator 动画没切换

    恶魔射手 Survival Shooter 项目 有两个动画 一个是静止时的Idle 一个是走路时候的Move 如下图 设置好动画状态机后发现按方向键后还是Idle 没反应 而一直按着方向键后呢又动起来了 最后找到了真相 原来选中了 Has
  • 使用yolov7模型用VOC深度学习

    yolov7及VOC数据集 权重文件地址 bubbliiiing yolov7 pytorch 这是一个yolov7的库 可以用于训练自己的数据集 github com 在colab中 训练 1 voc annotation py 如果使用
  • Python 判断数组list是否为空

    前言 判断数组为空 是一个常见用法 Python与Java的方法不同 需区分 Python 方法 1 根据长度判断 长度为0时 表示空 其中 判断条件 成立时 非零 则执行后面的语句 lst if len lst print c else
  • 如何在mybatis 中传多个参数,如何在mybatis 中遍历 集合?

    如何在mybatis 中传多个参数 List getIdByRand Param question Question question Param sectionIdList List sectionIdList param 映射参数到 x
  • .NET的RulesEngine(规则引擎)使用

    本文目录 1 背景说明 1 1 规则引擎的使用场景 1 2 demo的代码说明 2 演示 2 1 入门demo演示 2 1 1 代码展示 2 1 2 代码下载 2 2 规则参数说明 2 2 1 第一部分参数说明 2 2 2 第二部分参数说明
  • 2021.9.5笔试题

    第一题 题目 找x y target 数字特别大 可能会溢出 代码 include
  • CPU 100%问题排查

    1 top c top c 命令找出当前进程的运行列表 按一下 P 可以按照CPU使用率进行排序 显示Java进程 PID 为 2609 的java进程消耗最高 2 top Hp pid 然后我们需要根据PID 查出CPU里面消耗最高的进程
  • sklearn的make_circles和make_moons生成数据

    关于make circles and make moons生成环形形状和月亮形状数据 转载来源 https blog csdn net dataningwei article details 53649330 make circles sk
  • ConcurrentHashMap源码解读

    曾经研究过jkd1 5新特性 其中ConcurrentHashMap就是其中之一 其特点 效率比Hashtable高 并发性比hashmap好 结合了两者的特点 集合是编程中最常用的数据结构 而谈到并发 几乎总是离不开集合这类高级数据结构的
  • 儿童计算机诈骗案例,妈妈用纸箱为4岁女儿做笔记本电脑走红 小孩子这么好骗吗?...

    原标题 妈妈用纸箱为4岁女儿做笔记本电脑走红 小孩子这么好骗吗 来源 游民星空 在全球大隔离的状态下 单身生活的人可能会感到孤独无聊 但是已经有孩子的家长可能逐渐的要抓狂了 每天精力旺盛的孩子们可能会吵的你无法在家工作甚至休息 于是就开始变
  • 百度飞桨图像分割七日打卡营学习笔记

    百度飞桨图像分割七日打卡营学习笔记 来源 飞桨图像分割教程 课程链接https aistudio baidu com aistudio course introduce 1767 1 语义分割概念 图像分割是计算机视觉中除了分类和检测外的另
  • java项目抠图功能实现

    java项目抠图功能 项目中需要一个上传文字签名并且抠掉背景图的功能 当初第一次听到这个需求时 差点惊掉下巴 我压根都不会觉得java里能实现这功能 但是既然客户需要 那就照办吧 经过这次功能的实现 我也更加坚定了一个想法 再奇葩的需求 也