当前位置: 首页 > news >正文

java-正装照换底色小demo-技术分享

文章目录

  • 前言
      • java-正装照换底色小demo-技术分享
        • 01 实现思路
        • 02 效果
          • 02::01 原图:
          • 02::02 执行单元测试:
          • 02::03 效果:
        • 03 编码实现

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


java-正装照换底色小demo-技术分享

本来闲着没事想写个小demo玩玩,结果没想到坑还挺多,写个博客记录一下。

01 实现思路

其实这个需求如果加上人脸识别的话,然后截取人像部分,替换背景色,应该是最佳的选择。
而我的思路就只用java的awt包来解决,可能对于那些不是很标准的正装照来说,可能会有些瑕疵,但对于那些标签的正装照来说,是没有问题的。
下面是我的实现思路:

  1. 获取目标图片流;
  2. 取左上角30-30的位置作为图片原始背景色,即我们要替换的背景色;
  3. 遍历图片的像素(遍历长和宽上的每个像素),把指定像素上的颜色换成目标颜色;
  4. 当出现第一次出现指定像素上的颜色与图像上颜色不一致的时候,进行第二次范围RGB范围判断,因为有些正装照的背景色,不太标准,背景色有可能有些地方虽然都在 一个色素的范围之内,肉眼难以辨别,但是有可能有些差异,所以我又加了一个像素范围的过滤,判断图像上的颜色是否在这个指定像素范围之内, 如果在范围之内,那么替换目标像素,当第三次出现指定像素上的颜色与图像上颜色不一致的时候,不走范围RGB判断,因为如果没有控制的话, 可能将人物衣服上某些不该替换的颜色被目标颜色替换;
  5. 将修改完的图片生成新的图片文件输出;

02 效果

02::01 原图:

在这里插入图片描述

02::02 执行单元测试:
public  class PhotographToColorTest {@Testpublic void test(){String path = "D:\\Photograph\\证件照测试.jpg";//红色PhotographToColor.imageBackgroundRGB(path,PhotographToColor.TYPE.RED);//蓝色PhotographToColor.imageBackgroundRGB(path,PhotographToColor.TYPE.BLUE);}}

在这里插入图片描述

02::03 效果:

在这里插入图片描述

在这里插入图片描述
毕竟拿的是网图,这个正装照有些地方不是很标准,如果是标准的正装照,背景色素是一样的,使用这个办法就没有问题。


03 编码实现

引用:

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

具体小demo实现:

/*** @author yangzhenyu* @version 1.0* @description:* @date 2023/3/10 10:20*/public class PhotographToColor {private final static String BLUE = "BLUE";private final static String RED = "RED";private final static String WHITE ="WHITE";private static Map<String,PhotographToColor.RGB> init =   new ConcurrentHashMap<>();static {init.put(BLUE,new PhotographToColor.RGB(0,0,255));init.put(RED,new PhotographToColor.RGB(255,0,0));init.put(WHITE,new PhotographToColor.RGB(255,255,255));}private static final Logger log = LoggerFactory.getLogger(PhotographToColor.class);private static final int CRITICAL = 30;private static final int NUM = 1;// int转rgbpublic static String converArgbToRgb(int argb){int [] rgb  = new int[3];rgb[0] = (argb & 0xff0000) >> 16;rgb[1] = (argb & 0xff00) >> 8;rgb[2] = (argb & 0xff);return "rgb("+rgb[0]+","+rgb[1]+","+rgb[2]+")";}// rgb转intpublic static int rgbToArgb(int r,int g,int b){return ((0xFF << 24)|(r << 16)|(g << 8)|b);}public static int rule(int nowR,int nowG,int nowB,int p,int targetRgb){//蓝色if(nowR<188&&nowR>-1 && nowG<256&&nowG>133 && nowB<256&&nowB>204 ) {p = targetRgb;}//白色if(nowR<256&&nowR>240 && nowG<256&&nowG>240 && nowB<256&&nowB>240 ) {p = targetRgb;}//红色if(nowR<256&&nowR>149 && nowG<107&&nowG>-1 && nowB<100&&nowB>-1 ) {p = targetRgb;}return p;}/**** 处理图片背景色* @param path 原图地址*/public static void imageBackgroundRGB(String path,PhotographToColor.TYPE type)  {RGB rgb = init.get(type.code);int targetRgb = rgbToArgb(rgb.getR(),rgb.getG(),rgb.getB());File file = new File(path);//格式String[] data = path.split("\\.");String format = data [1];//输出的路径String srcPath = StringUtils.join(data[0], "_", UUID.randomUUID(),".", format);File srcPathFile = new File(srcPath);//用来处理图片的缓冲流BufferedImage bi = null;BufferedImage image = null;try {//用ImageIO将图片读入到缓冲中bi = ImageIO.read(file);//得到图片的长宽int width = bi.getWidth();int height = bi.getHeight();image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取左上角颜色,默认左上角像素块颜色为背景色int pixel = bi.getRGB(CRITICAL, CRITICAL);String s = converArgbToRgb(pixel);log.info("=============="+s);log.info("图片名称:{}, targetRgb:{}, width:{}, height:{}, pixel:{}",file.getName(), targetRgb, width, height, pixel);/*** 这里是遍历图片的像素,因为要处理图片的背色,所以要把指定像素上的颜色换成目标颜色* 这里 是一个二层循环,遍历长和宽上的每个像素*/Graphics graphics = image.getGraphics();Boolean flag =Boolean.FALSE;int num = 0;for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {// 得到指定像素(i,j)上的RGB值,int nowPixel = bi.getRGB(x, y);int p = nowPixel;if (flag){int nowR = (nowPixel & 0xff0000) >> 16;int nowG = (nowPixel & 0xff00) >> 8;int nowB = (nowPixel & 0xff);p = rule(nowR,nowG,nowB,p,targetRgb);}else {p = pixel == nowPixel ? targetRgb : nowPixel;}if (targetRgb == p){flag = Boolean.TRUE;}else{flag = Boolean.FALSE;}graphics.setColor(new Color(p));graphics.fillRect(x, y, 1, 1);}}log.info("处理完毕:{}", file.getName());ImageIO.write(image, format, srcPathFile);}catch (Exception e){log.error("错误",e);}}enum TYPE{BLUE("BLUE"),RED("RED"),WHITE("WHITE");private final String code;TYPE(String code) {this.code = code;}public String getCode() {return code;}}static class RGB{private int r;private int g;private int b;public RGB(int r, int g, int b) {this.r = r;this.g = g;this.b = b;}public int getR() {return r;}public void setR(int r) {this.r = r;}public int getG() {return g;}public void setG(int g) {this.g = g;}public int getB() {return b;}public void setB(int b) {this.b = b;}}
}

相关文章:

java-正装照换底色小demo-技术分享

文章目录前言java-正装照换底色小demo-技术分享01 实现思路02 效果02::01 原图:02::02 执行单元测试:02::03 效果:03 编码实现前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞…...

(枚举)(模拟)(二位前缀和)99. 激光炸弹

目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 99. 激光炸弹 - AcWing题库 数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&#xff5e;字&#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&#xff5e;字&am…...

vue3+vite项目移动端适配:postcss-pxtorem和amfe-flexible

一&#xff0c;定义 postcss-pxtorem PostCSS 的一个插件&#xff0c;可以从像素单位生成 rem 单位。 amfe-flexible amfe-flexible是配置可伸缩布局方案&#xff0c;主要是将1rem设为viewWidth/10。 二&#xff0c;使用 1. 设置 viewport 在 index.html 中&#xff1a; &l…...

sin x和cos x的导数

我们都知道(sin⁡x)′cos⁡x(\sin x)\cos x(sinx)′cosx&#xff0c;(cos⁡x)′−sin⁡x(\cos x)-\sin x(cosx)′−sinx&#xff0c;但是为什么呢&#xff1f; sin⁡x\sin xsinx的导数 (sin⁡x)′lim⁡Δx→0sin⁡(xΔx)−sin⁡xΔx(\sin x)\lim\limits_{\Delta x\rightarrow 0…...

html下自动消失的提示框jQuery实现

引言 最近在找一个可以自动消失的提示框&#xff0c;找来找去&#xff0c;找到了这个&#xff1a;提示框设置_html页面提示框等待一定时间消失博主写得很好&#xff0c;可以直接复制运行出来&#xff0c;我也从中得以受益。本篇文章对这篇博客的代码做了一些小的更新&#xff…...

第27篇:Java日期处理总结(一)

目录 1、Date类 1.1 如何实例化Date对象 1.2 Date相关操作方法 1.3 如何获取当前日期...

Linux入门教程——VI/VIM 编辑器

前言 本文小新为大家带来 Linux入门教程——VI/VIM 编辑器 相关知识&#xff0c;具体内容包括VI/VIM是什么&#xff0c;VIM的三种工作模式介绍&#xff0c;包括&#xff1a;一般模式&#xff0c;编辑模式&#xff0c;指令模式&#xff0c;以及模式间转换等进行详尽介绍~ 不积跬…...

第十四届蓝桥杯三月真题刷题训练——第 10 天

目录 第 1 题&#xff1a;裁纸刀 问题描述 运行限制 代码&#xff1a; 第 2 题&#xff1a;刷题统计 问题描述 输入格式 输出格式 样例输入 样例输出 评测用例规模与约定 运行限制 代码&#xff1a; 第 3 题&#xff1a;修建灌木 问题描述 输入格式 输出格式 …...

软件测试之jira

Jira 1. Jira 概述 JIRA 是澳大利亚 Atlassian 公司开发的一款优秀的问题跟踪管理软件工具&#xff0c;可以对各种类型的问题进行跟踪管理&#xff0c;包括缺陷、任务、需求、改进等。JIRA采用J2EE技术&#xff0c;能够跨平台部署。它正被广泛的开源软件组织&#xff0c;以及…...

传统方式实现SpringMVC

一、初次尝试SpringMVC 1.1、在pom.xml中添加依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.2.6.RELEASE</version></dependency><dependency><grou…...

RS232/RS485信号接口转12路模拟信号 隔离D/A转换器LED智能调光控制

特点&#xff1a;● RS-485/232接口&#xff0c;隔离转换成12路标准模拟信号输出● 可选型输出4-20mA或0-10V控制其他设备● 模拟信号输出精度优于 0.2%● 可以程控校准模块输出精度● 信号输出 / 通讯接口之间隔离耐压3000VDC ● 宽电源供电范围&#xff1a;10 ~ 30VDC● 可靠…...

聊一聊代码重构——封装集合和替换算法的代码实践

代码重构相关内容 聊一聊代码重构——我们为什么要代码重构 聊一聊代码重构——代码中究竟存在哪些坏代码 聊一聊代码重构——关于变量的代码实践 聊一聊代码重构——关于循环逻辑的代码实践 聊一聊代码重构——关于条件表达式的代码实践 聊一聊代码重构——程序方法上的…...

FPGA解码4K分辨率4line MIPI视频 OV13850采集 提供工程源码和技术支持

目录1、前言2、Xilinx官方主推的MIPI解码方案3、纯Vhdl方案解码MIPI4、vivado工程介绍5、上板调试验证6、福利&#xff1a;工程代码的获取1、前言 FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了&#xff0c;MIPI解码难度之高&#xff0c;令无数英雄竞折腰…...

Map接口及遍历方式

1、Map接口实现类的特点1)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value&#xff08;无序&#xff09;2) Map中的key和value可以是任何引用类型的数据&#xff0c;会封装到HashMap$Node对象中3) Map 中的key不允许重复import java.util.HashMap; import java…...

一步步构建自己的前端项目

一、我们先把webpack走通 1、先安装相关依赖&#xff0c;webpack是用来处理命令行参数的&#xff0c;但是我不准备使用webpack-cli&#xff0c;但是还是要求必须安装webpack-cli npm install webapck webpack-cli --save-dev2、npm init -y 3、创建项目结构 build.js cons…...

VMware搭建Mac OS环境

推荐阅读 Proxifier逆向分析(Mac) MacOS Burp2021安装配置 突破iOS App双向认证抓包 App绕过iOS手机的越狱检测 iOS系统抓包入门实践之短链 各种学习环境更新MacOS虚拟机 Android和iOS静态代码扫描工具 iOS系统抓包之短链-破解双向证书 Android和iOS应用源码的静态分析…...

【Maven】什么是Maven?Maven有什么用?

目录 一、什么是 Maven 二、Maven 能解决什么问题 三、Maven 的优势举例 四、Maven 的两个经典作用 4.1 Maven 的依赖管理 4. 2 项目的一键构建 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一下 一、什么是 Maven Maven 的正确发…...

【JavaSE】类和对象的详解

前言&#xff1a; 大家好&#xff0c;我还是那个不会打拳的程序猿。今天我给大家讲解的是类和对象&#xff0c;相信大家在之前的学习中都是面向过程的思想&#xff0c;那么今天就让我们走向面向对象的世界吧。 目录 1.面向过程VS面向对象 1.1什么是面向过程 1.2什么是面向对…...

2023年中职组“网络安全”赛项广西自治区竞赛任务书

2023年中职组“网络安全”赛项 广西自治区竞赛任务书 一、竞赛时间 总计&#xff1a;360分钟 需求环境可私信博主&#xff01;点个赞加三连吧&#xff01; 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2…...

简单的自定义录屏工具

在csdn上写文章&#xff0c;需要配一些操作动态图&#xff0c;需要针对电脑录屏&#xff0c;可能是整个屏幕录屏&#xff0c;也可能是某窗口&#xff0c;甚至是某一小块区域。 动态图最好是gif格式&#xff0c;方便直接嵌入文章中。 一、设计 窗口类widget 切屏类Capturescr…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...