java后端给图片添加水印(斜体水印),并且上传到minio

一、项目大致需求,前端上传图片,后端接收到图片之后,给图片添加水印,之后后端把图片上传到minio,然后把图片地址返回给前端。

其实就是图片上传minio,中间多了一步后端添加水印。直接上源码

/**
*图片上传接口,为了扩展,添加了boolean 类型的参数,true是需要加水印,false不需要加水印
*
*/
@PostMapping("/put-file-attach-copy")
public R putFileAttachCopy(@RequestParam MultipartFile file,@RequestParam Boolean copy) {
    String fileName = file.getOriginalFilename();
    if(copy){
       BufferedImage bufferedImage = convertToBufferedImage(file);
       ByteArrayOutputStream watermarkedStream = FullWatermarkHandler.addWatermark(bufferedImage, "水印文字");
       BladeFile bladeCopyFile = ossBuilder.template().putFile(fileName, convert(watermarkedStream, fileName + "gfscw", "image/png").getInputStream());
       Long copyOriginalFileId = buildAttach(fileName, file.getSize(), bladeCopyFile);
       bladeCopyFile.setAttachId(copyOriginalFileId);
       return R.data(bladeCopyFile);
    }
    BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
    Long originalFileId = buildAttach(fileName, file.getSize(), bladeFile);
    bladeFile.setAttachId(originalFileId);
    return R.data(bladeFile);
}

BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());

这一句就是上传minio,相当于minioclient.put()。。。。。。。这儿就不写了。应该都会

/**
*转字节流
*
*/
public static MockMultipartFile convert(ByteArrayOutputStream byteArrayOutputStream, String originalFilename, String contentType) throws IOException {
    return new MockMultipartFile(
       "file",
       originalFilename,
       contentType,
       new ByteArrayInputStream(byteArrayOutputStream.toByteArray())
    );
}




public  BufferedImage convertToBufferedImage(MultipartFile file) throws IOException {
    try (InputStream inputStream = file.getInputStream()) {
       return ImageIO.read(inputStream);
    }
}

最后是工具类

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class FullWatermarkHandler {


	/**
	 * @description
	 * @param originalImage 源图片路径
	 * @param watermarkText 水印内容
	 * @return void
	 */
	public static ByteArrayOutputStream  addWatermark(BufferedImage originalImage, String watermarkText){
		Font font = new Font("新宋体", Font.BOLD, 24);//水印字体,大小
		Color markContentColor = Color.yellow;//水印颜色
		Integer degree = -45;//设置水印文字的旋转角度
		float alpha = 1.0f;//设置水印透明度 默认为1.0  值越小颜色越浅
		ByteArrayOutputStream outputStream = null;
		try {
			int srcImgWidth = originalImage.getWidth(null);//获取图片的宽
			int srcImgHeight = originalImage.getHeight(null);//获取图片的高
			// 加水印
			BufferedImage bufferedImage = new BufferedImage(
				srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = bufferedImage.createGraphics();//得到画笔
			g.drawImage(originalImage, 0, 0, srcImgWidth, srcImgHeight, null);
			g.setColor(markContentColor); //设置水印颜色
			g.setFont(font);              //设置字体
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度
			if (null != degree) {
				g.rotate(Math.toRadians(degree), bufferedImage.getWidth(), bufferedImage.getHeight());//设置水印旋转
			}
			JLabel label = new JLabel(watermarkText);
			FontMetrics metrics = label.getFontMetrics(font);
			int width = metrics.stringWidth(label.getText());//文字水印的宽
			int rowsNumber = srcImgHeight/width+srcImgHeight%width;// 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
			int columnsNumber = srcImgWidth/width+srcImgWidth%width;//图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
			//防止图片太小而文字水印太长,所以至少打印一次
			if(rowsNumber < 1){
				rowsNumber = 1;
			}
			if(columnsNumber < 1){
				columnsNumber = 1;
			}
			for(int j=0;j<rowsNumber;j++){
				for(int i=0;i<columnsNumber;i++){
					g.drawString(watermarkText, i*width + j*width, -i*width + j*width);//画出水印,并设置水印位置
				}
			}
			g.dispose();// 释放资源
			// 输出图片
			outputStream = new ByteArrayOutputStream();
			ImageIO.write(bufferedImage, "png", outputStream);
		} catch (Exception e) {
			e.printStackTrace();
			e.getMessage();
		} finally{
			try {
				if(outputStream != null){
					outputStream.flush();
					outputStream.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				e.getMessage();
			}
		}
		return outputStream;
	}
//	public static void main(String[] args) {
//		System.out.println("开始水印:");
//		addWatermark("D:/003.jpg", "D:/bbb.jpg", "helloword!", "jpg");
//		System.out.println("水印完成。");
//	}


//		try {
//			// 从网络获取示例图片(实际使用时替换为您的图片路径)
//			File file = new File("D:/003.jpg");
//			BufferedImage sourceImage = ImageIO.read(file);
//
//			// 获取源图片尺寸
//			int width = sourceImage.getWidth();
//			int height = sourceImage.getHeight();
//
//			// 生成水印图片
//			BufferedImage watermarkImage = generateWatermarkImage(
//				"水印字体", // 水印文字 字体文件路径(需替换为实际路径)
//				width, height, // 图片尺寸
//				15, // 倾斜角度
//				120, // 水平间距
//				80, // 垂直间距
//				0.25f // 透明度
//			);
//
//			// 保存水印图片
//			File outputFile = new File("D:/watermark.png");
//			ImageIO.write(watermarkImage, "png", outputFile);
//
//			System.out.println("水印图片生成成功!保存至: " + outputFile.getAbsolutePath());
//			System.out.println("图片尺寸: " + width + "x" + height);
//		} catch (IOException e) {
//			System.err.println("生成水印图片时出错: " + e.getMessage());
//			e.printStackTrace();
//		}




}

如果有什么问题,欢迎指正。谢谢大家的阅读,希望能帮到大家。方便的话点个关注。

Java中,给PDF和Word文档添加斜体水印通常需要使用专门的库来处理这两种格式的文件。对于PDF,你可以使用iText库(Apache PDFBox的一个分支),它提供了丰富的功能来操作PDF。而对于Word文档,你可以借助Office开源项目如Apache POI,它支持读写Microsoft Office格式。 以下是简化的步骤: **PDF水印(使用iText):** ```java import com.itextpdf.text.Document; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfWriter; public void addItalicWatermarkToPdf(String inputFile, String outputFile) { try { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream(outputFile)); document.open(); // 创建一个带斜体水印的Paragraph对象 Paragraph watermark = new Paragraph("*(斜体水印)*", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD.Italic)); // 设置水印的位置和透明度 PdfCopy copy = new PdfCopy(document, new FileOutputStream(outputFile)); copy.setUnderContentCopier(new WatermarkUnderContent(copy.getUnderContent(), watermark, 0, -50f, Color.LIGHT_GRAY, 1.0f)); document.add(watermark); document.close(); } catch (Exception e) { e.printStackTrace(); } } ``` **Word水印(使用Apache POI):** ```java import org.apache.poi.xwpf.usermodel.*; public void addItalicWatermarkToWord(String inputFile, String outputFile) { try { XWPFDocument doc = new XWPFDocument(new FileInputStream(inputFile)); XWPFParagraph watermarkPara = doc.createParagraph(); XWPFRun run = watermarkPara.createRun(); run.setText("(斜体水印)"); run.setFontColor(Color.LIGHT_GRAY); // 设置颜色 run.setBold(true); // 设置斜体 // 将水印添加到文档的开始 doc.getDocument().getBody().insert(0, watermarkPara); doc.saveAs(new File(outputFile)); doc.close(); } catch (Exception e) { e.printStackTrace(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值