10.图片像素化使用示例

一灰灰blogQuickMediaimage-plugin约 1570 字大约 5 分钟

本文为 image-pluginopen in new window 中土拍你像素化相关操作的使用参考示例

1. 项目依赖

直接从中央仓库,导入最新依赖

<!-- https://mvnrepository.com/artifact/com.github.liuyueyi.media/image-plugin -->
<dependency>
    <groupId>com.github.liuyueyi.media</groupId>
    <artifactId>image-plugin</artifactId>
    <!-- 请使用最新版本号替换下面的版本 -->
    <version>3.1.0</version>
</dependency>

2. 参数说明

相关参数配置由com.github.hui.quick.plugin.image.wrapper.pixel.ImgPixelOptions实体类进行装载,对应的参数说明如下

参数名类型说明是否必要
sourceBufferedImage原图与下面的gifSource必须有一个存在
gifSourceGifDecodergif 图于上的source必须有一个存在
pixelTypeIPixelStyle转换类型否,默认为CHAR_COLOR
blockSizeint对于转字符图时,它控制字符大小;对于灰度/像素处理时,这个表示像素化的处理操作否 1
fontSizeint字体大小
charsString字符图时,用于渲染的字符集$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,\"^'.
fontFont字符字体否,默认黑色字体
rateDouble缩放比例,1 表示输出的图不缩放; > 1,表示生成的图,按倍数扩大否,默认1
picTypeString输出图片类型否,默认png
bgCharCharacter背景字符,默认值为空格否,默认为空格
bgColorColor字符图/svg 图的背景色否,默认白色
fontColorColor字符图/svg 图的字体色否,默认黑色
bgPredicatePredicate<Integer>背景色判断方式,传参为 intColor,如果返回 true,表示认定为背景色;否则不是否,默认颜色rbga == 0时为背景

上面的配置参数中,重点关注一下 PixelType,它表明了具体的转换策略

类型说明示例图
GRAY_ALG基于灰度公式将图片灰度化
GRAY_AVG基于灰度均值将图片灰度化
PIXEL_COLOR_AVG图片像素化时,采用颜色均值
CHAR_COLOR图片转字符图
CHAR_GRAY图片转灰度字符图
CHAR_BLACK图片转纯黑白字符,常用于svg输出
CHAR_SEQ_SCALE_UP图片转文字图,根据字符顺序绘画,且支持按比例放大
BLACK_CHAR_BORDER只针对有颜色的边框进行渲染,常用于文本输出

3. 使用示例

所有的使用姿势,可以在源码对应的test工程中获取 BasicPixelTest.javaopen in new window

根据实际需要,选择不同的处理枚举,如

case1: 希望对图片进行灰度处理时:

  • PixelStyleEnum.GRAY_ALG
  • PixelStyleEnum.GRAY_AVG
@Test
public void testGrayAlg() {
    try {
        String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setPixelType(PixelStyleEnum.GRAY_ALG)
                .build()
                .asFile("/tmp/gray_alg.png");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Test
public void testGrayAvg() {
    try {
        String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setPixelType(PixelStyleEnum.GRAY_AVG)
                .build()
                .asFile("/tmp/gray_avg.png");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

输出如下:

样式原图转换图
GRAY_ALG
GRAY_AVG

case2: 希望将图片转换像素块图时

主要需要设置 blockSize 参数,将其设置>1,此时可使用的转换类型方式为

  • PixelStyleEnum.GRAY_ALG
  • PixelStyleEnum.GRAY_AVG
  • PixelStyleEnum.PIXEL_COLOR_AVG
@Test
public void testPixelColorAvg() {
    try {
        String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setBlockSize(8)
                .setPixelType(PixelStyleEnum.PIXEL_COLOR_AVG)
                .build()
                .asFile("/tmp/pixelColorAvg.png");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

输出如下:

样式原图转换图
PIXEL_COLOR_AVG

case3: 将图转换为字符图时

可以输出图片也可以输出svg,常用的转换类型方式为

  • PixelStyleEnum.CHAR_COLOR
  • PixelStyleEnum.CHAR_GRAY
  • PixelStyleEnum.CHAR_BLACK:常用于输出svg字符图、二维字符数组
  • PixelStyleEnum.CHAR_SEQ_SCALE_UP: 它于上面三个的区别在于根据传入的文字进行顺序渲染,且对输出图片会按照文字的大小进行等比例放大、以确保文字可见
@Test
public void testCharColor() {
    try {
        String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setBlockSize(20)
                .setPixelType(PixelStyleEnum.CHAR_COLOR)
                .build()
                .asFile("/tmp/charColor.png");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Test
public void testCharGray() {
    try {
        String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setBlockSize(20)
                .setPixelType(PixelStyleEnum.CHAR_GRAY)
                .build()
                .asFile("/tmp/charGray.png");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Test
public void testCharBlack() {
    try {
//            String img = "https://pic.rmb.bdstatic.com/bjh/down/cbfbc690d1ea27f3afbe3733f49d7dac.jpeg";
        // 使用抠图后的人物图
        String img = "pixel/nezha.png";
        ImgPixelWrapper.build()
                .setSourceImg(img)
                .setBlockSize(3)
                .setRate(0.6)
                .setChars("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'  ")
                .setPixelType(PixelStyleEnum.CHAR_BLACK)
                .setBgPredicate(c -> {
                    return new Color(c, true).getAlpha() < 10;
                })
                .build()
                .asSvgFile("d://tmp/CharGray.svg");
    } catch (Exception e) {
        e.printStackTrace();
    }
}


/**
 * 使用文字来组装图片
 *
 * @throws Exception
 */
@Test
public void testCharPicture() throws Exception {
    String img = "pixel/nezha-mini.png";
    ImgPixelWrapper.build()
            .setSourceImg(img)
            .setChars("哪吒魔童降世")
            // 字体文件下载地址: https://www.diyiziti.com/Builder/446
            .setFontName("font/潇洒体.ttf")
            .setBlockSize(12)
            .setFontSize(12)
            .setBgPredicate(color -> {
                if (color == 0) {
                    return true;
                }
                Color rc = ColorUtil.int2color(color);
                // 将白色当作背景色
                return (rc.getRed() >= 245 && rc.getGreen() >= 245 && rc.getBlue() >= 245) || rc.getAlpha() < 10;
            })
            .setPixelType(PixelStyleEnum.CHAR_SEQ_SCALE_UP)
            .build()
            .asFile("/tmp/charSeq.png");
    System.out.println("---- over ---");
}
样式原图转换图
CHAR_COLOR
CHAR_GRAY
CHAR_BLACK
CHAR_SEQ_SCALE_UP

case4: 输出字符画

将图片转换为ascii或者特定的字符画,可用

  • PixelStyleEnum.CHAR_BLACK
  • PixelStyleEnum.BLACK_CHAR_BORDER: 与上面的区别在于它希望输入的是线图
@Test
public void testCharBorder() throws Exception {
    try {
        String img = "pixel/slake.jpeg";
        List<List<String>> out = ImgPixelWrapper.build().setSourceImg(img)
                .setBlockSize(30)
                .setChars("1")
                .setBgChar(' ')
                .setPixelType(PixelStyleEnum.BLACK_CHAR_BORDER)
                .setBgPredicate(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer color) {
                        if (color == 0) {
                            return true;
                        }

                        Color rc = ColorUtil.int2color(color);
                        if (rc.getAlpha() < 10) {
                            // 透明的直接过滤掉
                            return true;
                        }
                        // 将白色当作背景色
                        return rc.getRed() >= 40 && rc.getGreen() >= 40 && rc.getBlue() >= 40;
                    }
                })
                .build().asChars();

        for (String t : out.get(0)) {
            System.out.println(t);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
样式原图转换图
BLACK_CHAR_BORDER

case5: GIF图转换

上面除了给出对静态图的处理之外,我们还额外支持gif图的转换,需要注意的是gif图时,只支持输出为gif,不支持输出svg格式

基本使用姿势与前面一致,区别在于传入的图片为gif格式

@Test
public void testGif() throws Exception {
    String img = "https://img.zcool.cn/community/01565859a4ea21a801211d251e1cbc.gif";
    ImgPixelWrapper.build().setSourceImg(img)
            .setBlockSize(7)
            .setPixelType(PixelStyleEnum.CHAR_COLOR)
            .setRate(2d)
            .setFontStyle(Font.BOLD)
            .build()
            .asFile("/tmp/outV1.gif");
    System.out.println("--------");
}

@Test
public void testGifV2() throws Exception {
    String img = "https://img.zcool.cn/community/01565859a4ea21a801211d251e1cbc.gif";
    ImgPixelWrapper.build().setSourceImg(img)
            .setBlockSize(8)
            .setPixelType(PixelStyleEnum.CHAR_SEQ_SCALE_UP)
            .setChars("小黄人")
            .setBgPredicate(c -> {
                Color color = new Color(c, true);
                return color.getAlpha() < 10 || (color.getBlue() > 245 && color.getRed() > 245 && color.getGreen() > 245);
            })
            .setFontStyle(Font.BOLD)
            .build()
            .asFile("/tmp/outV2.gif");
    System.out.println("--------");
}
原图v1v2
Loading...