java文件上传时给pdf、word、excel、ppt、图片添加水印

前言

在开发的过程中,因为文件的特殊性,需要给pdf、word、excel、ppt、图片添加水印。添加水印可以在文件上传时添加,也可以在文件下载时添加。因为业务的某些原因,文件需要在浏览器预览,如果用户将文件另存为则无法添加水印,所以此文章主要介绍文件上传时添加水印。至于文件下载时添加水印功能也很简单,稍微修改即可。

一:文件上传

1.1 controller控制层

@ApiOperation("上传文件")@PostMapping("/file/upload")public String uploadFile(@RequestParam(value = "file") MultipartFile file) {if (file == null || file.isEmpty()) {throw new BusinessException("上传文件为空");}String originalFilename = file.getOriginalFilename();if (StringUtils.isBlank(originalFilename)) {throw new BusinessException("上传文件名为空");}String filePath = obsClientHelper.upload(file, file.getOriginalFilename());return filePath;}

1.2 文件上传到服务器

/*** 上传文件到服务器** @param uploadFile 文件* @param fileName   文件名称* @return 文件路径*/@SneakyThrowspublic String upload(MultipartFile uploadFile, String fileName) {String objectKey = directory + "/" + DATE_TIME_FORMATTER.format(LocalDate.now()) + "/" + UUID.randomUUID() + "/" + fileName;InputStream inputStream = null;//上传文件添加水印SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String watermark = UserContext.currentUser().getUserName() + "(" + UserContext.currentUser().getUserId() + ")" + "\n" + simpleDateFormat.format(new Date());if (fileName.endsWith("pdf")) {inputStream = PdfWatermarkUtils.addWatermarkInputStream(uploadFile.getInputStream(), new PdfWatermarkPageEventHelper(watermark));} else if (fileName.endsWith(ImageConstants.PICTURE_JPG) || fileName.endsWith(ImageConstants.PICTURE_PNG)) {inputStream = ImageWatermarkUtil.imgWatermarkInputStream(watermark, uploadFile.getInputStream(), -40);} else if (fileName.endsWith("docx") || fileName.endsWith("xlsx") || fileName.endsWith("pptx")) {TextWaterMarkDTO waterMarkDTO = new TextWaterMarkDTO(fileName, watermark);inputStream = OfficeWatermarkUtil.doMarkInputStream(uploadFile.getInputStream(), waterMarkDTO);} else {inputStream = uploadFile.getInputStream();}if (inputStream == null) {throw new RuntimeException("上传文件时,文件添加水印失败");}try (ObsClient obsClient = new ObsClient(ak, sk, endPoint)) {PutObjectResult putObjectResult = obsClient.putObject(bucketName, objectKey, inputStream);if (putObjectResult.getStatusCode() != HttpServletResponse.SC_OK) {throw new RuntimeException("文件上传失败,OBS响应码:" + putObjectResult.getStatusCode());}return putObjectResult.getObjectKey();} catch (IOException e) {throw new RuntimeException("文件上传失败", e);}}

二:PDF添加水印

2.1 引入依赖

<dependency><groupId>com.itextpdf</groupId><artifactId>kernel</artifactId><version>7.1.11</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>layout</artifactId><version>7.1.11</version></dependency><!--没有该包的话,会有中文显示问题--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.11</version></dependency>

2.2 PdfWatermarkUtils

/*** pdf加水印* @param inputStream 输入流* @param pdfPageEventHelper 水印* @return InputStream* @throws IOException*/public static InputStream addWatermarkInputStream(InputStream inputStream, PdfPageEventHelper pdfPageEventHelper) throws IOException {String watermarkText = ((PdfWatermarkPageEventHelper) pdfPageEventHelper).getWatermarkText();float fontSize = 13;int rowSpace = 150;int colSpace = 150;boolean linux = SystemUtil.getOsInfo().isLinux();String chineseFontPath = null;if (linux) {chineseFontPath = "/usr/share/fonts/STSONG.TTF";} else {chineseFontPath = SystemUtil.getUserInfo().getCurrentDir() + "\\fonts\\STSONG.TTF";}watermarkText = watermarkText.replace("\n", "  ");// 加载PDF文件PDDocument document = PDDocument.load(inputStream);document.setAllSecurityToBeRemoved(true);// 加载水印字体PDFont font = PDType0Font.load(document, new FileInputStream(chineseFontPath), true);// 遍历PDF文件,在每一页加上水印for (PDPage page : document.getPages()) {PDPageContentStream stream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);PDExtendedGraphicsState r = new PDExtendedGraphicsState();// 设置透明度r.setNonStrokingAlphaConstant(0.2f);r.setAlphaSourceFlag(true);stream.setGraphicsStateParameters(r);// 设置水印字体颜色stream.setStrokingColor(Color.GRAY);stream.beginText();stream.setFont(font, fontSize);stream.newLineAtOffset(0, -15);// 获取PDF页面大小float pageHeight = page.getMediaBox().getHeight();float pageWidth = page.getMediaBox().getWidth();// 根据纸张大小添加水印,30度倾斜for (int h = 10; h < pageHeight; h = h + rowSpace) {for (int w = -10; w < pageWidth; w = w + colSpace) {stream.setTextMatrix(Matrix.getRotateInstance(0.3, w, h));stream.showText(watermarkText);}}// 结束渲染,关闭流stream.endText();stream.restoreGraphicsState();stream.close();}return pdDocumentConvertorStream(document);}
/*** 将PDDocument转化为InputStream** @param document document* @return InputStream*/public static InputStream pdDocumentConvertorStream(PDDocument document) {try {//临时缓冲区ByteArrayOutputStream out = new ByteArrayOutputStream();document.save(out);document.close();return new ByteArrayInputStream(out.toByteArray());} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

三:图片添加水印

3.1 ImageWatermarkUtil

import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;@Component
@Slf4j
public class ImageWatermarkUtil {/*** 水印透明度*/private static final float ALPHA = 0.5f;/*** 水印文字大小*/public static final int FONT_SIZE = 23;/*** 水印文字字体*/private static Font FONT;/*** 水印文字颜色*/private static final Color COLOR = Color.white;/*** 水印之间的间隔*/private static final int X_MOVE = 60;/*** 水印之间的间隔*/private static final int Y_MOVE = 60;/*** 获取文本长度。汉字为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;}/*** 图片添加水印** @param logoText         水印内容* @param sourceFileStream 流文件* @param degree           倾斜角度* @return InputStream*/public static InputStream imgWatermarkInputStream(String logoText, InputStream sourceFileStream, Integer degree) {try {BufferedImage bufferedImage = addWatermark(logoText, sourceFileStream, degree);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "jpg", os);return new ByteArrayInputStream(os.toByteArray());} catch (IOException e) {return null;}}/*** 图片添加水印** @param logoText         水印内容* @param sourceFileStream 流文件* @param degree           倾斜角度* @return BufferedImage*/public static BufferedImage addWatermark(String logoText, InputStream sourceFileStream, Integer degree) throws IOException {//源图片Image srcImg = ImageIO.read(sourceFileStream);//原图宽度int width = srcImg.getWidth(null);//原图高度int height = srcImg.getHeight(null);BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),BufferedImage.TYPE_INT_RGB);// 得到画笔对象Graphics2D g = buffImg.createGraphics();// 设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH),0, 0, null);// 设置水印旋转if (null != degree) {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 = -width / 2;int y = -height / 2;// 字体长度int markWidth = FONT_SIZE * getTextLength(logoText);// 字体高度// 循环添加水印while (x < width * 1.5) {y = -height;while (y < height * 1.5) {String[] lines = logoText.split("\n");for (String line : lines) {g.drawString(line, x, y);y += FONT_SIZE + Y_MOVE;}}x += markWidth + X_MOVE;}// 释放资源g.dispose();return buffImg;}/*** 给图片添加水印文字、可设置水印文字的旋转角度** @param logoText         水印内容* @param sourceFileStream 输入流文件* @param targetFileStream 输出流文件* @param degree           倾斜角度*/public static void imageByText(String logoText, InputStream sourceFileStream, OutputStream targetFileStream, Integer degree) {if (Objects.isNull(FONT)) {FONT = new Font(FontUtil.firstZhSupportedFontName(), Font.BOLD, FONT_SIZE);}try {// 生成图片ImageIO.write(addWatermark(logoText, sourceFileStream, degree), "JPG", targetFileStream);log.info("图片-添加水印文字成功!");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != targetFileStream) {targetFileStream.close();}} catch (Exception e) {e.printStackTrace();}}}}

3.2 FontUtil

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import java.awt.*;
import java.util.Arrays;@Slf4j
public class FontUtil {private static String ZH_SUP;static {GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();char randomZh = '唐';Font[] allFonts = ge.getAllFonts();for (Font font : allFonts) {if(font.canDisplay(randomZh)){ZH_SUP = font.getFontName();break;}}if(StringUtils.isEmpty(ZH_SUP)){log.error("Zh supported font not found");ZH_SUP = allFonts[0].getFontName();}}public static String firstZhSupportedFontName(){return ZH_SUP;}public static java.util.List<String> getAllFontNames(){GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();String[] availableFontFamilyNames = ge.getAvailableFontFamilyNames();return Arrays.asList(availableFontFamilyNames);}
}

四:docx、xlsx、pptx添加水印

注:ppt、xls、doc由于版本新旧问题,此处先不介绍添加水印方法

4.1 TextWaterMarkDTO

import com.FontUtil;
import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class TextWaterMarkDTO{public TextWaterMarkDTO() {this.fontName = FontUtil.firstZhSupportedFontName();}public TextWaterMarkDTO(String fileName,String text) {this.fontName = FontUtil.firstZhSupportedFontName();this.fileSuffix = loadFileSuffix(fileName);this.text = text;}String fileSuffix;private String text;private String fontName;private String fontColor;private Integer fontSize = 20;private Integer rotation = -20;Integer intervalHorizontal;Integer intervalVertical;Integer picWidth;Integer picHeight;Float alpha;boolean enable;private String loadFileSuffix(String fileName){String realName = fileName.trim();int index = realName.lastIndexOf(".");if( index < 0){return null;}return fileName.substring(index + 1);}}

4.2 doMarkInputStream

/*** 添加文件水印,返回InputStream** @param input         输入流* @param waterMarkInfo waterMarkInfo* @return InputStream*/public static InputStream doMarkInputStream(InputStream input, TextWaterMarkDTO waterMarkInfo) {InputStream inputStream = null;try {String fileSuffix = waterMarkInfo.getFileSuffix().toLowerCase();switch (fileSuffix) {case "docx":inputStream = docxWaterMarkInputStream(input, waterMarkInfo);break;case "xlsx":log.info("xlsx");inputStream = xlsxWaterMarkInputStream(input, waterMarkInfo.setPicWidth(1000).setPicHeight(2000));break;case "pptx":log.info("pptx");inputStream = pptxAddWatermarkInputStream(input, waterMarkInfo);break;default:log.info("in default. fileSuffix:{}", fileSuffix);inputStream = input;}return inputStream == null ? input : inputStream;} catch (Exception e) {log.error(ExceptionUtil.stacktraceToString(e));return null;} finally {close(input);}}

4.3 docx

@SneakyThrowsprivate static InputStream docxWaterMarkInputStream(InputStream input, TextWaterMarkDTO waterMarkInfo) {XWPFDocument docx = new XWPFDocument(input);//设置默认值String watermark = StringUtils.isBlank(waterMarkInfo.getText()) ? DEFAULT_WATERMARK : waterMarkInfo.getText();String color = StringUtils.isBlank(waterMarkInfo.getFontColor()) ? DEFAULT_FONT_COLOR : "#" + waterMarkInfo.getFontColor();String fontSize = (null == waterMarkInfo.getFontSize()) ? FONT_SIZE : waterMarkInfo.getFontSize() + "pt";String rotation = (null == waterMarkInfo.getRotation()) ? STYLE_ROTATION : String.valueOf(waterMarkInfo.getRotation());DocxUtil.makeFullWaterMarkByWordArt(docx, watermark, color, fontSize, rotation);//将XWPFDocument转化为InputStreamreturn convertToInputStream(docx);}
/*** 将XWPFDocument转化为InputStream** @param doc XWPFDocument* @return InputStream*/public static InputStream convertToInputStream(XWPFDocument doc) {try {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();doc.write(outputStream);return new ByteArrayInputStream(outputStream.toByteArray());} catch (IOException e) {log.error(e.getMessage(), e);return null;}}

4.4 xlsx

@SneakyThrowsprivate static InputStream xlsxWaterMarkInputStream(InputStream input, TextWaterMarkDTO waterMark) {XSSFWorkbook workbook = new XSSFWorkbook(input);Iterator<Sheet> iterator = workbook.sheetIterator();BufferedImage image = FontImage.createWatermarkImageFillWithText(waterMark);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);while (iterator.hasNext()) {XSSFSheet sheet = (XSSFSheet) iterator.next();String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();//set background picture to sheetsheet.getCTWorksheet().addNewPicture().setId(rID);}//将XSSFWorkbook转化为InputStreamreturn workbookConvertorStream(workbook);}
/*** 将XSSFWorkbook转化为InputStream** @param workbook XSSFWorkbook* @return InputStream*/public static InputStream workbookConvertorStream(XSSFWorkbook workbook) {try {//临时缓冲区ByteArrayOutputStream out = new ByteArrayOutputStream();//创建临时文件workbook.write(out);byte[] bookByteAry = out.toByteArray();return new ByteArrayInputStream(bookByteAry);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

4.5 pptx

@SneakyThrowsprivate static InputStream pptxAddWatermarkInputStream(InputStream input, TextWaterMarkDTO waterMarkDto) {XMLSlideShow slideShow = new XMLSlideShow(input);waterMarkDto.setPicWidth(Double.valueOf(slideShow.getPageSize().width).intValue());waterMarkDto.setPicHeight(Double.valueOf(slideShow.getPageSize().height).intValue());BufferedImage image = FontImage.createWatermarkImageFillWithText(waterMarkDto);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);PictureData pictureData1 = slideShow.addPicture(os.toByteArray(), PictureData.PictureType.PNG);for (XSLFSlide slide : slideShow.getSlides()) {XSLFPictureShape pictureShape = slide.createPicture(pictureData1);pictureShape.setAnchor(new Rectangle(0, 0, slideShow.getPageSize().width, slideShow.getPageSize().height));}return xmlSlideShowConvertorStream(slideShow);}
/*** 将XMLSlideShow转化为InputStream** @param slideShow slideShow* @return InputStream*/public static InputStream xmlSlideShowConvertorStream(XMLSlideShow slideShow) {try {//临时缓冲区ByteArrayOutputStream out = new ByteArrayOutputStream();//创建临时文件slideShow.write(out);byte[] bookByteAry = out.toByteArray();return new ByteArrayInputStream(bookByteAry);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

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

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

相关文章

算法与数据结构汇总

基本 数组 字符串 排序 矩阵 模拟 枚举 字符串匹配 桶排序 计数排序 基数排序 回文&#xff1a;中心扩展 马拉车 树上启发式合并 括号 数学表达式 字符串&#xff1a;前后缀分解。 贡献法 分组&#xff1a; 【状态机dp 状态压缩 分组】1994. 好子集的数目 【动态规划】【前缀…

Excel中sum的跨表求和

#实际工作中&#xff0c;一个xlsx文件中会包含多个Excel表格&#xff0c;一般会有“总-分”的关系&#xff0c;如何把分表里的数字汇总到总表里呢&#xff1f; 一般有上图所示的两种表达方式。 可以使用通配符 *&#xff1a;代表任意个数、任意字符&#xff1b; &#xff1f;&…

51单片机的最小系统详解

51单片机的最小系统详解 1. 引言 在嵌入式系统中,51单片机被广泛应用于各种小型控制器和嵌入式开发板中。相信很多人都接触过51单片机,但是对于51单片机的最小系统却了解得不够深入。本文将从振荡电路、电源模块、复位电路、LED指示灯和调试接口五个方面详细介绍51单片机的…

quartz定时任务

Quartz 数据结构 quartz采用完全二叉树&#xff1a;除了最后一层每一层节点都是满的&#xff0c;而且最后一层靠左排列。 二叉树节点个数规则&#xff1a;每层从左开始&#xff0c;第一层只有一个&#xff0c;就是2的0次幂&#xff0c;第二层两个就是2的1次幂&#xff0c;第三…

DOS学习-目录与文件应用操作经典案例-attrib

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统中的attrib命令是一个用于显示或更改文件&#…

设计模式——职责链(责任链)模式

目录 职责链模式 小俱求实习 结构图 实例 职责链模式优点 职责链模式缺点 使用场景 1.springmvc流程 ​2.mybatis的执行流程 3.spring的过滤器和拦截器 职责链模式 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成…

github设置项目分类

https://www.php.cn/faq/541957.html https://docs.github.com/zh/repositories/working-with-files/managing-files/creating-new-files

什么是回表,如何解决回表问题

下面表中:主键id是聚簇索引&#xff0c;name是辅助索引。 执行这样一条SQL: select name from A where name"s;name字段是有索引&#xff0c;所以MYSQL在通过name进行査询的时候&#xff0c;是需要扫描两颗Btree树的。 第一遍:先通过二级索引定位主键值1。第二遍:根据主键…

免费发布web APP的四个途径(Python和R)

免费发布数据分析类&#x1f310;web APP的几个途径&#x1f4f1; 数据分析类web APP目前用来部署生信工具&#xff0c;统计工具和预测模型等&#xff0c;便利快捷&#xff0c;深受大家喜爱。而一个免费的APP部署途径&#xff0c;对于开发和测试APP都是必要的。根据笔者的经验…

word-形状绘制、smartart、visio

一、人员架构图绘制 小技巧&#xff1a; 1、ctrlshift水平复制 2、点击图形&#xff0c;右键设置为默认形状 3、插入-形状-右键-锁定绘图模式&#xff0c;按esc退出状态 4、插入-形状-新建绘图画布&#xff0c;代替组合问题 画布中存在锚点&#xff0c;便于直线连接 二、s…

网络安全相关面试题(hw)

网络安全面试题 报错注入有哪些函数 updatexml注入 载荷注入 insert注入 updata注入 delete注入 extractvalue&#xff08;&#xff09;注入 注入防御方法 涵数过滤 直接下载相关防范注入文件&#xff0c;通过incloud包含放在网站配置文件里面 PDO预处理,从PHP 5.1开始&…

electron中BrowserWindow的show事件没有触发踩坑记录

class ElectronApi {static mainWindow;//主窗口createWindow() {try {// Create the browser window.this.mainWindow new BrowserWindow({width: 1200,height: 800,minHeight: 800,minWidth: 1200,webPreferences: {preload: preloadPath,// nodeIntegration: true,// conte…

windows怎么复制文件到vmware 中ubantu虚拟机,vmware中的虚拟机怎么联网,NAT参数和DHCP参数。

目录 windows怎么复制文件到vmware 中ubantu虚拟机 vmware中的虚拟机怎么联网 NAT参数和DHCP参数。

Linux环境Docker安装,使用Docker搭建Mysql服务实战

1、环境&#xff1a;阿里云Linxu服务器 2、安装docker # 1、yum 包更新到最新 yum update # 2、安装需要的软件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外两个是devicemapper驱动依赖的 yum install -y yum-utils device-mapper-persistent-data…

OpenSSL之API编程 - C/C++实现AES、DES、3DES、SM4对称加密算法

文章介绍 本文章介绍了OpenSSL计算对称加解密算法(AES、DES、3DES、SM4等)的相关接口&#xff0c;并使用C语言实现了AES和SM4加解密。 对称加解密算法 对称加密与非对称加密算法 OpenSSL介绍 openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有&#xff…

深度学习之基于YOLOV5的口罩检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着全球公共卫生事件的频发&#xff0c;口罩成为了人们日常生活中不可或缺的一部分。在公共场所&am…

10、SpringBoot 源码分析 - 自动配置深度分析三

SpringBoot 源码分析 - 自动配置深度分析三 refresh和自动配置大致流程AutoConfigurationImportSelector的getAutoConfigurationEntry获取自动配置实体(重点)AutoConfigurationImportSelector的getCandidateConfigurations获取EnableAutoConfiguration类型的名字集合AutoConfig…

Android中JVM内存回收机制

文章目录 分代收集算法&#xff1a;新生代&#xff08;Young Generation&#xff09;老年代&#xff08;Old Generation&#xff09; 垃圾回收器&#xff1a;JVM常见三大回收算法&#xff1a;Mark-Sweep(标记清除)优点:缺点: 复制算法优点&#xff1a;缺点&#xff1a; Mark-Co…

ubuntu下交叉编译安卓FFmpeg 和 官方指导链接

将之前的编译方法在此记录 Linux系统&#xff1a;Ubuntu 18.04.6 LTS 交叉编译工具链&#xff1a;gcc-aarch64-linux-gnu gaarch64-linux-gnu ffmpeg版本&#xff1a;5.1.3 1.下载源码 ffmpeg官网&#xff1a;https://ffmpeg.org/download.html#releases 下载完成后&#x…

Edge浏览器“此页存在问题”解决思路

Edge浏览器显示“此页存在问题”解决思路 大家平时使用Edge浏览器时&#xff0c;是否和我一样会突然出现“此页存在问题”的情况&#xff1f; 经过百度查询后我找了一种情况和解决办法&#xff0c;能够大大减少这类问题的出现。出现“此页存在问题”可能是因为之前使用过软件…