Java 实现 图片 添加 文字水印、图片水印 工具类

一、话不多说,直接上代码

1.1,水印类型枚举

import lombok.AllArgsConstructor;
import lombok.Getter;/*** @author: wangjing* @createTime: 2023-12-05 15:01* @version: 1.0.0* @Description: 水印类型枚举*/
@Getter
@AllArgsConstructor
@SuppressWarnings("AlibabaEnumConstantsMustHaveComment")
public enum WatermarkTypeEnum {TEXT_WATERMARK(1, "文字水印"),IMAGE_WATERMARK(2, "图片水印");private final Integer code;private final String msg;public static WatermarkTypeEnum matchCode(Integer code) {for (WatermarkTypeEnum watermarkTypeEnum : WatermarkTypeEnum.values()) {if (code.equals(watermarkTypeEnum.getCode())) {return watermarkTypeEnum;}}return null;}}

1.2,图片水印位置类型枚举

import lombok.AllArgsConstructor;
import lombok.Getter;/*** @author: wangjing* @createTime: 2023-12-05 15:01* @version: 1.0.0* @Description: 图片水印位置类型枚举*/
@Getter
@AllArgsConstructor
@SuppressWarnings("AlibabaEnumConstantsMustHaveComment")
public enum ImageWatermarkPositionTypeEnum {/*** 九方位*/CENTER(1, "居中"),LEFT_SIDE(2, "左侧"),RIGHT_SIDE(3, "右侧"),DIRECTLY_ABOVE(4, "正上方"),DIRECTLY_BELOW(5, "正下方"),UPPER_LEFT(6, "左上角"),LOWER_LEFT(7, "左下角"),UPPER_RIGHT(8, "右上方"),LOWER_RIGHT(9, "右下方"),/*** 平铺*/TILE(10, "平铺水印"),TILT_TILE(11, "倾斜平铺");private final Integer code;private final String msg;public static ImageWatermarkPositionTypeEnum matchCode(Integer code) {for (ImageWatermarkPositionTypeEnum imageWatermarkPositionTypeEnum : ImageWatermarkPositionTypeEnum.values()) {if (code.equals(imageWatermarkPositionTypeEnum.getCode())) {return imageWatermarkPositionTypeEnum;}}return null;}}

1.3,图片水印处理类

import cn.piesat.space.watermark.enums.ImageWatermarkPositionTypeEnum;
import cn.piesat.space.watermark.enums.WatermarkTypeEnum;
import lombok.Data;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;/*** @author: wangjing* @createTime: 2023-12-05 15:01* @version: 1.0.0* @Description: 图片水印处理类*/
public class ImageWatermarkUtil {/*** 水印信息对象*/@Datastatic class WatermarkInfo {BufferedImage watermarkBufferedImage;Integer watermarkWidth;Integer watermarkHeight;}/*** 获取水印信息并对画布做基础配置** @param graphics* @param watermarkType* @param watermark* @param font* @param color* @return*/public static WatermarkInfo getWatermarkInfo(Graphics2D graphics, Integer watermarkType, String watermark,Font font, Color color) {WatermarkInfo watermarkInfo = new WatermarkInfo();// 文字水印if (WatermarkTypeEnum.TEXT_WATERMARK.getCode().equals(watermarkType)) {// 设置字体graphics.setFont(font);// 设置颜色graphics.setColor(color);watermarkInfo.setWatermarkWidth(getWatermarkLength(watermark, graphics));watermarkInfo.setWatermarkHeight(font.getSize());} else {// 图片水印BufferedImage对象BufferedImage watermarkBufferedImage = readPicture(watermark);watermarkInfo.setWatermarkBufferedImage(watermarkBufferedImage);watermarkInfo.setWatermarkWidth(watermarkBufferedImage.getWidth());watermarkInfo.setWatermarkHeight(watermarkBufferedImage.getHeight());}return watermarkInfo;}/*** 添加水印** @param bufferedImage              源文件* @param font                       字体* @param color                      颜色* @param watermarkType              水印类型(具体见 WatermarkTypeEnum 枚举类)* @param imageWatermarkPositionType 水印位置(具体见 ImageWatermarkPositionType)* @param watermark                  水印(文字或图片地址)* @return*/public static BufferedImage addWatermark(BufferedImage bufferedImage, Font font, Color color, Integer watermarkType,Integer imageWatermarkPositionType, String watermark) {// 图片宽度Integer imageWidth = bufferedImage.getWidth();// 图片高度Integer imageHeight = bufferedImage.getHeight();// 创建画笔Graphics2D graphics = bufferedImage.createGraphics();WatermarkInfo watermarkInfo = getWatermarkInfo(graphics, watermarkType, watermark, font, color);switch (ImageWatermarkPositionTypeEnum.matchCode(imageWatermarkPositionType)) {// 居中case CENTER:centerCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;// 左侧case LEFT_SIDE:leftSideCompute(graphics, imageHeight, watermarkInfo, watermarkType, watermark);break;// 右侧case RIGHT_SIDE:rightSideCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;// 正上方case DIRECTLY_ABOVE:directlyAboveCompute(graphics, imageWidth, watermarkInfo, watermarkType, watermark);break;// 正下方case DIRECTLY_BELOW:directlyBelowCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;// 左上角case UPPER_LEFT:upperLeftCompute(graphics, watermarkInfo, watermarkType, watermark);break;// 左下角case LOWER_LEFT:lowerLeftCompute(graphics, imageHeight, watermarkInfo, watermarkType, watermark);break;// 右上角case UPPER_RIGHT:upperRightCompute(graphics, imageWidth, watermarkInfo, watermarkType, watermark);break;// 右下角case LOWER_RIGHT:lowerRightCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;// 右下角case TILE:tileDrawCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;// 右下角case TILT_TILE:// 倾斜度graphics.rotate(0.2);tileDrawCompute(graphics, imageWidth, imageHeight, watermarkInfo, watermarkType, watermark);break;default: // 错误的操作类型throw new RuntimeException("错误的操作类型");}graphics.dispose();return bufferedImage;}/*** 居中 配置** @param graphics* @param imageWidth* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void centerCompute(Graphics2D graphics, Integer imageWidth, Integer imageHeight,WatermarkInfo watermarkInfo, Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = (imageWidth - watermarkInfo.getWatermarkWidth()) / 2;Integer y = imageHeight / 2 + (watermarkInfo.getWatermarkHeight() / 2);drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 左侧 配置** @param graphics* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void leftSideCompute(Graphics2D graphics, Integer imageHeight, WatermarkInfo watermarkInfo,Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = 0;Integer y = (imageHeight + watermarkInfo.getWatermarkHeight()) / 2;drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 右侧配置** @param graphics* @param imageWidth* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void rightSideCompute(Graphics2D graphics, Integer imageWidth, Integer imageHeight,WatermarkInfo watermarkInfo, Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = imageWidth - watermarkInfo.getWatermarkWidth();Integer y = (imageHeight + watermarkInfo.getWatermarkHeight()) / 2;drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 正上方配置** @param graphics* @param imageWidth* @param watermarkInfo* @param watermarkType* @param watermark*/public static void directlyAboveCompute(Graphics2D graphics, Integer imageWidth, WatermarkInfo watermarkInfo,Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = (imageWidth - watermarkInfo.getWatermarkWidth()) / 2;Integer y = watermarkInfo.getWatermarkHeight();drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 正下方** @param graphics* @param imageWidth* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void directlyBelowCompute(Graphics2D graphics, Integer imageWidth, Integer imageHeight,WatermarkInfo watermarkInfo, Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = (imageWidth - watermarkInfo.getWatermarkWidth()) / 2;Integer y = imageHeight;drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 左上角** @param graphics* @param watermarkInfo* @param watermarkType* @param watermark*/public static void upperLeftCompute(Graphics2D graphics, WatermarkInfo watermarkInfo, Integer watermarkType,String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = 0;Integer y = watermarkInfo.getWatermarkHeight();drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 左下角** @param graphics* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void lowerLeftCompute(Graphics2D graphics, Integer imageHeight, WatermarkInfo watermarkInfo,Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = 0;Integer y = imageHeight;drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 右上方** @param graphics* @param imageWidth* @param watermarkInfo* @param watermarkType* @param watermark*/public static void upperRightCompute(Graphics2D graphics, Integer imageWidth, WatermarkInfo watermarkInfo,Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = imageWidth - watermarkInfo.getWatermarkWidth();Integer y = watermarkInfo.getWatermarkHeight();drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 右下方** @param graphics* @param imageWidth* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void lowerRightCompute(Graphics2D graphics, Integer imageWidth, Integer imageHeight,WatermarkInfo watermarkInfo, Integer watermarkType, String watermark) {// 设置水印的坐标(为原图片中间位置)Integer x = imageWidth - watermarkInfo.getWatermarkWidth();Integer y = imageHeight;drawTestOrImage(graphics, x, y, watermarkType, watermark, watermarkInfo);}/*** 平铺** @param graphics* @param imageWidth* @param imageHeight* @param watermarkInfo* @param watermarkType* @param watermark*/public static void tileDrawCompute(Graphics2D graphics, Integer imageWidth, Integer imageHeight,WatermarkInfo watermarkInfo, Integer watermarkType, String watermark) {Integer watermarkHeight = watermarkInfo.getWatermarkHeight();Integer watermarkWidth = watermarkInfo.getWatermarkWidth();// 间隔Integer split = watermarkHeight * 2;// x,y可以绘制的数量,多加一个补充空白int xCanNum = imageWidth / watermarkWidth + 1;int yCanNum = imageHeight / watermarkHeight + 1;for (int i = 1; i <= yCanNum; i++) {int y = watermarkHeight * i + split * i;for (int j = 0; j < xCanNum; j++) {int x = watermarkWidth * j + split * j;drawTestOrImage(graphics, x, y - (watermarkHeight + split) * j, watermarkType, watermark,watermarkInfo);}}}/*** 画文字水印或图片水印** @param graphics* @param x* @param y* @param watermarkType* @param watermark* @param watermarkInfo*/public static void drawTestOrImage(Graphics2D graphics, int x, int y, Integer watermarkType, String watermark,WatermarkInfo watermarkInfo) {// 文字水印if (WatermarkTypeEnum.TEXT_WATERMARK.getCode().equals(watermarkType)) {graphics.drawString(watermark, x, y);} else {// 图片水印graphics.drawImage(watermarkInfo.getWatermarkBufferedImage(), x, y - watermarkInfo.getWatermarkHeight(), watermarkInfo.getWatermarkWidth(),watermarkInfo.getWatermarkHeight(), null);}}/*** 获取水印文字的长度** @param watermarkContent 文字水印内容* @param graphics         图像类* @return*/private static Integer getWatermarkLength(String watermarkContent, Graphics2D graphics) {return graphics.getFontMetrics(graphics.getFont()).charsWidth(watermarkContent.toCharArray(), 0,watermarkContent.length());}/*** 将图片写入到指定位置** @param bufImg* @param tarImgPath*/public static void writeImage(BufferedImage bufImg, String tarImgPath) {// 输出图片try {FileOutputStream outImgStream = new FileOutputStream(tarImgPath);ImageIO.write(bufImg, "png", outImgStream);outImgStream.flush();outImgStream.close();} catch (IOException e) {throw new RuntimeException(e);}}/*** 读取图片** @param path* @return*/public static BufferedImage readPicture(String path) {try {// 尝试获取本地return readLocalPicture(path);} catch (Exception e) {// 尝试获取网路return readNetworkPicture(path);}}/*** 读取本地图片** @param path* @return*/public static BufferedImage readLocalPicture(String path) {if (null == path) {throw new RuntimeException("本地图片路径不能为空");}// 读取原图片信息 得到文件File srcImgFile = new File(path);try {// 将文件对象转化为图片对象return ImageIO.read(srcImgFile);} catch (IOException e) {throw new RuntimeException(e);}}/*** 读取网络图片** @param path 网络图片地址*/public static BufferedImage readNetworkPicture(String path) {if (null == path) {throw new RuntimeException("网络图片路径不能为空");}try {// 创建一个URL对象,获取网络图片的地址信息URL url = new URL(path);// 将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)BufferedImage bugImg = ImageIO.read(url.openStream());if (null == bugImg) {throw new RuntimeException("网络图片地址不正确");}return bugImg;} catch (IOException e) {throw new RuntimeException(e);}}/*** 文字类型测试* @param args*/public static void main(String[] args) {// 要处理的图片路径:String localPath = "/Users/wangjing/Desktop/watermark/image/test1.jpg";// 定义存储的地址String tarImgPath = "/Users/wangjing/Desktop/watermark/image/";// 文字水印内容String textWatermark = "刘亦菲";// 根据图片的背景设置水印颜色Color color = new Color(255, 255, 255, 128);// 设置字体  画笔字体样式为微软雅黑,加粗,文字大小为45ptFont font = new Font("微软雅黑", Font.BOLD, 45);for (int i = 1; i < 12; i++) {BufferedImage bufferedImage = readPicture(localPath);BufferedImage test = addWatermark(bufferedImage, font, color, WatermarkTypeEnum.TEXT_WATERMARK.getCode(),i, textWatermark);writeImage(test, tarImgPath + "watermark_text_" + i + ".jpg");}}/*** 图片水印测试** @param args*/
//    public static void main(String[] args) {
//
//        // 要处理的图片路径:
//        String localPath = "https://vrar-obs-production.obs.cn-north-4.myhuaweicloud.com/survey/watermark/image.jpg";
//
//        // 定义存储的地址
//        String tarImgPath = "/Users/wangjing/Desktop/watermark/image/";
//
//        // 图片水印内容
//        String textWatermark = "https://vrar-obs-production.obs.cn-north-4.myhuaweicloud" +
//                ".com/survey/watermark/watermark.png";
//
//
//        for (int i = 1; i < 12; i++) {
//            BufferedImage bufferedImage = readPicture(localPath);
//            BufferedImage test = addWatermark(bufferedImage, null, null, WatermarkTypeEnum.IMAGE_WATERMARK.getCode(), i,
//                    textWatermark);
//            writeImage(test, tarImgPath + "watermark_image_" + i + ".jpg");
//        }
//    }}

二、看效果

2.1,原图

2.2,文字水印生成效果

2.3,水印图片

2.4,图片水印生成效果

注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!

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

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

相关文章

「Verilog学习笔记」状态机-重叠序列检测

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 读入数据移位寄存&#xff0c;寄存后的数据与序列数做对比&#xff0c;相等则flag为1&#xff0c;不等则为0 timescale 1ns/1nsmodule sequence_test2(input wire clk ,in…

java单人聊天

服务端 package 单人聊天;import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import…

拼多多商品详情API:构建高效电子商务解决方案

一、引言 随着互联网的快速发展&#xff0c;电子商务行业正在迅速崛起&#xff0c;其中拼多多以其独特的商业模式和创新的商品详情API&#xff0c;成为了行业内的佼佼者。本文将深入探讨拼多多商品详情API的技术特点、实现方式及其在电子商务解决方案中的应用。 二、拼多多商…

【PyTorch】模型选择、欠拟合和过拟合

文章目录 1. 理论介绍2. 实例解析2.1. 实例描述2.2. 代码实现2.2.1. 完整代码2.2.2. 输出结果 1. 理论介绍 将模型在训练数据上拟合的比在潜在分布中更接近的现象称为过拟合&#xff0c; 用于对抗过拟合的技术称为正则化。训练误差和验证误差都很严重&#xff0c; 但它们之间差…

计算两个结构的差

平面上有6个点&#xff0c;以6a1的方式运动 1 1 1 1 - - - 1 - - - 1 现在有一个点逃逸&#xff0c;剩下的5个点将如何运动&#xff1f; 2 2 2 3 - - - 3 - - - 3 将6a1的6个点减去1个点&#xff0c;只有两种可能&#xff0c;或者变成5a2&#xff0c…

SpringBoot的配置加载优先级

目录 一、背景分析 二、学习资源 三、具体使用 四、一些小技巧 方式一 方式二 一、背景分析 SpringBoot项目在打包之后&#xff0c;其配置文件就在jar包内&#xff0c;如果没有<配置文件优先级>这个机制&#xff0c;那么项目打成jar包之后&#xff0c;如果启动项目…

视频监控管理平台/智能监测/检测系统EasyCVR智能地铁监控方案,助力地铁高效运营

近日&#xff0c;关于全国44座城市开通地铁&#xff0c;却只有5座城市赚钱的新闻冲上热搜。地铁作为城市交通的重要枢纽&#xff0c;是人们出行必不可少的一种方式&#xff0c;但随着此篇新闻的爆出&#xff0c;大家也逐渐了解到城市运营的不易&#xff0c;那么&#xff0c;如何…

目标检测——SPPNet算法解读

论文&#xff1a;Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 作者&#xff1a;Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun 链接&#xff1a;https://arxiv.org/abs/1406.4729 目录 1、算法概述2、Deep Networks with Spatia…

适用于 Windows 的 10 个顶级分区管理器软件

您想要对硬盘驱动器或 USB 驱动器进行分区的原因可能有多种。许多用户希望对其外部和内部硬盘驱动器进行分区以有效地管理数据。为了处理分区&#xff0c;Windows为用户提供了一个内置的分区管理工具。 Windows 用户可以通过磁盘管理面板对任何驱动器进行分区。然而&#xff0…

哪种超声波清洗眼镜不伤镜片?超声波什么牌子好?眼镜清洗机推荐

戴眼镜的朋友就能够感同身受&#xff0c;眼镜佩戴一天真的特别容易脏&#xff0c;灰尘或者是脸部出汗出油等&#xff0c;让耳机惨不忍睹&#xff01;对于眼镜清洗的方式也有很多种&#xff0c;那么到底哪种清洗方式才是真正有效果并且不伤眼镜的呢&#xff1f;跟随笔者的脚步来…

安装Kuboard管理K8S集群

目录 第一章.安装Kuboard管理K8S集群 1.安装kuboard 2.绑定K8S集群&#xff0c;完成信息设定 3.内网安装 第二章.kuboard-spray安装K8S 2.1.先拉镜像下来 2.2.之后打开后&#xff0c;先熟悉功能&#xff0c;注意版本 2.3.打开资源包管理&#xff0c;选择符合自己服务器…

Python-Opencv图像处理的小坑

1.背景 最近在做一点图像处理的事情&#xff0c;在做处理时的cv2遇到一些小坑&#xff0c;希望大家遇到的相关的问题可以注意&#xff01;&#xff01; 2. cv2.imwrite保存图像 cv2.imwrite(filename, img, [params]) filename&#xff1a;需要写入的文件名&#xff0c;包括路…

快速排序并不难

快速排序的核心框架是“二叉树的前序遍历对撞型双指针”。我们在《一维数组》一章提到过”双指针思路“&#xff1a;在处理奇偶等情况时会使用两个游标&#xff0c;一个从前向后&#xff0c;一个是从后向前来比较&#xff0c;根据结果来决定继续移动还是停止等待。快速排序的每…

医院信息系统源码,采用JAVA编程,支持跨平台部署应用,满足一级综合医院(专科二级及以下医院500床)的日常业务应用

医院HIS系统源码&#xff0c;HIS系统全套源码&#xff0c;支持电子病历4级&#xff0c;自主版权 his医院信息系统内设门诊/住院医生工作站、门诊/住院护士工作站。各工作站主要功能依据职能要求进行研发。如医生工作站主要功能为编辑电子病历、打印、处理医嘱&#xff1b;护士工…

总结|哪些平台有大模型知识库的Web API服务

截止2023/12/6 笔者个人的调研&#xff0c;有三家有大模型知识库的web api服务&#xff1a; 平台类型文档数量文档上传并解析的结构api情况返回页码文心一言插件版多文档有问答api&#xff0c;文档上传是通过网页进行上传有&#xff0c;而且是具体的chunk id&#xff0c;需要设…

“消费增值:改变你的购物方式,让每一笔消费都变得更有价值“

你是否厌倦了仅仅购买物品或享受服务后便一无所有的消费方式&#xff1f;现在&#xff0c;消费增值的概念将彻底改变你的消费观念&#xff01;通过参与消费增值&#xff0c;你的每一笔消费都将变得更有价值&#xff01; 消费增值是一种全新的消费理念&#xff0c;它让你在购物的…

星闪的三层架构

在数字化转型的浪潮中&#xff0c;物联网技术正成为连接世界的纽带&#xff0c;将各种智能设备融为一个无缝的整体。而在这个大背景下&#xff0c;星闪崭露头角&#xff0c;将成为连接未来的关键枢纽。本文将介绍星闪系统的三层架构&#xff0c;包括基础应用层、基础服务层和星…

面向AI开发的六种最重要的编程语言

在AI开发界&#xff0c;你使用的编程语言很重要。每种语言有其独特的特性。选择合适的语言不是关乎个人偏好的问题&#xff0c;而是影响你如何构建和启动AI系统的关键决定。无论你在AI方面有无经验&#xff0c;选择一种合适的语言来学习至关重要。合适的语言将帮助你创建功能强…

一文带你快速了解Python史上最快Web框架

文章目录 1. 写在前面2. Sanic框架简介2.1 背景2.2 特征与优势 3. Sanic框架实战3.1. 安装Sanic3.2. Demo案例编写 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&a…

NVRAM相关

1. Modem NVRAM四个分区 nvdata&#xff1a;手机运行过程中&#xff0c;使用(读写)的NVRAM(除了存在protect_f和protect_s中的NVRAM)都是该分区的nvram文件。存储着普通NVRAM数据、 IMEI、barcode、Calibration数据等。对应的modem path是Z:\NVRAM。NVRAM目录下有CALIBRAT、NVD…