feat: update
This commit is contained in:
@@ -6,15 +6,11 @@ import com.schisandra.auth.common.entity.CaptchaResult;
|
|||||||
import com.schisandra.auth.common.redis.RedisUtil;
|
import com.schisandra.auth.common.redis.RedisUtil;
|
||||||
import com.schisandra.auth.common.utils.RotateImageUtils;
|
import com.schisandra.auth.common.utils.RotateImageUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.coobird.thumbnailator.Thumbnailator;
|
|
||||||
import net.coobird.thumbnailator.Thumbnails;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -42,19 +38,20 @@ public class ReactRotateCaptchaController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("get")
|
@GetMapping("get")
|
||||||
public CaptchaResult get() throws Exception {
|
public CaptchaResult get() throws Exception {
|
||||||
RotateImageUtils rotateImageUtils = new RotateImageUtils();
|
|
||||||
CompletableFuture<HashMap> futurePrice = CompletableFuture.supplyAsync(() -> {
|
CompletableFuture<HashMap> futurePrice = CompletableFuture.supplyAsync(() -> {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
SecureRandom random = new SecureRandom();
|
SecureRandom random = new SecureRandom();
|
||||||
double randomNumber = random.nextInt(280) + 40;
|
double randomNumber = random.nextInt(280) + 40;
|
||||||
InputStream inputStream = ReactRotateCaptchaController.class.getClassLoader().getResourceAsStream("image/cropped_image.png");
|
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("image/test2.png");
|
||||||
|
assert inputStream != null;
|
||||||
BufferedImage image = ImageIO.read(inputStream);
|
BufferedImage image = ImageIO.read(inputStream);
|
||||||
String token = UUID.randomUUID().toString();
|
String token = UUID.randomUUID().toString();
|
||||||
String prefix = redisUtil.buildKey(authRotateCaptchaPrefix, token);
|
String prefix = redisUtil.buildKey(authRotateCaptchaPrefix, token);
|
||||||
redisUtil.setNx(prefix, String.valueOf(randomNumber), 60L, TimeUnit.SECONDS);
|
redisUtil.setNx(prefix, String.valueOf(randomNumber), 30L, TimeUnit.SECONDS);
|
||||||
BufferedImage image1 = rotateImageUtils.rotateImage(image, randomNumber);
|
BufferedImage bufferedImage = RotateImageUtils.rotateImage(image, randomNumber);
|
||||||
String img = RotateImageUtils.BufferedImageToBase64(image1);
|
BufferedImage newImage = RotateImageUtils.writeCyclePic(bufferedImage);
|
||||||
|
String img = RotateImageUtils.bufferedImageToBase64(newImage);
|
||||||
map.put("token", token);
|
map.put("token", token);
|
||||||
map.put("str", img);
|
map.put("str", img);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 52 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 354 KiB After Width: | Height: | Size: 354 KiB |
@@ -1,68 +1,17 @@
|
|||||||
package com.schisandra.auth.common.utils;
|
package com.schisandra.auth.common.utils;
|
||||||
|
|
||||||
import java.util.Base64;
|
import net.coobird.thumbnailator.Thumbnails;
|
||||||
import java.util.Base64.Encoder;
|
|
||||||
import java.util.Base64.Decoder;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
public class RotateImageUtils {
|
public class RotateImageUtils {
|
||||||
|
|
||||||
public static Color bgColor = new Color(255, 255, 255);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 压缩图片并将图片转换成base64
|
|
||||||
* @param: [bufferedImage]
|
|
||||||
* @return: java.lang.String
|
|
||||||
* @author zlg
|
|
||||||
* @date: 2024/5/9 13:13
|
|
||||||
*/
|
|
||||||
public static String BufferedImageToBase64(BufferedImage bufferedImage) throws IOException {
|
|
||||||
int targetWidth = 400;
|
|
||||||
int targetHeight = 400;
|
|
||||||
// 获取原始图片的尺寸
|
|
||||||
int originalWidth = bufferedImage.getWidth();
|
|
||||||
int originalHeight = bufferedImage.getHeight();
|
|
||||||
// 创建一个新的 BufferedImage,用于存放处理后的图片
|
|
||||||
BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, bufferedImage.getType());
|
|
||||||
// 创建一个 Graphics2D 对象,用于绘制新图片
|
|
||||||
Graphics2D graphics = outputImage.createGraphics();
|
|
||||||
graphics.dispose();
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
|
|
||||||
ImageIO.write(outputImage, "png", baos);//写入流中
|
|
||||||
byte[] bytes = baos.toByteArray();//转换成字节
|
|
||||||
Encoder encoder = Base64.getEncoder();
|
|
||||||
String png_base64 = encoder.encodeToString(bytes);//转换成base64串
|
|
||||||
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
|
|
||||||
return "data:image/jpg;base64," + png_base64;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 将base64转换成图片
|
|
||||||
* @param: [base64]
|
|
||||||
* @return: java.awt.image.BufferedImage
|
|
||||||
* @author zlg
|
|
||||||
* @date: 2024/5/9 13:14
|
|
||||||
*/
|
|
||||||
public static BufferedImage base64ToBufferedImage(String base64) {
|
|
||||||
Decoder decoder = Base64.getDecoder();
|
|
||||||
try {
|
|
||||||
byte[] bytes1 = decoder.decode(base64);
|
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
|
|
||||||
return ImageIO.read(bais);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 获取旋转后的图片
|
* @description: 获取旋转后的图片
|
||||||
@@ -71,39 +20,77 @@ public class RotateImageUtils {
|
|||||||
* @author zlg
|
* @author zlg
|
||||||
* @date: 2024/5/9 13:14
|
* @date: 2024/5/9 13:14
|
||||||
*/
|
*/
|
||||||
public BufferedImage rotateImage(BufferedImage image, double theta) throws IOException {
|
public static BufferedImage rotateImageByThumbnails(BufferedImage image, double theta) throws IOException {
|
||||||
BufferedImage originalImage = image;
|
|
||||||
int width = originalImage.getWidth();
|
BufferedImage bufferedImage = Thumbnails.of(image).size(200, 200).rotate(theta).asBufferedImage();
|
||||||
int height = originalImage.getHeight();
|
BufferedImage newCompleteImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),
|
||||||
// 创建新的BufferedImage对象,设置类型为ARGB_8888
|
BufferedImage.TYPE_INT_ARGB);
|
||||||
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
newCompleteImage.createGraphics().drawImage(bufferedImage, 0, 0,null);
|
||||||
// 使用Graphics2D对象将原始图片绘制到新的BufferedImage对象上,同时设置背景色为透明色
|
return newCompleteImage;
|
||||||
Graphics2D g2d = newImage.createGraphics();
|
}
|
||||||
g2d.setBackground(new Color(0, 0, 0, 0)); // 设置背景色为透明色
|
|
||||||
g2d.clearRect(0, 0, width, height); // 清除画布
|
/**
|
||||||
g2d.drawImage(originalImage, 0, 0,null); // 绘制原始图片
|
* BufferedImage转base64
|
||||||
g2d.dispose();
|
*
|
||||||
// 对新的BufferedImage对象进行旋转操作
|
* @param bufferedImage
|
||||||
double angle = Math.toRadians(theta);
|
* @return
|
||||||
int newWidth = (int) (height * Math.cos(angle) + width * Math.sin(angle));
|
*/
|
||||||
int newHeight = (int) (height * Math.sin(angle) + width * Math.cos(angle));
|
public static String bufferedImageToBase64(BufferedImage bufferedImage) {
|
||||||
BufferedImage rotatedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
Graphics2D g2dRotated = rotatedImage.createGraphics();
|
try {
|
||||||
g2dRotated.translate((newWidth - width) / 2, (newHeight - height) / 2);
|
// 设置图片格式
|
||||||
g2dRotated.rotate(angle, width / 2, height / 2);
|
ImageIO.write(bufferedImage, "png", stream);
|
||||||
g2dRotated.drawImage(newImage, 0, 0,null);
|
} catch (IOException e) {
|
||||||
g2dRotated.dispose();
|
e.printStackTrace();
|
||||||
int newSize = 160; // 新的大小为500像素
|
}
|
||||||
BufferedImage resizedImage = new BufferedImage(newSize, newSize, BufferedImage.TYPE_INT_ARGB);
|
byte[] bytes = Base64.getEncoder().encode(stream.toByteArray());
|
||||||
Graphics2D g2dResized = resizedImage.createGraphics();
|
String base64 = new String(bytes);
|
||||||
g2dResized.drawImage(rotatedImage, 0, 0, newSize, newSize, null);
|
return "data:image/png;base64," + base64;
|
||||||
g2dResized.dispose();
|
}
|
||||||
// 将调整大小后的图像保存到文件中
|
|
||||||
return resizedImage;
|
|
||||||
|
/**
|
||||||
|
* @description: 获取旋转后的图片
|
||||||
|
* @param: [image, theta, backgroundColor]
|
||||||
|
* @return: java.awt.image.BufferedImage
|
||||||
|
* @author zlg
|
||||||
|
* @date: 2024/5/9 13:14
|
||||||
|
*/
|
||||||
|
public static BufferedImage rotateImage(BufferedImage image, double theta) throws IOException {
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
double angle = theta * Math.PI / 180; // 度转弧度
|
||||||
|
double[] xCoords = getX(width / 2, height / 2, angle);
|
||||||
|
double[] yCoords = getY(width / 2, height / 2, angle);
|
||||||
|
int WIDTH = (int) (xCoords[3] - xCoords[0]);
|
||||||
|
int HEIGHT = (int) (yCoords[3] - yCoords[0]);
|
||||||
|
BufferedImage resultImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||||
|
for (int i = 0; i < WIDTH; i++) {
|
||||||
|
for (int j = 0; j < HEIGHT; j++) {
|
||||||
|
int x = i - WIDTH / 2;
|
||||||
|
int y = HEIGHT / 2 - j;
|
||||||
|
double radius = Math.sqrt(x * x + y * y);
|
||||||
|
double angle1;
|
||||||
|
if (y > 0) {
|
||||||
|
angle1 = Math.acos(x / radius);
|
||||||
|
} else {
|
||||||
|
angle1 = 2 * Math.PI - Math.acos(x / radius);
|
||||||
|
}
|
||||||
|
x = (int) Math.round(radius * Math.cos(angle1 - angle));
|
||||||
|
y = (int) Math.round(radius * Math.sin(angle1 - angle));
|
||||||
|
if (x < (width / 2) & x > -(width / 2) & y < (height / 2) & y > -(height / 2)) {
|
||||||
|
int rgb = image.getRGB((int) Math.round(x + width / 2), (int) Math.round(height / 2 - y));
|
||||||
|
resultImage.setRGB(i, j, rgb);
|
||||||
|
} else {
|
||||||
|
resultImage.setRGB(i, j, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取四个角点旋转后Y方向坐标
|
// 获取四个角点旋转后Y方向坐标
|
||||||
private double[] getY(int i, int j, double angle) {
|
private static double[] getY(int i, int j, double angle) {
|
||||||
double results[] = new double[4];
|
double results[] = new double[4];
|
||||||
double radius = Math.sqrt(i * i + j * j);
|
double radius = Math.sqrt(i * i + j * j);
|
||||||
double angle1 = Math.asin(j / radius);
|
double angle1 = Math.asin(j / radius);
|
||||||
@@ -116,7 +103,7 @@ public class RotateImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取四个角点旋转后X方向坐标
|
// 获取四个角点旋转后X方向坐标
|
||||||
private double[] getX(int i, int j, double angle) {
|
private static double[] getX(int i, int j, double angle) {
|
||||||
double results[] = new double[4];
|
double results[] = new double[4];
|
||||||
double radius = Math.sqrt(i * i + j * j);
|
double radius = Math.sqrt(i * i + j * j);
|
||||||
double angle1 = Math.acos(i / radius);
|
double angle1 = Math.acos(i / radius);
|
||||||
@@ -135,17 +122,17 @@ public class RotateImageUtils {
|
|||||||
* @author zlg
|
* @author zlg
|
||||||
* @date: 2024/5/9 13:14
|
* @date: 2024/5/9 13:14
|
||||||
*/
|
*/
|
||||||
public BufferedImage writeCyclePic(BufferedImage image) {
|
public static BufferedImage writeCyclePic(BufferedImage image) {
|
||||||
BufferedImage newImage = new BufferedImage(350, 350, BufferedImage.TYPE_INT_BGR);
|
BufferedImage newImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_BGR);
|
||||||
try {
|
try {
|
||||||
int width = image.getWidth();
|
int width = image.getWidth();
|
||||||
int heigth = image.getHeight();
|
int heigth = image.getHeight();
|
||||||
double x0 = width / 2;
|
double x0 = width / 2;
|
||||||
double y0 = heigth / 2;
|
double y0 = heigth / 2;
|
||||||
int woffset = (width - 350) / 2;
|
int woffset = (width - 800) / 2;
|
||||||
int hoffset = (heigth - 350) / 2;
|
int hoffset = (heigth - 800) / 2;
|
||||||
for (int i = woffset; i < 350 + woffset; i++) {
|
for (int i = woffset; i < 800 + woffset; i++) {
|
||||||
for (int j = hoffset; j < 350 + hoffset; j++) {
|
for (int j = hoffset; j < 800 + hoffset; j++) {
|
||||||
double r = Math.sqrt(Math.pow(Math.abs(i - x0), 2.0) + Math.pow(Math.abs(j - y0), 2.0));
|
double r = Math.sqrt(Math.pow(Math.abs(i - x0), 2.0) + Math.pow(Math.abs(j - y0), 2.0));
|
||||||
if (r > (x0 - woffset)) {
|
if (r > (x0 - woffset)) {
|
||||||
newImage.setRGB(i - woffset, j - hoffset, -1);
|
newImage.setRGB(i - woffset, j - hoffset, -1);
|
||||||
@@ -163,6 +150,4 @@ public class RotateImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user