package com.sf.vsolution.hb.pcc.util.pictures;
import com.sf.vsolution.hb.pcc.constant.OrderImgConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author: yachun
* @description: 订单模块_特殊派送
*/
@Slf4j
public class ImageUtil {
/**
* 给图片+图片水印
*
* @param url --url 地址
* @param pressImg -- 水印图片
* @param targetImg -- 目标文件
* @param location 水印位置:left-top:左上角,right-top:右上角,left-bottom:左下角,right-bottom:右下角
* @param degree 水印旋转角度
*/
public static void pressImage(String url, String pressImg, String targetImg, String location, Integer degree) {
try {
// 目标文件
File srcfile = toFile(url, new File(targetImg));
Image src = ImageIO.read(srcfile);
int width = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.drawImage(src, 0, 0, width, height, null);
// 水印文件
File zipfilebiao = new File(pressImg);
Image srcBiao = ImageIO.read(zipfilebiao);
int widthBiao = srcBiao.getWidth(null);
int heightBiao = srcBiao.getHeight(null);
// 水印坐标
int x = 0, y = 0;
if (StringUtils.equals(location, OrderImgConstant.LEFT_TOP)) {
x += 30;
y += 30;
} else if (StringUtils.equals(location, OrderImgConstant.RIGHT_TOP)) {
x = width - widthBiao - 30;
y += 30;
} else if (StringUtils.equals(location, OrderImgConstant.LEFT_BOTTOM)) {
y = height - heightBiao - 30;
x += 30;
} else if (StringUtils.equals(location, OrderImgConstant.RIGHT_BOTTOM)) {
x = width - widthBiao - 30;
y = height - heightBiao - 30;
} else {
x = (width - widthBiao) / 2;
y = (height - heightBiao) / 2;
}
if (null != degree) {
// 设置水印旋转
g.rotate(Math.toRadians(degree), x, y);
}
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawImage(srcBiao, x, y, widthBiao, heightBiao, null);
// 水印文件结束
g.dispose();
//直接修改源文件
FileOutputStream out = new FileOutputStream(targetImg);
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
// encoder.encode(image);
out.flush();
out.close();
//生成新的文件
// File sf = new File("D:/imgout/" + "test" + "." + "jpg");
// ImageIO.write(image, "jpg", sf); // 保存图片
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给图片加文字水印
*
* @param url 图片的网络地址
* @param pressText s水印文字
* @param targetImg 目标文件
* @param fontName 字体名称
* @param fontStyle 字体风格
* @param fontSize 字体大小
* @param location 字体位置:left-top:左上角,right-top:右上角,left-bottom:左下角,right-bottom:右下角
*/
public static String pressText(String url, String pressText, String targetImg, String fontName, int fontStyle,
int fontSize, String location, Color color) {
try {
int textWidth = getFontWidth(fontName, fontStyle, fontSize, pressText);
//File _file = new File(targetImg);
File file = new File(targetImg);
log.info("----------targetImg----------传入的路径--------------File为:" + file);
File inPutfile = toFile(url, new File(targetImg));
System.out.println("_file = " + inPutfile);
log.info("---------toFile方法执行后返回-------------------图片加水印返回的_file地址为:" + inPutfile);
Image src = ImageIO.read(inPutfile);
log.info("----------ImageIO.read(_file)------------------读取图片路径返回的src为:" + src);
int width = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
g.setColor(color);
g.setFont(new Font(fontName, fontStyle, fontSize));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
0.45f));
int x = 0, y = 0;
if (StringUtils.equals(location, OrderImgConstant.LEFT_TOP)) {
x = 30;
y = 30;
} else if (StringUtils.equals(location, OrderImgConstant.RIGHT_TOP)) {
x = width - textWidth - 30;
y = 30;
} else if (StringUtils.equals(location, OrderImgConstant.LEFT_BOTTOM)) {
x += 30;
y = height - 30;
} else if (StringUtils.equals(location, OrderImgConstant.RIGHT_BOTTOM)) {
x = width - textWidth - 30;
y = height - 30;
} else {
x = (width - textWidth) / 2;
y = (height) / 2;
}
// g.drawString(pressText, x, y);
getRowPrint(pressText, fontSize, width, height, g, x, y);
g.dispose();
//TODO 注释掉找不到包的--原方式处理3-18
// FileOutputStream out = new FileOutputStream(targetImg);
// System.out.println("out = " + out);
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
// encoder.encode(image);
// out.flush();
// out.close();
saveImage(image, targetImg);
//-------------------------------------------------------------------------------------
//读取文件上的数据_可以的话返给前端
InputStream in = new FileInputStream(targetImg);
System.out.println("in = " + in);
String base64FromInputStream = getBase64FromInputStream(in);
in.close();
return base64FromInputStream;
} catch (IOException e) {
log.error("--------------------pressText方法---------------------给图片加水印出现异常" + e);
}
return null;
}
/**
* 文件保存
*
* @param link 图片链接
* @param file 存入的文件地址
* @return 下载的文件
*/
public static File toFile(String link, File file) {
try {
log.info("---------toFile--------进入到图片链接转换为FIle的接口-------------------------");
URL url = new URL(link);
URLConnection uri = url.openConnection();
//获取数据流
InputStream ins = uri.getInputStream();
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
int lent = 8192;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, lent)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
log.info("---------toFile-----结束到图片链接转换为FIle的接口----------------------------");
return file;
} catch (Exception e) {
e.printStackTrace();
System.out.println("------------------------------下载文件 = " + e);
log.error("--------------------------图片utl转换水印的异常信息为:" + e);
return null;
}
}
/**
* 计算文本占用的width
*
* @param fontName 字体名称
* @param fontStyle 字体风格
* @param fontSize 字体大小
* @param pressText 输入文本
* @return 文字所占用的宽带
*/
public static int getFontWidth(String fontName, int fontStyle, int fontSize, String pressText) {
Font f = new Font(fontName, fontStyle, fontSize);
FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(f);
// 高度
//System.out.println(fm.getHeight());
// 单个字符宽度
//System.out.println(fm.charWidth('A'));
// 整个字符串的宽度
//System.out.println(fm.stringWidth(pressText));
return fm.stringWidth(pressText);
}
/**
* 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
*
* @param in
* @return
*/
public static String getBase64FromInputStream(InputStream in) {
// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
byte[] data = null;
ByteArrayOutputStream swapStream = null;
// 读取图片字节数组
try {
swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
int len = 100;
while ((rc = in.read(buff, 0, len)) > 0) {
swapStream.write(buff, 0, rc);
}
data = swapStream.toByteArray();
swapStream.close();
} catch (IOException e) {
log.info("获取图片流转base64失败" + e);
} finally {
try {
swapStream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
log.info("------------------------获取图片流转base64关流失败" + e);
}
}
}
// System.out.println("将流转换为字符串{} " + new String(Base64.encodeBase64(data)));
return new String(Base64.encodeBase64(data));
}
/**
* @param dstImage 图片的原地址
* @param dstName 目标地址
* @throws IOException
*/
static void saveImage(BufferedImage dstImage, String dstName) throws IOException {
String formatName = dstName.substring(dstName.lastIndexOf(".") + 1);
ImageIO.write(dstImage, formatName, new File(dstName));
}
private static void getRowPrint(String pressText, int fontSize, int width, int height, Graphics2D g, int x, int y) {
//TODO y,数子越小,越靠上
System.out.println("图片x = " + x);
System.out.println("图片y = " + y);
System.out.println("图片的宽度像素 = " + width);
System.out.println("图片的高度像素 = " + height);
System.out.println("每个汉字的像素宽度, = " + width / fontSize);
//1.根据图片的宽度,和字体的大小, 计算出每行显示的文字
int ziShu = (width - 100) / fontSize;//每行显示的字数
int rowCount = 0;
if ((!StringUtils.isEmpty(pressText) && pressText.contains("#"))) {
int pressTextlength = pressText.length() - 18;
if (pressTextlength % ziShu == 0) {
rowCount = pressText.length() / ziShu;
} else {
rowCount = pressTextlength / ziShu + 1;
}
} else {
if (pressText.length() % ziShu == 0) {
rowCount = pressText.length() / ziShu;
} else {
rowCount = pressText.length() / ziShu + 1;
}
}
log.info("行数---" + rowCount);
log.info("行数x---" + x);
log.info("行数y---" + y);
if (!StringUtils.isEmpty(pressText) && pressText.contains("#")) {
int i = pressText.indexOf("#");
String timePrint = pressText.substring(0, i);
pressText = pressText.substring(i + 1, pressText.length());
int timeY = y - rowCount * fontSize - fontSize;
log.info("行数timeY---" + timeY);
g.drawString(timePrint, x, timeY);
}
System.out.println("hangCount = " + rowCount);
//2.根据打印水印文字的长度,计算出需要打印的行数
y -= rowCount * fontSize;
int b = rowCount * fontSize;
System.out.println("b = " + b);
// y = height - hangCount * fontSize;
//4.如果行数大于1,需要截取每行要显示的文字
//3.重新设置y左标的,开头第一行的值
if (rowCount > 1) {
for (int i = 0; i < rowCount; i++) {
int index = i * ziShu;
int end = ziShu * (i + 1);
if (i == rowCount - 1) {
end = pressText.length();
}
if (i >= 1) {
y += fontSize;
}
System.out.println("文 = " + index + "-----------------ent=" + end);
String substring = pressText.substring(index, end);
System.out.println("substring = " + substring);
System.out.println("文字的坐标x+Y = " + x + "-----------------y=" + y);
g.drawString(substring, x, y);
}
} else {
g.drawString(pressText, x, y);
}
return;
}
public static void main(String[] args) {
String url = "https://fxs-sit-1252000277.cos.ap-guangzhou.myqcloud.com/B2020020033/FX20040604646934/360D7A29-025E-49A3-BF2A-07310689426F.jpg?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDGdT77d9iP2U-4VNJh0XB8L6U5ST1shLqMabMankmum7pUp7vFQkVs639zSM2JoXJ%26q-sign-time%3D1586187514%3B1586194714%26q-key-time%3D1586187514%3B1586194714%26q-header-list%3D%26q-url-param-list%3D%26q-signature%3D958640915a074e881d8606d1fd7342757e3dbf66&x-cos-security-token=Mrq3S1vf97IRQjlkFEXmIV3V4geA4yJA2b0386c30ff9d78668fe44eb220b78dboNvcvhdcZF8HZfGf7lG1_jMY0z5a7Ijr0eu_Ml4RNZr-tc-zKeNL0hN1UzRJ0dyuy-mvMJHX2ZKKRLvuBYKwQyl2ElexeUY7u-Rtv875K-lZ7wQT4qftmj4vBkLDg0w0RHD3trFxDkMHhl0hwpM1C4G5yXRpHbClKZExynlM7Jn4C-Jp3j3Mx7o34n_gpoWN78e3tGMhL1ZhPWpGtchGMk-2ZDZt2qIrw3jAORuRxoMvorOGUFwgs-21QSfcIw7ya-e-_k3X9NWh2kgprdK6GFtNh_j5KmqBJ95N5pm2eCnDIFr69g6qruvPNMfiKUCPfscV0TJeI_GHw-Mk5qUX5DQp3rbwwdkVCFkALHS7deofU2RS2X7T4jVnGnlflClXBy4Q8iw3o4V3koDsOiRmkb2lXKmmVG6COnoifPW6kuYKSKP4Kty2jxQ2BSD9gF1serwJk3FJszEl9m-KYDZVJNsmzfx4OgkXV_mRg99n2gVlDJeXySK1qyveM5bBoswEfxIJh4-kdnlx9b9cN2o7Q4ukexPq46zO43yg4_aut52QZJLTV7ho-OGxp-CTOVwKP8gKh5tYOgzYbuX6YmzZK1S5kl6fl3-2bD6OWi3UF-joaw1EsxVFyu89kEzo9Zr6Fq8nGAyk1Pi80bRJENA0hZpIvLu_wDuG-jzFDDfznu8&";
// pressImage("https://cbu01.alicdn.com/img/ibank/2017/041/711/4771117140_1239574879.jpg", "D:/Desktop/test/logo.png", "D:/Desktop/test/a.png", "left-bottom", null);//
// pressImage(url, "D:/Desktop/test/logo.png", "D:/Desktop/imgout/b.png", "left-bottom", null);//
//pressImage("D:/imgin/20181017110944.png", "D:/imgout/1.png", "right-top", null);
//pressImage("D:/imgin/20181017110944.png", "D:/imgout/1.png", "center", null);
//pressImage("D:/imgin/20181017110944.png", "D:/imgout/1.png", "left-bottom", null);
//pressImage("D:/imgin/20181017110944.png", "D:/imgout/1.png", "right-bottom", null);
//TODO 项目路径有坑http://img.netbian.com/file/20130912/d59ab4ea5b932466d103a63f61a25ba0.jpg
// url = "http://img.netbian.com/file/20130912/d59ab4ea5b932466d103a63f61a25ba0.jpg";
String realPath = new String("hb-biz-pcc-core/src/main/resources/static/uploadFile/") + "r116.jpg";
// String realPath = new String("src\\main\\resources\\static\\uploadFile\\") + "r1110.jpg";
// System.out.println("realPath = " + realPath);
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
String format = sdf.format(new Date());
String paressText = format + "#" + "订单运单号是阿联迪斯科解放立刻撒旦解放昆仑山的发了深刻搭街坊卡拉QQQQ73890";
// String realPath = new String("d:/user/01380217/desktop/test/") + "r121.jpg";
// pressText("https://cbu01.alicdn.com/img/ibank/2017/041/711/4771117140_1239574879.jpg", "测试图片上添加文字水印啊", "D:/Desktop/imgout/r2.jpg", "黑体", Font.BOLD + Font.ITALIC, 30, "right-bottom",Color.GRAY);
pressText(url, paressText, realPath, "黑体", Font.BOLD + Font.ITALIC, 60, "left-bottom", Color.RED);
// pressText(url, "订单号是||1234567890||运单号是||1234567890", "D:/Desktop/imgout/r7.jpg", "黑体", Font.BOLD + Font.ITALIC, 30, "right-bottom",Color.RED);
// getFontWidth("黑体", Font.BOLD + Font.ITALIC, 30, "miraclesgrocery");
// System.out.println(Color.RED);
// System.out.println(Color.WHITE);
// System.out.println(Color.GRAY);
}
}