Skip to content

Commit

Permalink
3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Dituon committed Jun 27, 2022
1 parent 85b7266 commit 4a01617
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 28 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ content:
"pos": [0, 0, 200, 200]
```

###### 仿射变换/图像变形

**坐标格式枚举`posType`**

- `ZOOM` 缩放(见上文)
- `DEFORM` 变形

`DEFORM` 坐标格式为 `[[x1,y1],[x2,y2],[x3,y3],[x4,y4]]`;
分别对应图片的`[[左下角],[左上角],[右上角],[右下角]]`

目前仿射变换仅支持单帧

#### 头像

`3.0`版本后 提供了更灵活的头像构造方法, 与之前的版本有很大差别
Expand All @@ -147,11 +159,12 @@ content:
"pos": [[92, 64, 40, 40], [135, 40, 40, 40], [84, 105, 40, 40]], // 坐标
"round": true, // 值为true时, 头像裁切为圆形, 默认为false
"avatarOnTop": true // 值为true时, 头像图层在背景之上, 默认为true
"angle": 90, // 初始角度, 目前仅支持整数
"angle": 90, // 初始角度
},
{
"type": "TO",
"pos": [[58, 90, 50, 50], [62, 95, 50, 50], [42, 100, 50, 50]],
"pos": [[65, 128],[60,210],[110,210],[110, 120]],
"posType": "DEFORM", //图像变形 坐标格式, 默认为ZOOM
"antialias": true, // 抗锯齿, 对头像单独使用抗锯齿算法, 默认为false
"rotate": false // 值为true时, GIF类型的头像会旋转, 默认为false
}
Expand Down
4 changes: 1 addition & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import sun.font.EAttribute

plugins {
id 'org.jetbrains.kotlin.jvm' version '1.6.10'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.10'
Expand All @@ -13,7 +11,7 @@ apply plugin: "java"


group = 'xmmt.dituon'
version = '3.0'
version = '3.1'

repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/xmmt/dituon/plugin/Petpet.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import net.mamoe.mirai.event.events.GroupMessageEvent;
import net.mamoe.mirai.event.events.NudgeEvent;
import net.mamoe.mirai.message.data.*;
import xmmt.dituon.share.AvatarExtraData;
import xmmt.dituon.share.BaseConfigFactory;
import xmmt.dituon.share.TextExtraData;

Expand All @@ -19,7 +18,7 @@

public final class Petpet extends JavaPlugin {
public static final Petpet INSTANCE = new Petpet();
public static final float VERSION = 3.0F;
public static final float VERSION = 3.1F;

ArrayList<Group> disabledGroup = new ArrayList<>();
PluginPetService pluginPetService;
Expand Down Expand Up @@ -98,7 +97,8 @@ private void onGroupMessage(GroupMessageEvent e) {
key = firstWord;
otherText = m.contentToString().replace(key, "").trim();

if (!pluginPetService.commandMustAt && notContainsAt(e.getMessage())) {
if (!pluginPetService.commandMustAt &&
notContainsAt(e.getMessage()) && !e.getMessage().contains(Image.Key)) {
pluginPetService.sendImage(e.getGroup(), e.getGroup().getBotAsMember(),
e.getSender(), key, otherText);
return;
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/xmmt/dituon/share/AvatarModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import kotlinx.serialization.json.JsonArray;
import kotlinx.serialization.json.JsonElement;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/xmmt/dituon/share/ImageDeformer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package xmmt.dituon.share;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

Expand Down
63 changes: 46 additions & 17 deletions src/main/java/xmmt/dituon/share/ImageSynthesis.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ public static BufferedImage synthesisImage(BufferedImage sticker,
}

// 背景
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, sticker.getWidth(), sticker.getHeight());
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0F));
output = g2d.getDeviceConfiguration().createCompatibleImage(
sticker.getWidth(), sticker.getHeight(), Transparency.TRANSLUCENT);
g2d.dispose();
g2d = output.createGraphics();

// g2d.setColor(Color.WHITE);
// g2d.fillRect(0, 0, sticker.getWidth(), sticker.getHeight());
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0F));

// 按照图层分类
ArrayList<AvatarModel> topAvatars = new ArrayList<>();
Expand Down Expand Up @@ -56,34 +61,37 @@ public static BufferedImage synthesisImage(BufferedImage sticker,
private static void drawAvatar(Graphics2D g2d, AvatarModel avatar) {
switch (avatar.getPosType()) {
case ZOOM:
g2dDrawZoomAvatar(g2d, avatar.getImage(), avatar.nextPos(), avatar.getRotateIndex(), avatar.getAngle());
g2dDrawZoomAvatar(g2d, avatar.getImage(),
avatar.nextPos(), avatar.getRotateIndex(), avatar.getAngle(), avatar.isRound());
break;
case DEFORM:
g2dDrawDeformAvatar(g2d, avatar.getImage(), avatar.getDeformPos());
}
}

private static void g2dDrawZoomAvatar(Graphics2D g2d, BufferedImage avatarImage, int[] pos, int rotateIndex, int angle) {
private static void g2dDrawZoomAvatar(Graphics2D g2d, BufferedImage avatarImage, int[] pos,
int rotateIndex, int angle, boolean isRound) {
if (avatarImage == null) {
return;
}
BufferedImage newAvatarImage = new BufferedImage(avatarImage.getWidth(), avatarImage.getHeight(), avatarImage.getType());

if (rotateIndex == 0 && angle == 0) {
newAvatarImage = avatarImage;
} else {
Graphics2D rotateG2d1 = newAvatarImage.createGraphics();
//TODO 旋转时会有黑边 应当使用AffineTransform
rotateG2d1.rotate(Math.toRadians((float) ((360 / pos.length) * (rotateIndex)) + angle),
avatarImage.getWidth() / 2, avatarImage.getHeight() / 2);
rotateG2d1.drawImage(avatarImage, null, 0, 0);
}

int x = pos[0];
int y = pos[1];
int w = pos[2];
int h = pos[3];
g2d.drawImage(newAvatarImage, x, y, w, h, null);
if (rotateIndex == 0 && angle == 0) {
g2d.drawImage(avatarImage, x, y, w, h, null);
return;
}

if (isRound || angle % 90 == 0) {
Graphics2D rotateG2d = avatarImage.createGraphics();
rotateG2d.rotate(angle);
g2d.drawImage(avatarImage, x, y, w, h, null);
return;
}

g2d.drawImage(rotateImage(avatarImage, angle), x, y, w, h, null);
}

private static void g2dDrawDeformAvatar(Graphics2D g2d, BufferedImage avatarImage, Point2D[] pos) {
Expand Down Expand Up @@ -115,6 +123,27 @@ public static BufferedImage convertCircular(BufferedImage input, boolean antiali
return output;
}

public static BufferedImage rotateImage(BufferedImage avatarImage, int angle) {
double sin = Math.abs(Math.sin(Math.toRadians(angle))),
cos = Math.abs(Math.cos(Math.toRadians(angle)));
int w = avatarImage.getWidth();
int h = avatarImage.getHeight();
int neww = (int) Math.floor(w * cos + h * sin),
newh = (int) Math.floor(h * cos + w * sin);
BufferedImage rotated = new BufferedImage(neww, newh, avatarImage.getType());
Graphics2D g2d = rotated.createGraphics();
rotated = g2d.getDeviceConfiguration().createCompatibleImage(
rotated.getWidth(), rotated.getHeight(), Transparency.TRANSLUCENT);
g2d.dispose();
g2d = rotated.createGraphics();

g2d.translate((neww - w) / 2, (newh - h) / 2);
g2d.rotate(Math.toRadians(angle), w / 2, h / 2);
g2d.drawRenderedImage(avatarImage, null);
g2d.dispose();
return rotated;
}

public static BufferedImage getAvatarImage(String URL) {
HttpURLConnection conn = null;
BufferedImage image = null;
Expand Down

0 comments on commit 4a01617

Please sign in to comment.