Skip to content

Commit

Permalink
resampling 重采样
Browse files Browse the repository at this point in the history
  • Loading branch information
Dituon committed Feb 27, 2023
1 parent b1d06fe commit f452417
Show file tree
Hide file tree
Showing 14 changed files with 2,490 additions and 72 deletions.
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@
> 画布抗锯齿, 默认为`true`
<br/>
- **resampling**: `true`

> 重采样缩放, 启用后头像质量更高, 可对模板单独配置
<br/>
- **disabled**: `[]`

> 禁用表列, 默认为空, 在此数组中的`key`不会被随机触发 (会覆盖`data.json`中的配置)
Expand Down Expand Up @@ -200,16 +205,16 @@
>
> 注: 缩放在图片合成时进行, 不会影响性能
>
> 例: (配置项为`-200 -200 -32]`时)
> 例: (配置项为`[200, 200, 32]`时)
> - 当Gif长度超过`32`帧时, 检查Gif尺寸
> - 当Gif尺寸大于`200*200`时, 对Gif进行等比例缩放
> - Gif缩放后 最长边不会超过设定值
> (当Gif中包含`40`帧, 尺寸为`300*500`时)
> - 输出的Gif长度不变, 尺寸为`120*200`
- **gifQuality**: `10`
- **gifQuality**: `5`

> Gif编码质量(`1`-`99`), 默认为`10`
> Gif编码质量(`1`-`49`), 默认为`5`
>
> 数字越小, 速度越慢, 质量越好 (大于`20`时, 速度不会有明显提升)
>
Expand Down Expand Up @@ -458,6 +463,7 @@
"pos": [[5, 8], [60, 90], [50, 90], [50, 0], [60, 120]],
"posType": "DEFORM", // 图像变形 坐标格式, 默认为ZOOM
"antialias": true, // 抗锯齿, 对头像单独使用抗锯齿算法, 默认为false
"resampling": true, // 重采样, 对头像使用重采样缩放, 默认跟随全局设置
"rotate": false // 值为true时, GIF类型的头像会旋转, 默认为false
},
{
Expand Down Expand Up @@ -634,14 +640,17 @@
启动时会生成 `config.json`:
```
{
"port": 2333, // 监听端口
"webServerThreadPoolSize": 10, // HTTP服务器线程池容量
"dataPath": "data/xmmt.dituon.petpet", // PetData路径
"gifMaxSize": [200, 200, 32], // GIF缩放阈值, 详见上文
"gifEncoder": "ANIMATED_LIB", // GIF编码器, 详见上文
"gifQuality": 100, // GIF质量, 详见上文
"gifMakerThreadPoolSize": 0, // GIF编码器线程池容量, 详见上文
"headless": true // 使用headless模式
"port": 2333, // 监听端口
"webServerThreadPoolSize": 10, // HTTP服务器线程池容量
"dataPath": "data/xmmt.dituon.petpet", // PetData路径
"preview": false, // 启用动态预览 (启动时生成所有模板预览)
"antialias": true, // 启用抗锯齿, 详见上文
"resampling": true, // 启用重采样, 详见上文
"gifMaxSize": [200, 200, 32], // GIF缩放阈值, 详见上文
"gifEncoder": "ANIMATED_LIB", // GIF编码器, 详见上文
"gifQuality": 5, // GIF质量, 详见上文
"threadPoolSize": 0, // GIF编码器线程池容量, 详见上文
"headless": true // 使用headless模式
}
```

Expand Down
17 changes: 12 additions & 5 deletions src/main/java/moe/dituon/petpet/mirai/MiraiPluginConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ object MiraiPluginConfig : AutoSavePluginConfig("PetPet")
@ValueDescription("是否使用抗锯齿")
val antialias: Boolean by value(true)

@ValueDescription("是否使用重采样")
val resampling: Boolean by value(true)

@ValueDescription("禁用列表")
val disabled: List<String> by value(emptyList())

Expand Down Expand Up @@ -51,20 +54,23 @@ object MiraiPluginConfig : AutoSavePluginConfig("PetPet")
@ValueDescription("是否使用消息事件同步锁")
val synchronized: Boolean by value(false)

// @ValueDescription("核心线程池容量, 填入0为CPU线程数+1 (默认值)")
// val serviceThreadPoolSize: Int by value(0)

@ValueDescription("GIF编码器")
val gifEncoder: Encoder by value(Encoder.ANIMATED_LIB)

@ValueDescription("GIF缩放阈值/尺寸")
val gifMaxSize: List<Int> by value(listOf(200, 200, 32))

@ValueDescription("GIF质量, 仅适用于ANIMATED_LIB编码器, 1为质量最佳, 超过20不会有明显性能提升")
val gifQuality: Int by value(10)
val gifQuality: Int by value(5)

@ValueDescription("是否使用headless模式")
val headless: Boolean by value(true)

@ValueDescription("图片合成线程池容量, 填入0为CPU线程数+1 (默认值)")
val threadPoolSize: Int by value(0)
@ValueDescription("GIF合成线程池容量, 填入0为CPU线程数+1 (默认值)")
val gifEncoderThreadPoolSize: Int by value(0)

@ValueDescription("是否自动从仓库同步PetData")
val autoUpdate: Boolean by value(true)
Expand Down Expand Up @@ -98,10 +104,11 @@ object MiraiPluginConfig : AutoSavePluginConfig("PetPet")
strictCommand = strictCommand,
synchronized = synchronized,
antialias = antialias,
// serviceThreadPoolSize = serviceThreadPoolSize,
gifMaxSize = gifMaxSize,
gifEncoder = gifEncoder,
gifQuality = gifQuality,
headless = headless,
threadPoolSize = threadPoolSize
threadPoolSize = gifEncoderThreadPoolSize,
headless = headless
)
}
9 changes: 4 additions & 5 deletions src/main/java/moe/dituon/petpet/plugin/PluginPetService.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ public void readPluginServiceConfig(PluginServiceConfig config) {

readBaseServiceConfig(config.toBaseServiceConfig());

if (super.quality < 1 || super.quality >= 100) {
if (super.quality < 1 || super.quality >= 49) {
System.out.println(
MessageFormat.format("Petpet Plugin 的GIF质量参数范围为 1-99 (1为最佳), 你提供的质量参数为{0}, 已自动更改为默认值10", quality)
MessageFormat.format("Petpet Plugin 的GIF质量参数范围为 1-49 (1为最佳), 你提供的质量参数为{0}, 已自动更改为默认值5", quality)
);
super.quality = 10;
super.quality = 5;
}

super.setGifMakerThreadPoolSize(config.getThreadPoolSize());
System.out.println("Petpet GifMakerThreadPoolSize: " + super.getGifMakerThreadPoolSize());
System.out.println("Petpet GifMakerThreadPoolSize: " + super.getGifEncoderThreadPoolSize());

for (String path : config.getDisabled()) {
disabledKey.add(path.replace("\"", ""));
Expand Down
52 changes: 28 additions & 24 deletions src/main/java/moe/dituon/petpet/plugin/PluginServiceConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ import kotlinx.serialization.json.Json
import moe.dituon.petpet.share.BaseServiceConfig
import moe.dituon.petpet.share.Encoder

interface Nudge {
val probability: Int
val respondSelfNudge: Boolean
}

interface AutoUpdate {
val autoUpdate: Boolean
val repositoryUrl: String
}

interface CoolDown {
val coolDown: Int
val groupCoolDown: Int
val inCoolDownMessage: String
}

interface DevMode {
val devMode: Boolean
}

interface MessageHook {
val messageHook: Boolean
}
//interface Nudge {
// val probability: Int
// val respondSelfNudge: Boolean
//}
//
//interface AutoUpdate {
// val autoUpdate: Boolean
// val repositoryUrl: String
//}
//
//interface CoolDown {
// val coolDown: Int
// val groupCoolDown: Int
// val inCoolDownMessage: String
//}
//
//interface DevMode {
// val devMode: Boolean
//}
//
//interface MessageHook {
// val messageHook: Boolean
//}

//@Serializable
//abstract class AbstractPluginServiceConfig : AbstractBaseServiceConfig() {
Expand Down Expand Up @@ -56,6 +56,8 @@ data class PluginServiceConfig(
val synchronized: Boolean = false,

val antialias: Boolean = true,
val resampling: Boolean = true,
// val serviceThreadPoolSize: Int = 0,
val gifMaxSize: List<Int> = emptyList(),
val gifEncoder: Encoder = Encoder.ANIMATED_LIB,
val gifQuality: Int = 5,
Expand All @@ -64,10 +66,12 @@ data class PluginServiceConfig(
) {
fun toBaseServiceConfig() = BaseServiceConfig(
antialias = antialias,
resampling = resampling,
// serviceThreadPoolSize = serviceThreadPoolSize,
gifMaxSize = gifMaxSize,
gifEncoder = gifEncoder,
gifQuality = gifQuality,
threadPoolSize = threadPoolSize,
gifEncoderThreadPoolSize = threadPoolSize,
headless = headless
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void readConfig(ServerServiceConfig config) {
usePreview = config.getPreview();

readBaseServiceConfig(config.toBaseServiceConfig());
System.out.println("GifMakerThreadPoolSize: " + super.getGifMakerThreadPoolSize());
System.out.println("GifMakerThreadPoolSize: " + super.getGifEncoderThreadPoolSize());
}

public void readConfig() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ data class ServerServiceConfig(
val preview: Boolean = false,

val antialias: Boolean = true,
val resampling: Boolean = true,
// val serviceThreadPoolSize: Int = 0,
val gifMaxSize: List<Int> = emptyList(),
val gifEncoder: Encoder = Encoder.ANIMATED_LIB,
val gifQuality: Int = 5,
Expand All @@ -35,10 +37,12 @@ data class ServerServiceConfig(

fun toBaseServiceConfig() = BaseServiceConfig(
antialias = antialias,
resampling = resampling,
// serviceThreadPoolSize = serviceThreadPoolSize,
gifMaxSize = gifMaxSize,
gifEncoder = gifEncoder,
gifQuality = gifQuality,
threadPoolSize = threadPoolSize,
gifEncoderThreadPoolSize = threadPoolSize,
headless = headless
)

Expand Down
22 changes: 19 additions & 3 deletions src/main/java/moe/dituon/petpet/share/AvatarModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

public class AvatarModel {
private Type imageType;
Expand All @@ -20,6 +23,7 @@ public class AvatarModel {
protected List<BufferedImage> imageList = null;
private short posIndex = 0;
private boolean antialias;
private boolean resampling;
private AvatarPosType posType;
private DeformData deformData = null;
private CropType cropType;
Expand Down Expand Up @@ -52,6 +56,7 @@ private void buildData(AvatarData data, Type imageType) {
rotate = Boolean.TRUE.equals(data.getRotate());
onTop = Boolean.TRUE.equals(data.getAvatarOnTop());
antialias = Boolean.TRUE.equals(data.getAntialias());
resampling = Boolean.TRUE.equals(data.getResampling());
buildImage();
}

Expand Down Expand Up @@ -122,7 +127,7 @@ private void setPos(JsonArray posElements, Type imageType) {
try {
deformData = DeformData.fromGifPos(posElements);
break;
} catch (Exception ignored){
} catch (Exception ignored) {
}
case IMG:
deformData = DeformData.fromImgPos(posElements);
Expand Down Expand Up @@ -178,11 +183,22 @@ private void buildImage() {
if (round) {
imageList = ImageSynthesis.convertCircular(imageList, antialias);
}

if (resampling && posType == AvatarPosType.ZOOM) {
imageList = new ArrayList<>(imageList);
for (short i = 0; i < imageList.size(); i++) {
imageList.set(
i,
Scalr.resize(imageList.get(i), Scalr.Method.AUTOMATIC, pos[i][2], pos[i][3])
);
}
}
}

public FitType getZoomType() {
return fitType;
}

public float getOpacity() {
return opacity;
}
Expand Down Expand Up @@ -316,7 +332,7 @@ public static DeformData fromImgPos(JsonArray posElements) {
return deformData;
}

public short getLength(){
public short getLength() {
return (short) deformPos.length;
}

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/moe/dituon/petpet/share/BaseConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ val encodeDefaultsJson = Json { encodeDefaults = true }
@Serializable
data class BaseServiceConfig(
val antialias: Boolean = true,
val resampling: Boolean = true,
// val serviceThreadPoolSize: Int = 0,
val gifMaxSize: List<Int> = emptyList(),
val gifEncoder: Encoder = Encoder.ANIMATED_LIB,
val gifQuality: Int = 5,
val threadPoolSize: Int = 0,
val gifEncoderThreadPoolSize: Int = 0,
val headless: Boolean = true
) {
fun stringify(): String {
Expand Down Expand Up @@ -151,7 +153,8 @@ data class AvatarData @JvmOverloads constructor(
var round: Boolean? = false,
var rotate: Boolean? = false,
var avatarOnTop: Boolean? = true,
val antialias: Boolean? = false
var antialias: Boolean? = false,
var resampling: Boolean? = null
)

@Deprecated("使用GifAvatarExtraDataProvider以保证对GIF格式的解析")
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/moe/dituon/petpet/share/BaseGifMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -23,8 +26,7 @@ public class BaseGifMaker {
* 默认线程池容量为 <b>CPU线程数 + 1</b>
*/
public BaseGifMaker() {
threadPool =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
threadPool = Executors.newFixedThreadPool(BasePetService.DEFAULT_THREAD_POOL_SIZE);
}

public BaseGifMaker(int threadPoolSize) {
Expand Down Expand Up @@ -121,7 +123,7 @@ public InputStream makeGIF(List<AvatarModel> avatarList, List<TextModel> textLis
gifEncoder.start(output);
gifEncoder.setRepeat(0);
gifEncoder.setDelay(params.getDelay());
gifEncoder.setQuality(100 - params.getQuality());
gifEncoder.setQuality(params.getQuality());

latch.await();
gifEncoder.setSize(size[0], size[1]);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/moe/dituon/petpet/share/BaseImageMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public InputStream makeImage(
}
}

private static InputStream bufferedImageToInputStream(BufferedImage bf) throws IOException {
public static InputStream bufferedImageToInputStream(BufferedImage bf) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bf, "png", os);
return new ByteArrayInputStream(os.toByteArray());
Expand Down
Loading

0 comments on commit f452417

Please sign in to comment.