job修改

This commit is contained in:
JiyangTang 2023-07-03 11:41:50 +08:00
parent ed92db8b91
commit 75fb7b9eda
11 changed files with 761 additions and 83 deletions

View File

@ -11,7 +11,7 @@ import java.util.Date;
* @date: 2023/06/16 : 12:09 * @date: 2023/06/16 : 12:09
*/ */
@Data @Data
public class EdgeXAnnouncementsDto implements Serializable { public class AnnouncementsDto implements Serializable {
private static final long serialVersionUID = 2069054276884655439L; private static final long serialVersionUID = 2069054276884655439L;

View File

@ -1,81 +0,0 @@
package top.baogutang.admin.schedule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import top.baogutang.admin.domain.EdgeXAnnouncementsDto;
import top.baogutang.admin.services.IWxMsgPushService;
import top.baogutang.admin.utils.DingTalkMsgPushUtils;
import top.baogutang.common.domain.Page;
import top.baogutang.common.domain.Results;
import top.baogutang.common.properties.WxMsgPushProperties;
import top.baogutang.common.utils.HttpUtils;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static top.baogutang.common.constants.CacheConstant.MSG_PUSH_PREFIX_KEY;
/**
* @description: EDGEX公告
* @author: nikooh
* @date: 2023/06/16 : 11:41
*/
@Slf4j
@Component
@RefreshScope
public class EdgeXNoticeSchedule {
@Resource
private IWxMsgPushService wxMsgPushService;
@Resource
private WxMsgPushProperties wxMsgPushProperties;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private DingTalkMsgPushUtils dingTalkMsgPushUtils;
@Value("${dingtalk.baogutang.agentId}")
private String agentId;
private static final String REQUEST_URL = "https://art-api.edge-x.cn/api/v1/art/announcements?pageNum=1&pageSize=1";
/**
* 每分钟查询edgeX公告
*/
@Scheduled(cron = "0 0/1 * * * ? ")
public void edgeXNotice() {
Results<Page<EdgeXAnnouncementsDto>> results = HttpUtils.get(REQUEST_URL, new TypeReference<Results<Page<EdgeXAnnouncementsDto>>>() {
});
log.info(">>>>>>>>>>请求获取edgeX公告返回数据{}<<<<<<<<<<", JSON.toJSONString(results));
if (Objects.isNull(results)) {
return;
}
if (!Boolean.TRUE.equals(results.isSuccess())) {
return;
}
if (Objects.isNull(results.getData()) || CollectionUtils.isEmpty(results.getData().getList())) {
return;
}
EdgeXAnnouncementsDto announcementsDto = results.getData().getList().get(0);
String cacheKey = String.format(MSG_PUSH_PREFIX_KEY, announcementsDto.getId());
Boolean result = redisTemplate.opsForValue().setIfAbsent(cacheKey, 1, 5, TimeUnit.DAYS);
if (Boolean.TRUE.equals(result)) {
String content = "# " + announcementsDto.getTitle() + "\n\n![](" + announcementsDto.getCover() + ")\n\n> 点击下方链接查看更多详情:\n\n[查看详情](" + "https://app.edge-x.cn/#/noticeDetail?noticeId=" + announcementsDto.getId() + ")";
dingTalkMsgPushUtils.robotMarkdownMsgPush(announcementsDto.getTitle(), content);
// wxMsgPushService.msgPush(Message.CONTENT_TYPE_HTML, announcementsDto.getTitle(), announcementsDto.getContent(), wxMsgPushProperties.getTopicIds());
}
}
}

View File

@ -0,0 +1,110 @@
package top.baogutang.admin.schedule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import top.baogutang.admin.domain.AnnouncementsDto;
import top.baogutang.admin.services.IWxMsgPushService;
import top.baogutang.admin.utils.DingTalkMsgPushUtils;
import top.baogutang.common.domain.Page;
import top.baogutang.common.domain.Results;
import top.baogutang.common.properties.WxMsgPushProperties;
import top.baogutang.common.utils.HttpUtils;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static top.baogutang.common.constants.CacheConstant.MSG_PUSH_PREFIX_KEY;
/**
* @description: EDGEX公告
* @author: nikooh
* @date: 2023/06/16 : 11:41
*/
@Slf4j
@Component
@RefreshScope
public class NoticeSchedule {
@Resource
private IWxMsgPushService wxMsgPushService;
@Resource
private WxMsgPushProperties wxMsgPushProperties;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private DingTalkMsgPushUtils dingTalkMsgPushUtils;
@Value("${dingtalk.baogutang.agentId}")
private String agentId;
private static final String EDGE_X_REQUEST_URL = "https://art-api.edge-x.cn/api/v1/art/announcements?pageNum=1&pageSize=1";
private static final String EDGE_REQUEST_URL = "https://art-api.heishiapp.com/api/v1/art/announcements?pageNum=1&pageSize=1";
/**
* 每分钟查询edgeX公告
*/
@Scheduled(cron = "0 0/1 * * * ? ")
public void edgeXNotice() {
Results<Page<AnnouncementsDto>> results = HttpUtils.get(EDGE_X_REQUEST_URL, new TypeReference<Results<Page<AnnouncementsDto>>>() {
});
log.info(">>>>>>>>>>请求获取edgeX公告返回数据{}<<<<<<<<<<", JSON.toJSONString(results));
if (Objects.isNull(results)) {
return;
}
if (!Boolean.TRUE.equals(results.isSuccess())) {
return;
}
if (Objects.isNull(results.getData()) || CollectionUtils.isEmpty(results.getData().getList())) {
return;
}
AnnouncementsDto announcementsDto = results.getData().getList().get(0);
String cacheKey = String.format(MSG_PUSH_PREFIX_KEY, "edge_x", announcementsDto.getId());
Boolean result = redisTemplate.opsForValue().setIfAbsent(cacheKey, 1, 5, TimeUnit.DAYS);
if (Boolean.TRUE.equals(result)) {
String content = "# EDGE-X-" + announcementsDto.getTitle() + "\n\n![](" + announcementsDto.getCover() + ")\n\n> 点击下方链接查看更多详情:\n\n[查看详情](" + "https://app.edge-x.cn/#/noticeDetail?noticeId=" + announcementsDto.getId() + ")";
dingTalkMsgPushUtils.robotMarkdownMsgPush(announcementsDto.getTitle(), content);
// wxMsgPushService.msgPush(Message.CONTENT_TYPE_HTML, announcementsDto.getTitle(), announcementsDto.getContent(), wxMsgPushProperties.getTopicIds());
}
}
/**
* 每分钟查询edge公告
*/
@Scheduled(cron = "0 0/1 * * * ? ")
public void edgeNotice() {
Results<Page<AnnouncementsDto>> results = HttpUtils.get(EDGE_REQUEST_URL, new TypeReference<Results<Page<AnnouncementsDto>>>() {
});
log.info(">>>>>>>>>>请求获取edge公告返回数据{}<<<<<<<<<<", JSON.toJSONString(results));
if (Objects.isNull(results)) {
return;
}
if (!Boolean.TRUE.equals(results.isSuccess())) {
return;
}
if (Objects.isNull(results.getData()) || CollectionUtils.isEmpty(results.getData().getList())) {
return;
}
AnnouncementsDto announcementsDto = results.getData().getList().get(0);
String cacheKey = String.format(MSG_PUSH_PREFIX_KEY, "edge", announcementsDto.getId());
Boolean result = redisTemplate.opsForValue().setIfAbsent(cacheKey, 1, 5, TimeUnit.DAYS);
if (Boolean.TRUE.equals(result)) {
String content = "# EDGE-" + announcementsDto.getTitle() + "\n\n![](" + announcementsDto.getCover() + ")\n\n> 点击下方链接查看更多详情:\n\n[查看详情](" + "https://activities-h5.heishiapp.com/#/noticeDetail?noticeId=" + announcementsDto.getId() + ")";
dingTalkMsgPushUtils.robotMarkdownMsgPush(announcementsDto.getTitle(), content);
// wxMsgPushService.msgPush(Message.CONTENT_TYPE_HTML, announcementsDto.getTitle(), announcementsDto.getContent(), wxMsgPushProperties.getTopicIds());
}
}
}

View File

@ -0,0 +1,28 @@
package top.baogutang.common.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import top.baogutang.common.serialize.SensitiveJsonSerializer;
import top.baogutang.common.serialize.SensitiveStrategy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 敏感注解
*
* @author liushuai(liushuai711 @ gmail.com)
* @version v4.0
* @Description:
* @since 2021/9/10 16:45
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
SensitiveStrategy strategy();
}

View File

@ -30,7 +30,7 @@ public class CacheConstant {
/** /**
* 消息推送 * 消息推送
*/ */
public static final String MSG_PUSH_PREFIX_KEY = "top:baogutang:msg:push:%d:"; public static final String MSG_PUSH_PREFIX_KEY = "top:baogutang:msg:push:%s:%d:";
public static final Integer ENABLE = 0; public static final Integer ENABLE = 0;

View File

@ -0,0 +1,57 @@
package top.baogutang.common.serialize;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import top.baogutang.common.annotation.Sensitive;
import java.io.IOException;
import java.util.Objects;
/**
* 敏感信息序列化时 过滤
*
* @author liushuai(liushuai711 @ gmail.com)
* @version v4.0
* @Description:
* @since 2021/9/10 16:46
*/
public class SensitiveJsonSerializer extends JsonSerializer<String>
implements ContextualSerializer, ApplicationContextAware {
private SensitiveStrategy strategy;
/**
* 系统配置
*/
private SystemSettingProperties systemSettingProperties;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 字段序列化处理
gen.writeString(strategy.desensitizer().apply(value));
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
//获取敏感枚举
Sensitive annotation = property.getAnnotation(Sensitive.class);
//如果有敏感注解则加入脱敏规则
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
this.strategy = annotation.strategy();
return this;
}
return prov.findValueSerializer(property.getType(), property);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
systemSettingProperties = applicationContext.getBean(SystemSettingProperties.class);
}
}

View File

@ -0,0 +1,50 @@
package top.baogutang.common.serialize;
import java.util.function.Function;
/**
* 敏感策略枚举
*
* @author liushuai(liushuai711 @ gmail.com)
* @version v4.0
* @Description:
* @since 2021/9/10 16:46
*/
public enum SensitiveStrategy {
/**
* Username sensitive strategy.
*/
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* Id card sensitive type.
*/
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
/**
* Phone sensitive type.
*/
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* Email sensitive type.
*/
EMAIL(s -> s.replaceAll("(^\\w)[^@]*(@.*$)", "$1****$2")),
/**
* Name sensitive type.
*/
NAME(s -> s.replaceAll("^(.{3}).+(.{3})$", "$1*****$2")),
/**
* Address sensitive type.
*/
ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));
private final Function<String, String> desensitizer;
SensitiveStrategy(Function<String, String> desensitizer) {
this.desensitizer = desensitizer;
}
public Function<String, String> desensitizer() {
return desensitizer;
}
}

View File

@ -0,0 +1,60 @@
package top.baogutang.common.serialize;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 系统设置
*
* @author Chopper
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "baogutang.system")
public class SystemSettingProperties {
/**
* 是否是演示站点
*/
private Boolean isDemoSite = false;
/**
* 测试模式
* 验证码短信为6个1
*/
private Boolean isTestModel = false;
/**
* 脱敏级别
* 0不做脱敏处理
* 1管理端用户手机号等信息脱敏
* 2商家端信息脱敏为2时表示管理端商家端同时脱敏
* <p>
* PS:
*/
private Integer sensitiveLevel = 0;
public Boolean getDemoSite() {
if (isDemoSite == null) {
return false;
}
return isDemoSite;
}
public Boolean getTestModel() {
if (isTestModel == null) {
return false;
}
return isTestModel;
}
public Integer getSensitiveLevel() {
if (sensitiveLevel == null) {
return 0;
}
return sensitiveLevel;
}
}

View File

@ -0,0 +1,235 @@
package top.baogutang.common.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Base64编码
*
* @author looly
* @since 3.2.0
*/
public class Base64Utils {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
/**
* 标准编码表
*/
private static final byte[] STANDARD_ENCODE_TABLE = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
/**
* URL安全的编码表 + / 替换为 - _
*/
private static final byte[] URL_SAFE_ENCODE_TABLE = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '-', '_'
};
//-------------------------------------------------------------------- encode
/**
* 编码为Base64非URL安全的
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
*/
public static byte[] encode(byte[] arr, boolean lineSep) {
return encode(arr, lineSep, false);
}
/**
* 编码为Base64URL安全的
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
* @since 3.0.6
*/
public static byte[] encodeUrlSafe(byte[] arr, boolean lineSep) {
return encode(arr, lineSep, true);
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
public static String encode(CharSequence source) {
return encode(source, DEFAULT_CHARSET);
}
/**
* base64编码URL安全
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(CharSequence source) {
return encodeUrlSafe(source, DEFAULT_CHARSET);
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
*/
public static String encode(CharSequence source, Charset charset) {
return encode(bytes(source, charset));
}
/**
* base64编码URL安全的
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(CharSequence source, Charset charset) {
return encodeUrlSafe(bytes(source, charset));
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
public static String encode(byte[] source) {
return str(encode(source, false), DEFAULT_CHARSET);
}
/**
* base64编码,URL安全的
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(byte[] source) {
return str(encodeUrlSafe(source, false), DEFAULT_CHARSET);
}
/**
* 编码为Base64<br>
* 如果isMultiLine为<code>true</code>则每76个字符一个换行符否则在一行显示
*
* @param arr 被编码的数组
* @param isMultiLine 在76个char之后是CRLF还是EOF
* @param isUrlSafe 是否使用URL安全字符一般为<code>false</code>
* @return 编码后的bytes
*/
public static byte[] encode(byte[] arr, boolean isMultiLine, boolean isUrlSafe) {
if (null == arr) {
return null;
}
int len = arr.length;
if (len == 0) {
return new byte[0];
}
int evenlen = (len / 3) * 3;
int cnt = ((len - 1) / 3 + 1) << 2;
int destlen = cnt + (isMultiLine ? (cnt - 1) / 76 << 1 : 0);
byte[] dest = new byte[destlen];
byte[] encodeTable = isUrlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
for (int s = 0, d = 0, cc = 0; s < evenlen; ) {
int i = (arr[s++] & 0xff) << 16 | (arr[s++] & 0xff) << 8 | (arr[s++] & 0xff);
dest[d++] = encodeTable[(i >>> 18) & 0x3f];
dest[d++] = encodeTable[(i >>> 12) & 0x3f];
dest[d++] = encodeTable[(i >>> 6) & 0x3f];
dest[d++] = encodeTable[i & 0x3f];
if (isMultiLine && ++cc == 19 && d < destlen - 2) {
dest[d++] = '\r';
dest[d++] = '\n';
cc = 0;
}
}
//剩余位数
int left = len - evenlen;
if (left > 0) {
int i = ((arr[evenlen] & 0xff) << 10) | (left == 2 ? ((arr[len - 1] & 0xff) << 2) : 0);
dest[destlen - 4] = encodeTable[i >> 12];
dest[destlen - 3] = encodeTable[(i >>> 6) & 0x3f];
if (isUrlSafe) {
//在URL Safe模式下=为URL中的关键字符不需要补充空余的byte位要去掉
int urlSafeLen = destlen - 2;
if (2 == left) {
dest[destlen - 2] = encodeTable[i & 0x3f];
urlSafeLen += 1;
}
byte[] urlSafeDest = new byte[urlSafeLen];
System.arraycopy(dest, 0, urlSafeDest, 0, urlSafeLen);
return urlSafeDest;
} else {
dest[destlen - 2] = (left == 2) ? encodeTable[i & 0x3f] : (byte) '=';
dest[destlen - 1] = '=';
}
}
return dest;
}
/**
* 编码字符串
*
* @param str 字符串
* @param charset 字符集如果此字段为空则解码的结果取决于平台
* @return 编码后的字节码
*/
public static byte[] bytes(CharSequence str, Charset charset) {
if (str == null) {
return null;
}
if (null == charset) {
return str.toString().getBytes();
}
return str.toString().getBytes(charset);
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集如果此字段为空则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String str(byte[] data, Charset charset) {
if (data == null) {
return null;
}
if (null == charset) {
return new String(data);
}
return new String(data, charset);
}
}

View File

@ -0,0 +1,37 @@
package top.baogutang.common.utils;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
/**
* 通用工具
* @author Chopper
*/
public class CommonUtils {
public static final String BASE_NUMBER = "0123456789";
/**
* 以UUID重命名
* @param fileName 文件名称
* @return 格式化名称
*/
public static String rename(String fileName) {
String extName = fileName.substring(fileName.lastIndexOf("."));
return UUID.randomUUID().toString().replace("-", "") + extName;
}
/**
* 随机6位数生成
*/
public static String getRandomNum() {
StringBuilder sb = new StringBuilder(6);
for (int i = 0; i < 6; i++) {
int num = ThreadLocalRandom.current().nextInt(BASE_NUMBER.length());
sb.append(BASE_NUMBER.charAt(num));
}
return sb.toString();
}
}

View File

@ -0,0 +1,182 @@
package top.baogutang.common.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* ImageUtil
*
* @author niko
* @version v1.0
* 2020-11-17 14:50
*/
public class ImageUtil {
/**
* 添加水印
*
* @param oriImage 原图
* @param text 文字
* @throws IOException 流操作异常
*/
public static void addWatermark(BufferedImage oriImage, String text) {
Graphics2D graphics2D = oriImage.createGraphics();
//设置水印文字颜色
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//设置水印文字Font
graphics2D.setColor(Color.black);
//设置水印文字透明度
graphics2D.setFont(new Font("宋体", Font.BOLD, 30));
//第一参数->设置的内容后面两个参数->文字在图片上的坐标位置(x,y)
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f));
graphics2D.drawString(text, 10, 40);
graphics2D.dispose();
}
/**
* 干扰图
*
* @param oriImage 原图
* @param templateImage 模板图
* @param x 随机扣取坐标X
* @param y 随机扣取坐标y
*/
public static void interfereTemplate(BufferedImage oriImage, BufferedImage templateImage,
int x, int y) {
//临时数组遍历用于高斯模糊存周边像素值
int[][] matrix = new int[3][3];
int[] values = new int[9];
int xLength = templateImage.getWidth();
int yLength = templateImage.getHeight();
//模板图像宽度
for (int i = 0; i < xLength; i++) {
//模板图片高度
for (int j = 0; j < yLength; j++) {
//如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
int rgb = templateImage.getRGB(i, j);
if (rgb < 0) {
//抠图区域高斯模糊
readPixel(oriImage, x + i, y + j, values);
fillMatrix(matrix, values);
oriImage.setRGB(x + i, y + j, avgMatrix(matrix));
}
//防止数组越界判断
if (i == (xLength - 1) || j == (yLength - 1)) {
continue;
}
int rightRgb = templateImage.getRGB(i + 1, j);
int downRgb = templateImage.getRGB(i, j + 1);
//描边处理,取带像素和无像素的界点判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
boolean rgbImage = ((rgb >= 0 && rightRgb < 0)
|| (rgb < 0 && rightRgb >= 0)
|| (rgb >= 0 && downRgb < 0)
|| (rgb < 0 && downRgb >= 0));
}
}
}
/**
* @param oriImage 原图
* @param templateImage 模板图
* @param newImage 新抠出的小图
* @param x 随机扣取坐标X
* @param y 随机扣取坐标y
*/
public static void cutByTemplate(BufferedImage oriImage, BufferedImage templateImage, BufferedImage newImage,
int x, int y) {
//临时数组遍历用于高斯模糊存周边像素值
int[][] matrix = new int[3][3];
int[] values = new int[9];
int xLength = templateImage.getWidth();
int yLength = templateImage.getHeight();
//模板图像宽度
for (int i = 0; i < xLength; i++) {
//模板图片高度
for (int j = 0; j < yLength; j++) {
//如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
int rgb = templateImage.getRGB(i, j);
if (rgb < 0) {
newImage.setRGB(i, j, oriImage.getRGB(x + i, y + j));
//抠图区域高斯模糊
readPixel(oriImage, x + i, y + j, values);
fillMatrix(matrix, values);
oriImage.setRGB(x + i, y + j, avgMatrix(matrix));
}
//防止数组越界判断
if (i == (xLength - 1) || j == (yLength - 1)) {
continue;
}
int rightRgb = templateImage.getRGB(i + 1, j);
int downRgb = templateImage.getRGB(i, j + 1);
//描边处理,取带像素和无像素的界点判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
boolean rgbImage = ((rgb >= 0 && rightRgb < 0)
|| (rgb < 0 && rightRgb >= 0)
|| (rgb >= 0 && downRgb < 0)
|| (rgb < 0 && downRgb >= 0));
if (rgbImage) {
newImage.setRGB(i, j, Color.GRAY.getRGB());
}
}
}
}
public static void readPixel(BufferedImage img, int x, int y, int[] pixels) {
int xStart = x - 1;
int yStart = y - 1;
int current = 0;
for (int i = xStart; i < 3 + xStart; i++) {
for (int j = yStart; j < 3 + yStart; j++) {
int tx = i;
if (tx < 0) {
tx = -tx;
} else if (tx >= img.getWidth()) {
tx = x;
}
int ty = j;
if (ty < 0) {
ty = -ty;
} else if (ty >= img.getHeight()) {
ty = y;
}
pixels[current++] = img.getRGB(tx, ty);
}
}
}
public static void fillMatrix(int[][] matrix, int[] values) {
int filled = 0;
for (int[] x : matrix) {
for (int j = 0; j < x.length; j++) {
x[j] = values[filled++];
}
}
}
public static int avgMatrix(int[][] matrix) {
int r = 0;
int g = 0;
int b = 0;
for (int[] x : matrix) {
for (int j = 0; j < x.length; j++) {
if (j == 1) {
continue;
}
Color c = new Color(x[j]);
r += c.getRed();
g += c.getGreen();
b += c.getBlue();
}
}
return new Color(r / 8, g / 8, b / 8).getRGB();
}
}