java 图片水印、压缩图片、宽和高等比缩放的率

   /*** 添加水印* @param inputStream 图片文件流* @param mark  要打的水印* @param rgb  字体颜色(白色)* @param alpha 分辨率* @param degree 水印旋转* @return*/public static InputStream addMark(InputStream inputStream, String mark,Integer rgb,Float alpha,Integer fontSize,Integer degree) {if(Objects.isNull(rgb)){rgb = 0xffffff;}if(Objects.isNull(alpha)){alpha = 1F;}if(Objects.isNull(fontSize)){fontSize = 60;}String[] waterMarkContents = mark.split("\\|\\|");// 用来调整水印的间距int space = 20;//将读取流转化为图片对象Image srcImg = null;try {srcImg = ImageIO.read(inputStream);} catch (IOException e) {throw new RuntimeException(e);}//获取图片的宽int srcImgWidth = srcImg.getWidth(null);//获取图片的高int srcImgHeight = srcImg.getHeight(null);System.out.println("图片的宽:" + srcImgWidth);System.out.println("图片的高:" + srcImgHeight);BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);// 加水印//创建画笔Graphics2D g = bufImg.createGraphics();//设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);//srcImg 为上面获取到的原始图片的图片对象g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);//设置水印旋转if (null != degree) {g.rotate(Math.toRadians(degree),(double) bufImg.getWidth() / 2,(double) bufImg.getHeight() / 2);}//根据图片的背景设置水印颜色g.setColor(new Color(rgb));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));//设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60ptg.setFont(new Font("微软雅黑", Font.BOLD, fontSize));java.util.List<String> waterMarkContentList = new ArrayList<>();
// 将换行后的文字放入新的集合for (String markContent : waterMarkContents) {// 单字符长度int tempCharLen = 0;// 单行字符总长度临时计算int tempLineLen = 0;StringBuilder sb = new StringBuilder();for (int i = 0; i < markContent.length(); i++) {char tempChar = markContent.charAt(i);tempCharLen = getCharLen(tempChar, g);tempLineLen += tempCharLen;// 文字长度大于图片宽度-2*间距-字体大小if (tempLineLen > srcImgWidth - space * 2 - tempCharLen) {// 长度已经满一行waterMarkContentList.add(sb.toString());// 清空内容,重新追加sb.delete(0, sb.length());tempLineLen = 0;}// 追加字符sb.append(tempChar);}waterMarkContentList.add(sb.toString());}// 绘制水印int tempY = fontSize + space;for (int i = 0; i < waterMarkContentList.size(); i++) {String s = waterMarkContentList.get(i);//左上角
//                g.drawString(s, space, i * tempY + 3 * space);//右下角g.drawString(s, space, srcImgHeight - (waterMarkContentList.size() - i) * tempY + space);//            g.drawString(s, space, (srcImgHeight - (waterMarkContentList.size() - i) * (tempY*2))/2 + space);//设置水印的坐标
//            int x = (srcImgWidth - getWatermarkLength(mark, g)) / 2;
//            int y = srcImgHeight / 2;//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
//            g.drawString(s, x, y);}g.dispose();ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(bufImg,"jpg",baos);} catch (IOException e) {throw new RuntimeException(e);}return new ByteArrayInputStream(baos.toByteArray());}/*** 添加水印 并且等比缩(等比压缩图片)* @param inputStream* @param mark* @return*/public static InputStream addMarkValue(InputStream inputStream, String mark,Integer rgb,Float alpha,Integer fontSize,Integer degree) {if(Objects.isNull(rgb)){rgb = 0xffffff;}if(Objects.isNull(alpha)){alpha = 1F;}
//        if(Objects.isNull(fontSize)){
//            fontSize = 60;
//        }if(Objects.isNull(fontSize)){fontSize = 30;}String[] waterMarkContents = mark.split("\\|\\|");// 用来调整水印的间距int space = 20;//将读取流转化为图片对象Image srcImg = null;try {srcImg = ImageIO.read(inputStream);} catch (IOException e) {throw new RuntimeException(e);}// 等比缩int srcImgWidth = srcImg.getWidth(null);;int srcImgHeight = srcImg.getHeight(null);//如果图片本身的宽和高均小于要压缩到的宽和高,则不压缩直接返回if(800>srcImg.getWidth(null)&&800>srcImg.getHeight(null)){srcImgWidth =800;srcImgHeight =800;}else{//宽和高等比缩放的率double rate1=(double)srcImg.getWidth(null)/(double)800;double rate2=(double)srcImg.getHeight(null)/(double)800;//控制缩放大小double rate=rate1<rate2 ? rate1:rate2;srcImgWidth=(int) (srcImg.getWidth(null)/rate);srcImgHeight=(int) (srcImg.getHeight(null)/rate);}//获取图片的宽
//        int srcImgWidth = srcImg.getWidth(null);
//        //获取图片的高
//        int srcImgHeight = srcImg.getHeight(null);// 设置图片固定大小
//        int srcImgWidth = 1080; // 目标宽度
//        int srcImgHeight = 2400; // 目标高度System.out.println("图片的宽:" + srcImgWidth);System.out.println("图片的高:" + srcImgHeight);BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);//===============图片开始压缩=======================//通过比例压缩float scale = 0.6f;//压缩之后的长度和宽度int doWithHeight = (int) (scale * srcImgHeight);int dowithWidth = (int) (scale * srcImgWidth);// 图片压缩bufImg.getGraphics().drawImage(bufImg.getScaledInstance(dowithWidth, doWithHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);//===============图片结束压缩=======================// 加水印//创建画笔Graphics2D g = bufImg.createGraphics();//设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);//srcImg 为上面获取到的原始图片的图片对象g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);//设置水印旋转if (null != degree) {g.rotate(Math.toRadians(degree),(double) bufImg.getWidth() / 2,(double) bufImg.getHeight() / 2);}//根据图片的背景设置水印颜色g.setColor(new Color(rgb));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));//设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60ptg.setFont(new Font("微软雅黑", Font.BOLD, fontSize));java.util.List<String> waterMarkContentList = new ArrayList<>();
// 将换行后的文字放入新的集合for (String markContent : waterMarkContents) {// 单字符长度int tempCharLen = 0;// 单行字符总长度临时计算int tempLineLen = 0;StringBuilder sb = new StringBuilder();for (int i = 0; i < markContent.length(); i++) {char tempChar = markContent.charAt(i);tempCharLen = getCharLen(tempChar, g);tempLineLen += tempCharLen;// 文字长度大于图片宽度-2*间距-字体大小if (tempLineLen > srcImgWidth - space * 2 - tempCharLen) {// 长度已经满一行waterMarkContentList.add(sb.toString());// 清空内容,重新追加sb.delete(0, sb.length());tempLineLen = 0;}// 追加字符sb.append(tempChar);}waterMarkContentList.add(sb.toString());}// 绘制水印int tempY = fontSize + space;for (int i = 0; i < waterMarkContentList.size(); i++) {String s = waterMarkContentList.get(i);//左上角
//                g.drawString(s, space, i * tempY + 3 * space);//右下角g.drawString(s, space, srcImgHeight - (waterMarkContentList.size() - i) * tempY + space);//            g.drawString(s, space, (srcImgHeight - (waterMarkContentList.size() - i) * (tempY*2))/2 + space);//设置水印的坐标
//            int x = (srcImgWidth - getWatermarkLength(mark, g)) / 2;
//            int y = srcImgHeight / 2;//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
//            g.drawString(s, x, y);}// 设置透明度,0.5 表示半透明AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f);g.setComposite(alphaComposite);String text ="现场拍照";g.setStroke(new BasicStroke(10));
//        g.setFont(new Font("微软雅黑", Font.BOLD, 300));
//        没有压缩图片设置现场拍照大小
//        g.setFont(new Font("方正粗黑宋简体", Font.PLAIN, 120));// 压缩后设置现场拍照大小g.setFont(new Font("方正粗黑宋简体", Font.PLAIN, 150));int x =  (srcImgWidth - getWatermarkLength(text, g)) / 2;int y = srcImgHeight/2;g.setColor(new Color(0x80000000));g.drawString(text, x, y);/* 添加水印的文字和设置水印文字出现的内容 ----位置 */
//        g.drawString(iter, width - w, height - h);
//        g.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD+Font.PLAIN, 200));g.dispose();ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(bufImg,"jpg",baos);} catch (IOException e) {throw new RuntimeException(e);}return new ByteArrayInputStream(baos.toByteArray());}/*** 获取水印文字的长度* @param waterMarkContent* @param g* @return*/private static int getWatermarkLength(String waterMarkContent, Graphics2D g) {return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());}private static int getCharLen(char c, Graphics2D g) {return g.getFontMetrics(g.getFont()).charWidth(c);}//河北省  红色:0xff0000public static void main(String[] args) {try {InputStream inputStream = new FileInputStream("D:\\IMG_20231123_115406.jpg");InputStream inputStream1 = addMarkValue(inputStream, "经度:114.498895||" +"纬度:38.001944||" +"地址: 赵陵铺街道||"+"时间:2022/10/6 14:26:01 ||" +"海拔:0.0米 ||" +
//                    "天气:17-24C 北风  ||" +"备注:服务中备餐区",null,0.6F,null,null);String tarImgPath="D:\\tool2.jpg";FileOutputStream outImgStream = new FileOutputStream(tarImgPath);byte[] buf = new byte[1024];int le = -1;while (( le = inputStream1.read(buf))!=-1){outImgStream.write(buf,0,le);}} catch (Exception e) {throw new RuntimeException(e);}}

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

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

相关文章

鸿蒙原生应用/元服务开发-Stage模型能力接口(五)

说明 Common模块将二级模块API组织在一起方便开发者进行导出。本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。本模块接口仅可在Stage模型下使用 二、 导入模块 import common from ohos.app.ability.common; 三、 …

K8S学习指南(18)-k8s核心对象configmap

文章目录 前言什么是ConfigMap&#xff1f;示例演示步骤1&#xff1a;创建ConfigMap步骤2&#xff1a;在Pod中使用ConfigMap步骤3&#xff1a;应用变更并验证 高级用法&#xff1a;从文件中创建ConfigMap步骤4&#xff1a;从文件创建ConfigMap步骤5&#xff1a;在Pod中使用文件…

系列五、DQL

一、DQL 1.1、概述 DQL的英文全称为&#xff1a;Data Query Language&#xff0c;中文意思为&#xff1a;数据查询语言&#xff0c;用大白话讲就是查询数据。对于大多数系统来说&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访问企业官网、电商网站&…

LeetCode刷题--- 二叉树的所有路径

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 【 http://t.csdnimg.cn/yUl2I 】 【C】 【 http://t.csdnimg.cn/6AbpV 】 数据结构与算法 【 http://t.csdnimg.cn/hKh2l 】 前言&…

Java架构师-数据机构与算法实战(第一篇)

数学知识回顾 指数 指数函数是重要的基本初等函数之一。一般地&#xff0c;ya^x函数(a为常数且以a>0&#xff0c;a≠1)叫做指数函数&#xff0c;函数的定义域是 R 。注意&#xff0c;在指数函数的定义表达式中&#xff0c;在a^x前的系数必须是数1&#xff0c;自变量x必须在…

linux/CentOS 7 安装jdk

安装前准备 下载安装包。下载地址 本文使用的安装包是 jdk-8u211-linux-x64.tar.gz 将 jdk-8u211-linux-x64.tar.gz 放到到服务器上&#xff0c;按需放到对应目录下 安装步骤 #使用普通用户登陆服务器&#xff0c;执行以下安装 解压jdk-8u211-linux-x64.tar.gz tar -xvzf j…

车载测试包括哪些测试

车载测试包括CW测试和现网测试。以下是相关介绍&#xff1a; CW测试&#xff1a; 即在典型区域架设发射天线&#xff0c;发射单载被信号&#xff0c;然后在预先设定的路线上进行车载测试&#xff0c;使用车载接收机接收并记录各处的信号场强。CW测试频率和环境选择方便&#…

MySQL 是什么?

MySQL官方网站&#xff08;http://www.mysql.com/&#xff09;提供关于MySQL软件的最新信息。 MySQL是一个数据库管理系统。 数据库是一种结构化的数据集合。它可以是从简单的购物清单到图片库&#xff0c;再到企业网络中的大量信息等任何形式。要添加、访问和处理存储在计算…

如何拍摄超级大像素图片,超级大像素有哪些应用

引言&#xff1a; 在数字摄影领域&#xff0c;超级大像素照片是指通过高像素的相机或拼接多张照片合成的照片。这样的照片具有更高的分辨率&#xff0c;细节更加清晰&#xff0c;绘画质感更强。那么如何拍摄超级大像素照片&#xff0c;超级大像素可以用在哪些领域呢。 一&…

记一次Android中获取时间戳在Java转字符串不正确的问题

Hi, I’m Shendi 记一次Android中获取时间戳在Java转字符串不正确的问题 问题 在 Java 中将 Android 的时间戳转字符串&#xff0c;发现转换的结果不正确。示例代码如下 Calendar calendar Calendar.getInstance(); calendar.set(Calendar.YEAR, 2023); calendar.set(Calend…

如何做到人均告警减少 90%?B 站新一代告警平台的设计与实践

一分钟精华速览 B 站的业务规模和用户群体不断扩大&#xff0c;对于服务的稳定性和可用性的要求也日益增高。这就需要 B 站的监控告警系统能够及时、准确地发现和定位问题&#xff0c;以便尽快解决&#xff0c;维护好用户的使用体验。 本文是对 B 站在告警监控系统上的一次重…

小红书可观测 Metrics 架构演进,如何实现数十倍性能提升?

在当前云原生时代&#xff0c;随着微服务架构的广泛应用&#xff0c;云原生可观测性概念被广泛讨论。可观测技术建设&#xff0c;将有助于跟踪、了解和诊断生产环境问题&#xff0c;辅助开发和运维人员快速发现、定位和解决问题&#xff0c;支撑风险追溯、经验沉淀、故障预警&a…

MATLAB图解傅里叶变换(初学者也可以理解)

1、概述 相信很多人对于傅里叶变换可能觉得比较复杂和有点难懂&#xff0c;其实不难&#xff0c;它只是一种积分变换。 傅里叶变换&#xff0c;表示能将满足一定条件的某个函数表示成三角函数&#xff08;正弦和/或余弦函数&#xff09;或者它们的积分的线性组合。也就是说&qu…

『 Linux 』进程地址空间概念

文章目录 &#x1fad9; 前言&#x1fad9; 进程地址空间是什么&#x1fad9; 写时拷贝&#x1fad9; 可执行程序中的虚拟地址&#x1fad9; 物理地址分布方式 &#x1fad9; 前言 在c/C中存在一种内存的概念; 一般来说一个内存的空间分布包括栈区,堆区,代码段等等; 且内存是…

Notes2024节气和日历来了

大家好&#xff0c;才是真的好。 还有三周就是2024年了。 2024的节假日安排其实早就发布&#xff0c;有些人已经把这些节假日安排都写在自己的日历上了&#xff1b;同时我们这里也设置了一份&#xff0c;包括节假日和农历二十四节气以及中西传统的节日日期等。 如果你需要的…

均匀分布的随机变量

如果连续型随机变量的概率密度满足如下公式&#xff1a; 那么就称在区间(a,b)上服从均匀分布&#xff0c;记为。

国际语音呼叫中心有什么功能特点?

国际语音呼叫中心的功能特点 智能客服 国际语音呼叫中心通过智能客服系统&#xff0c;可以为客户提供快捷、高效的服务。可以根据客户需求&#xff0c;自动回答部分常见问题&#xff0c;提高客户服务效率。 个性化定制 国际语音呼叫中心平台可以根据客户需求&#xff0c;为…

el-tree搜索的使用

2023.12.11今天我学习了如何对el-tree进行搜索的功能&#xff0c;效果如下&#xff1a; 代码如下&#xff1a; 重点部分&#xff1a;给el-tree设置ref&#xff0c;通过监听roleName的变化过滤数据。 default-expand-all可以设置默认展开全部子节点。 check可以拿到当前节点的…

线程安全集合类

文章目录 1. ConcurrentHashMap2. LinkedBlockingQueue 阻塞队列3. ConcurrentLinkedQueue4. CopyOnWriteArrayList JDK1.7 hashmap采用数组加链表头插的方式&#xff0c;在扩容时会出现循环死链问题&#xff0c;A->B->C扩容后C->B->A AB BA出现循环死链。 1. Conc…

msvcp140.dll丢失怎么办?这些方法值得一试

小编将探讨计算机系统中MSVCP140.DLL文件的重要性及其潜在的问题和相应的修复措施。此文件对实现软件应用的特定功能起着关键性的作用&#xff0c;当其丢失时&#xff0c;某些运行环境下的应用程序和游戏便无法正常运作。因此&#xff0c;了解并解决相关问题非常必要。 一、msv…