工具类
图片相关
package com.wantong.question.util;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.wantong.common.utils.encrypt.UUIDGenerator;
import com.wantong.question.domain.po.brs.PositionPO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;
import sun.awt.image.BufferedImageGraphicsConfig;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public final class ImageUtil {
public static final String DEFAULT_NAME = "image";
public static final String PNG = "png";
public static final String JPG = "jpg";
public static byte[] merger(String first, String second) throws IOException {
return getImageBytes(mergeImage(first, second), PNG);
}
public static byte[] getImageBytes(BufferedImage newImg, String imageType) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(newImg, imageType, os);
return os.toByteArray();
}
public static BufferedImage mergeImage(String first, String second) throws IOException {
log.info("开始合并图片,img1:{} img2:{}", first, second);
FileInputStream img1 = new FileInputStream(first);
FileInputStream img2 = new FileInputStream(second);
BufferedImage image01 = ImageIO.read(img1);
BufferedImage image02 = ImageIO.read(img2);
return mergeImage(image01, image02, false, false, true, 0, null);
}
public static BufferedImage mergeImage(BufferedImage first, BufferedImage second, boolean horizontal, boolean center, boolean transparent, int gap, Color color) {
log.info("合并图片参数,水平合并:{} 水平居中:{} 背景透明:{} 图片间距:{} 图片背景:{}",
horizontal, center, transparent, gap, color);
if (first == null) {
return second;
} else if (second == null) {
return first;
}
int firstWidth = first.getWidth();
int firstHeight = first.getHeight();
int secondWidth = second.getWidth();
int secondHeight = second.getHeight();
int picGap = gap * 2;
int mergeWidth = Math.max(firstWidth, secondWidth) + picGap;
int mergeHeight = firstHeight + secondHeight + picGap;
if (horizontal) {
mergeWidth = firstWidth + secondWidth + picGap;
mergeHeight = Math.max(firstHeight, secondHeight) + picGap;
}
BufferedImage target = new BufferedImage(mergeWidth, mergeHeight, BufferedImage.TYPE_INT_RGB);
if (transparent) {
BufferedImageGraphicsConfig config = BufferedImageGraphicsConfig.getConfig(target);
target = config.createCompatibleImage(mergeWidth, mergeHeight, Transparency.TRANSLUCENT);
}
Graphics2D graphics = target.createGraphics();
int x1, y1;
int x2, y2;
if (horizontal) {
x1 = gap;
y1 = gap;
x2 = firstWidth + gap;
y2 = gap;
} else {
if (center) {
x1 = (mergeWidth - firstWidth) / 2;
x2 = (mergeWidth - secondWidth) / 2;
} else {
x1 = gap;
x2 = gap;
}
y1 = gap;
y2 = firstHeight + gap;
}
if (color != null) {
graphics.setColor(color);
graphics.fillRect(0, 0, mergeWidth, mergeHeight);
}
graphics.drawImage(first, x1, y1, firstWidth, firstHeight, null);
graphics.drawImage(second, x2, y2, secondWidth, secondHeight, null);
graphics.dispose();
log.info("合并图片完成");
return target;
}
public static byte[] getLatexBytes(String latexFormula) throws IOException {
return getImageBytes(latex2Image(latexFormula), PNG);
}
private static BufferedImage latex2Image(String latexFormula) {
log.info("Latex公式转图片,公式:{}", latexFormula);
if (StringUtils.isBlank(latexFormula)) {
return null;
}
latexFormula = latexFormula.replaceAll("<br>", "")
.replaceAll(" ", "\\ ")
.replaceAll("&", "\\&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll("_{6}", "\\\\_")
.replaceAll(""", "''")
.replaceAll("©", "\\copyright")
.replaceAll("®", "\\textregistered");
TeXFormula formula = new TeXFormula(latexFormula);
TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20);
BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.setPaint(new Color(0, 0, 0, 0));
g2.fillRect(0, 0, image.getWidth(), image.getHeight());
g2.setColor(Color.BLACK);
icon.paintIcon(new JLabel(), g2, 0, 0);
g2.dispose();
return image;
}
public static void writeToFile(String fileName, BufferedImage image) throws IOException {
if (fileName == null) {
fileName = DEFAULT_NAME;
}
File file = new File(fileName);
FileUtil.mkParentDirs(file);
ImageIO.write(image, PNG, file);
}
public static void cutImage(String src, String target, List<PositionPO.ShapeVO> shapes) throws IOException {
BufferedImage srcImage = ImageIO.read(new File(src));
Polygon polygon = new Polygon(
shapes.stream().mapToInt(shape -> shape.getX().intValue()).toArray(),
shapes.stream().mapToInt(shape -> shape.getY().intValue()).toArray(),
shapes.size()
);
Rectangle bounds = polygon.getBounds();
BufferedImage targetImage = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = targetImage.createGraphics();
g2d.translate(-bounds.x, -bounds.y);
g2d.setClip(polygon);
g2d.drawImage(srcImage, 0, 0, null);
g2d.dispose();
writeToFile(target, targetImage);
}
public static void main(String[] args) throws Exception {
String s = "[{\"x\":859.0,\"y\":887.0},{\"x\":1167.0,\"y\":1030.0},{\"x\":1088.0,\"y\":1377.0},{\"x\":1266.0,\"y\":1708.0},{\"x\":1027.0,\"y\":1981.0},{\"x\":754.0,\"y\":1949.0},{\"x\":766.0,\"y\":1514.0},{\"x\":693.0,\"y\":1138.0}]";
List<PositionPO.ShapeVO> shapes = JSON.parseArray(s, PositionPO.ShapeVO.class);
cutImage("E:\\cutSrc.png", "D:\\cutTarget.png", shapes);
Pattern LATEX_PATTERN = Pattern.compile("\\$\\(([^$]*)\\)\\$");
String text = "<p>哈哈哈哈$VT-G[1]$ $(\\left(x-1\\right)\\left(x+______\\right) )$</p>";
StringBuilder newText = new StringBuilder();
int index = 0;
Matcher matcher = LATEX_PATTERN.matcher(text);
while (matcher.find()) {
String fileName = UUIDGenerator.getUUID32() + "." + PNG;
writeToFile("D:\\latex\\" + fileName, latex2Image(matcher.group(1)));
newText.append(text, index, matcher.start());
newText.append("<img src=\"").append(fileName).append("\" alt=\"LaTeX Formula\"/>");
index = matcher.end();
}
newText.append(text.substring(index));
System.out.println(newText.toString());
FileInputStream img1 = new FileInputStream("E:\\1.png");
FileInputStream img2 = new FileInputStream("E:\\2.jpg");
BufferedImage image01 = ImageIO.read(img1);
BufferedImage image02 = ImageIO.read(img2);
BufferedImage target = mergeImage(image01, image02, false, true, false, 0, Color.white);
writeToFile("D:\\003.jpg", target);
System.out.println("合并成功......");
target = mergeImage(image01, image02, true, true, true, 20, null);
writeToFile("D:\\004.jpg", target);
System.out.println("合并成功......");
}
}
http调用
package com.wantong.common.utils.http;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.FormBodyPartBuilder;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.formula.functions.T;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@Slf4j
public abstract class AbsHttpClientPool {
protected CloseableHttpClient httpClient;
protected CookieStore cookieStore;
protected PoolingHttpClientConnectionManager manager;
protected ThreadLocal<CloseableHttpResponse> respThreadLocal = new InheritableThreadLocal<>();
protected ThreadLocal<byte[]> respEntityResp = new InheritableThreadLocal<>();
public int getTimeout() {
return 5000;
}
public int getConnectionAmount() {
return 10;
}
@SneakyThrows
public void initHttpClient() {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", ssf)
.register("http", PlainConnectionSocketFactory.INSTANCE).build();
HttpClientBuilder httpClientBuilder = HttpClients.custom();
manager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
SocketConfig config = SocketConfig.custom().setSoTimeout(getTimeout()).
setSoKeepAlive(true).setTcpNoDelay(true).build();
manager.setDefaultSocketConfig(config);
manager.setDefaultMaxPerRoute(getConnectionAmount());
manager.setMaxTotal(getConnectionAmount());
httpClientBuilder.setConnectionManager(manager);
httpClientBuilder.setDefaultSocketConfig(config);
cookieStore = new BasicCookieStore();
httpClientBuilder.setDefaultCookieStore(cookieStore);
beforeClientBuild(httpClientBuilder, config, manager);
httpClient = httpClientBuilder.build();
}
protected void beforeClientBuild(HttpClientBuilder httpClientBuilder, SocketConfig socketConfig, PoolingHttpClientConnectionManager httpClientConnectionManager) {
}
@Data
@Accessors(chain = true)
public static class ParamEntity {
Object body;
String fileName;
}
public static List<NameValuePair> convertParams(Map<String, Object> params) {
List<NameValuePair> p = new LinkedList<>();
params.forEach((key, value) -> p.add(new BasicNameValuePair(key, String.valueOf(value))));
return p;
}
protected <T> T executeGet(String url, Map<String, Object> params, TypeReference<T> reference) {
CloseableHttpResponse httpResponse = null;
try {
respThreadLocal.set(httpResponse);
String param = params == null ? "" : params.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
HttpGet request = new HttpGet(url + "?" + param);
httpResponse = httpClient.execute(request);
respThreadLocal.set(httpResponse);
int code = httpResponse.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
String content = EntityUtils.toString(httpResponse.getEntity());
return JSON.parseObject(content, reference);
} else {
String content = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
log.warn("远端服务返回错误[{}]: {}", code, content);
return null;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected <T> T executePost(String url, Map<String, Object> params, TypeReference<T> reference) {
return executePost(url, null, params, reference);
}
protected <T> T executePost(String url, Map<String, String> headers, Map<String, Object> params, TypeReference<T> reference) {
UrlEncodedFormEntity entity = null;
try {
entity = new UrlEncodedFormEntity(convertParams(params), "utf-8");
} catch (UnsupportedEncodingException e) {
log.error("UnsupportedEncodingException", e);
throw new RuntimeException(e);
}
return executePost(url, headers, entity, reference);
}
protected <T> T executePostMulti(String url, Map<String, String> headers, Map<String, ParamEntity> params, TypeReference<T> reference) {
MultipartEntityBuilder builder = null;
builder = MultipartEntityBuilder.create();
if (params != null && params.size() > 0) {
AtomicInteger i = new AtomicInteger();
MultipartEntityBuilder finalBuilder = builder;
params.forEach((key, value) -> {
if (value.getBody() instanceof byte[]) {
finalBuilder.addBinaryBody(key, (byte[]) value.getBody(), ContentType.APPLICATION_OCTET_STREAM, value.getFileName());
} else {
finalBuilder.addPart(FormBodyPartBuilder.create().setName(key).setBody(new StringBody((String) value.getBody(), ContentType.TEXT_PLAIN)).build());
}
});
}
return executePost(url, headers, builder.build(), reference);
}
protected <T> T executePost(String url, Map<String, String> headers, Object params, TypeReference<T> reference) {
StringEntity se = null;
String jsonStr = null;
if (params instanceof CharSequence) {
jsonStr = (String) params;
} else {
jsonStr = JSONObject.toJSONString(params);
}
if (!StringUtils.isEmpty(jsonStr)) {
se = new StringEntity(jsonStr, "utf-8");
se.setContentType("application/json;charset=utf-8");
}
if (headers == null) {
headers = new HashMap<>();
}
return executePost(url, headers, se, reference);
}
protected <T> T executePost(String url, Map<String, String> headers, HttpEntity entity, TypeReference<T> reference) {
CloseableHttpResponse httpResponse = null;
String content = null;
try {
respThreadLocal.set(httpResponse);
respEntityResp.set(null);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(entity);
Optional.ofNullable(headers).ifPresent(e -> e.forEach(httpPost::addHeader));
httpResponse = httpClient.execute(httpPost);
respThreadLocal.set(httpResponse);
int code = httpResponse.getStatusLine().getStatusCode();
byte[] bytes = EntityUtils.toByteArray(httpResponse.getEntity());
respEntityResp.set(bytes);
if (code == HttpStatus.SC_OK) {
if (reference == null) {
return null;
}
content = new String(bytes, StandardCharsets.UTF_8);
return JSON.parseObject(content, reference);
}
content = new String(bytes, StandardCharsets.UTF_8);
log.warn("远端服务返回错误[{}]: {}", code, content);
if (reference == null) {
throw new HttpReqException(content);
}
return null;
} catch (UnsupportedEncodingException e) {
log.error("参数转换异常", e);
} catch (ClientProtocolException e) {
log.error("请求协议异常", e);
} catch (IOException e) {
log.error("请求IO异常", e);
} catch (Exception e) {
log.error("响应JSON字符串格式化异常,content: {}", content, e);
}
return null;
}
public CloseableHttpResponse getResp() {
return respThreadLocal.get();
}
public byte[] getRespEntity() {
return respEntityResp.get();
}
public CookieStore getCookieStore() {
return this.cookieStore;
}
public String getCookie(String name) {
if (name == null) {
return null;
}
return getCookieStore().getCookies().parallelStream()
.filter(e -> name.equals(e.getName()))
.findFirst().map(Cookie::getValue).orElse(null);
}
public static <T> void doNotNull(T val, Consumer<T> c) {
if (val == null) {
return;
}
c.accept(val);
}
public static <T extends CharSequence> void doNotEmpty(T val, Consumer<T> c) {
if (StringUtils.isEmpty(val)) {
return;
}
c.accept(val);
}
}