java 水印测试工具

水印测试工具

介绍

在程序中添加了一个增加水印的操作,本地测试都ok,但是在实际使用中发现,服务器不行,打印出来都是方块,经过验证发现是没有安装中文字体,安装字体后就ok了。

你以为这就结束了吗?

当然不是

项目现场要部署在4台linux上面,但是安装完字体后说还是不行,然后就教现场的同事怎么安装字体,怎么部署项目,怎么测试

ok 问题解决了

当然还有后续

这个同事被调去别的项目了,正好现场的服务器被重置了,所有服务器,也就是说得从头来过,

最后没办法就写了这么一个工具,用来测试服务器是否安装字体,安装是否成功,软件水印功能是否ok

其实也挺简单的,就是增加水印的一个jar demo

代码

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;/*** 图片添加水印*/public class ImgWaterMark {// 水印透明度private  float alpha = 0.5f;// 水印文字大小private   int fontSize = 28;// 水印文字字体private  Font font = new Font(Font.DIALOG, Font.PLAIN, fontSize);// 水印文字颜色private  Color color = Color.gray;// 水印之间的间隔private   int xmove = 200;// 水印之间的间隔private   int ymove = 200;private int  degree = -40;private String logoText;private ByteArrayOutputStream out;//rgbpublic static Color color(int v1,int v2,int v3){return new Color(v1,v2,v3);}//文字加时间public static String  timeText(String logoText){SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return logoText + sdf.format(new Date());}public ImgWaterMark(float alpha,int fontSize ,Color color,int move,int degree){this.alpha = alpha;this.fontSize = fontSize;this.font =  new Font("宋体", Font.PLAIN, this.fontSize);this.color = color;this.xmove = move;this.ymove = move;this.degree = degree;}public ImgWaterMark(String logoText){this.logoText = logoText;out = new ByteArrayOutputStream();}/*** 创建图片* @return*/public ImgWaterMark create(InputStream in,String fileType) throws Exception {try {Image source = ImageIO.read(in);int srcWidth = source.getWidth(null);int srcHeight = source.getHeight(null);BufferedImage buffImg = new BufferedImage(srcWidth,srcHeight, BufferedImage.TYPE_INT_RGB);// 得到画笔对象Graphics2D g = buffImg.createGraphics();// 设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(source.getScaledInstance(srcWidth, srcHeight, Image.SCALE_SMOOTH),0, 0, null);// 设置水印旋转g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);// 设置水印文字颜色g.setColor(color);// 设置水印文字Fontg.setFont(font);// 设置水印文字透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));int x = -srcWidth / 2;int y = -srcHeight / 2;int markWidth = fontSize * getTextLength(logoText);// 字体长度int markHeight = fontSize;// 字体高度// 循环添加水印while (x < srcWidth * 1.5) {y = -srcHeight / 2;while (y < srcHeight * 1.5) {g.drawString(logoText, x, y);y += markHeight + ymove;}x += markWidth + xmove;}// 释放资源g.dispose();ImageIO.write(buffImg,fileType,out);} catch (IOException e) {throw new IOException("文件读取失败");}return this;}/*** 获取文本长度。汉字为1:1,英文和数字为2:1*/private static int getTextLength(String text) {int length = text.length();for (int i = 0; i < text.length(); i++) {String s = String.valueOf(text.charAt(i));if (s.getBytes().length > 1) {length++;}}length = length % 2 == 0 ? length / 2 : length / 2 + 1;return length;}public byte[] getData(){return out.toByteArray();}public String getDataBase64(){return Base64.getEncoder().encodeToString(getData());}public static void main(String[] args) throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String logoText = "测试图片水印字体" + sdf.format(new Date());FileInputStream in = new FileInputStream( "./imgTest.jpg");ImgWaterMark img = new ImgWaterMark(logoText);img.create(in,"png");byte[] data = img.getData();OutputStream outFile = new FileOutputStream("./resultimgTest.png");outFile.write(data);outFile.flush();outFile.close();}}

使用

打好包后直接运行就行了,当前目录下会生成一个带水印的图片

java -jar imgTest.jar

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/688685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenHarmony—UIAbility组件与UI的数据同步

基于HarmonyOS的应用模型&#xff0c;可以通过以下两种方式来实现UIAbility组件与UI之间的数据同步。 使用EventHub进行数据通信&#xff1a;基于发布订阅模式来实现&#xff0c;事件需要先订阅后发布&#xff0c;订阅者收到消息后进行处理。使用globalThis进行数据同步&#…

【数据结构与算法】递归、回溯、八皇后 一文打尽!

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

Vue3+Vite+TS+Pinia+ElementPlus+Router+Axios创建项目

目录 初始项目组成1. 创建项目1.1 下载项目依赖1.2 项目自动启动1.3 src 别名设置vite.config.ts配置文件tsconfig.json配置若新创项目ts提示 1.4 运行测试 2. 清除默认样式2.1 样式清除代码下载2.2 src下创建公共样式文件夹style2.3 main.js中引入样式2.4 安装sass解析插件 2.…

SNAT 与 DNAT

1.SNAT 1.1 SNAT 定义 SNAT 又称源地址转换。源地址转换是内网地址向外访问时&#xff0c;发起访问的内网ip地址转换为指定的ip地址&#xff08;可指定具体的服务以及相应的端口或端口范围&#xff09;&#xff0c;这可以使内网中使用保留ip地址的主机访问外部网络&#xff…

Leetcode 145.二叉树的后序遍历

题目 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[3,2,1] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root…

应用回归分析:岭回归

岭回归&#xff0c;也称为Tikhonov正则化&#xff0c;是一种专门用于处理多重共线性问题的回归分析技术。多重共线性是指模型中的自变量高度相关&#xff0c;这种高度的相关性会导致普通最小二乘法&#xff08;OLS&#xff09;估计的回归系数变得非常不稳定&#xff0c;甚至无法…

32、IO/对文件读写操作相关练习20240218

一、使用fgets统计给定文件的行数 代码&#xff1a; #include<stdlib.h> #include<string.h> #include<stdio.h>int main(int argc, const char *argv[]) {FILE *fpNULL;if((fpfopen("./1.txt","r"))NULL)//只读形式打开1.txt文件{per…

【C++】类与对象【定义、访问限定符、this指针】

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 面向过程和面向对象初步认识 类的引入 类的定义 成员变量命名规则的建议&#xff1a; 类的访问限定符及…

见智未来:数据可视化引领智慧城市之潮

在数字时代的浪潮中&#xff0c;数据可视化崭露头角&#xff0c;为打造智慧城市注入了强大的活力。不再被深奥的数据所束缚&#xff0c;我们通过数据可视化这一工具&#xff0c;可以更加接近智慧城市的未来。下面我就以可视化从业者的角度来简单聊聊这个话题。 数据可视化首先为…

LeetCode刷题小记 一、【数组】

LeetCode刷题小记 一、【数组】 文章目录 LeetCode刷题小记 一、【数组】写在前面1. 数组1.1 理论基础1.2 二分查找1.3 移除元素1.4 有序数组的平方1.5 长度最小的子数组1.6 螺旋矩阵II Reference 写在前面 本系列笔记主要作为笔者刷题的题解&#xff0c;所用的语言为Python3&…

模型超参数寻优

参考某篇QSAR的sci论文设置 根据上图&#xff0c;我设置我的XGBoost模型&#xff1a; # 定义要搜索的超参数的候选值 param_grid {model__learning_rate: [0.1, 0.01, 0.001], # 调整学习率model__n_estimators: [50, 100, 200, 300,400,500], # 调整树的数量model__max_de…

防御第五次作业

拓扑图及要求 1 创建安全区域 创建nat策略 测试 2 创建目标nat 测试 3 配置双向nat 配置IP 测试 查看会话表 4 FW1 FW3 结果 5 办公区限流 销售部限流 6 7

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第五天-ARM Linux编程之自动创建节点 (物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取码&#xff1a;1688 驱动程序编写好后&#xff0c;还需要创建设备节点&#xff0c;有两种方式&#xff0c;一是通过mknod命令去手动创建&#xff0c;例如&#xff1a;mknod /dev/hello c 250 0&…

ansible自动化运维工具及常见模块的使用

目录 一、ansible概述 二、ansible的特性 三、ansible 环境安装部署 管理端安装 ansible&#xff1a; 配置主机清单&#xff1a; 配置密钥对验证&#xff1a; 四、ansible 常见模块的使用 1&#xff0e;command 模块 2&#xff0e;shell 模块 3&#xff0e;cron 模块…

拿捏c语言指针(中)

前言 书接上回 拿捏c语言指针&#xff08;上&#xff09; 此篇主要讲解的是指针与数组之间的爱恨情仇&#xff0c;跟着我的脚步一起来看看吧~ 创造不易&#xff0c;可以帮忙点点赞吗 如有差错&#xff0c;欢迎指出 理解数组名 数组名是首元素地址 例外 1.sizeof&#xff0…

Java十进制转二进制

public static String tenTo2(int a){StringBuilder sb new StringBuilder();while (a>0){sb.append(a%2);a a/2;}return sb.reverse().toString();}

112 C++可调用对象整理,std::function std::bind 的使用

一 可调用对象 本节课将可调用对象整理一下 1 函数指针 void func90(int tv) {cout << "func90(int tv) called tv " << tv << endl; }void main() {//可调用对象 1 函数指针//方式一 1.1定义一个函数指针对象pmfvoid(*pmf)(int);//1.2将函数名…

【工作向】版本管理-IPD流程简介

1. IPD的由来 Integrated Product Development&#xff0c;集成产品开发 从IBM引进并结合自身实践 2. 引入IPD的过程 突破期 -> 全面推行期 -> 与时俱进发展 -> IPD2.0 19年开始 版本 -> 项目 -> 产品 产品开发流程&#xff0c;需求管理流程&#xff0c;生…

2024最新软件测试八股文(答案+文档)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&a…

PAT (Basic Level) Practice | A+B 和 C

给定区间 [−2的31次方, 2的31次方] 内的 3 个整数 A、B 和 C&#xff0c;请判断 AB 是否大于 C。 输入格式&#xff1a; 输入第 1 行给出正整数 T (≤10)&#xff0c;是测试用例的个数。随后给出 T 组测试用例&#xff0c;每组占一行&#xff0c;顺序给出 A、B 和 C。整数间…