opencv for java给图片添加水印中文问题
Posted luffy5459
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv for java给图片添加水印中文问题相关的知识,希望对你有一定的参考价值。
opencv提供的给图片添加文字的方法Imgproc.putText()可以给图片添加文字,最后类似一个添加水印的效果,但是这个方法对中文支持不好,在没有字体支持的情况下,默认中文显示?。如下图所示:
代码如下:
package org.example;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.net.URL;
public class AddWatermark1
public static void main(String[] args)
try
URL url = null;
String os = System.getProperty("os.name");
if(os.startsWith("Linux"))
url = ClassLoader.getSystemResource("opencvlib/libopencv_java453.so");
else
url = ClassLoader.getSystemResource("opencvlib/opencv_java453.dll");
System.load(url.getPath());
Mat src= Imgcodecs.imread("C:\\\\Users\\\\86159\\\\Pictures\\\\watermark.png");
if(src.empty())
throw new Exception("no file");
Mat dst = src.clone();
int height = src.height();
int width = src.width();
//设置遮罩层
Imgproc.rectangle(dst,new Point(0,height - 200),new Point(width-2,height-2),new Scalar(50,48,48,158),-1);
Point p=new Point(0,height-120);
Point p2 = new Point(0,height-54);
Point p3 = new Point(width-150,height-80);
//添加时间
Imgproc.putText(dst, "2022-04-01 09:21:13", p, 4, 0.8, new Scalar(245,168,1),2);
//添加地点
Imgproc.putText(dst, "湖北省武汉市", p2, 4, 0.8, new Scalar(245,168,1),2);
//添加使用人
Imgproc.putText(dst, "张三", p3, 4, 0.8, new Scalar(245,168,1),2);
boolean flag = Imgcodecs.imwrite("watermark.png", dst);
System.out.println("done."+flag);
//输出图像
catch(Exception e)
System.out.println("例外:" + e);
解决这个乱码问题的办法也不是没有,这个好像需要在编译opencv的时候就把字体添加进去。总体来说,还是很麻烦的。
还有一种原始的办法,就是回到java.awt提供的画图工具上,使用Graphics2D类提供的办法。这里也给出一个代码:
package org.example;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class AddWatermark2
private static URL picLocationURL;
private static URL picTimeURL;
public static void main(String[] args)
String path = "C:\\\\Users\\\\86159\\\\Pictures\\\\watermark.png";
try
URL url = null;
String os = System.getProperty("os.name");
if(os.startsWith("Linux"))
url = ClassLoader.getSystemResource("opencvlib/libopencv_java453.so");
else
url = ClassLoader.getSystemResource("opencvlib/opencv_java453.dll");
System.load(url.getPath());
picLocationURL = ClassLoader.getSystemResource("pic_location.png");
picTimeURL = ClassLoader.getSystemResource("pic_time.png");
BufferedImage image = ImageIO.read(new File(path));
int width = image.getWidth();
int height = image.getHeight();
Graphics2D g = image.createGraphics();
Color fillColor = new Color(50, 48, 48,158);
g.setColor(fillColor);
g.fillRect(0,height-200,width,200);
Color fontColor = new Color(245,168,1);
g.setColor(fontColor);
Image locationIcon = new ImageIcon(picLocationURL.getPath()).getImage();
Image timeIcon = new ImageIcon(picTimeURL.getPath()).getImage();
g.drawImage(timeIcon,34,height-157,null);
g.drawImage(locationIcon,34,height-93,null);
Font font = new Font("微软雅黑",Font.PLAIN,40);
g.setFont(font);
g.drawString("2022-04-03 20:53:00",80,height-120);
g.drawString("湖北省武汉市",80,height-54);
font = new Font("微软雅黑",Font.PLAIN,44);
g.setFont(font);
g.drawString("张三",width-150,height-80);
g.dispose();
Mat dst = WeChatQRCodeTool.bufImg2Mat(image,BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
boolean flag = Imgcodecs.imwrite("watermark.png", dst);
System.out.println("done."+flag);
catch (IOException e)
e.printStackTrace();
这种办法加水印的效果如下:
中文问题很好解决。
这个里面使用了微软雅黑字体,在windows下没有问题,但是部署到linux下,可能缺失微软雅黑字体,所以最终还是会显示中文乱码,这个乱码是因为系统缺失字体,直接拷贝windows系统下的msyh.ttf字体文件(C:\\Windows\\Fonts)到linux字体目录(usr/share/fonts)下新建的目录myfonts即可,系统字体,windows和linux倒是通用的,字体文件要生效,可以执行一个这样的命令:
[root@server myfonts]# fc-cache -fv
上面提到opencv提供的添加文字Imgproc.putString()要解决中文乱码,需要在opencv提供的依赖库里面编译的时候就安装上字体,显然更麻烦。
以上是关于opencv for java给图片添加水印中文问题的主要内容,如果未能解决你的问题,请参考以下文章