Java图片转字符图片的生成方法

 更新时间:2021年11月17日 09:54:37   作者:一灰灰  
本文主要实现了将一张图片转成字符图片,同样可以遍历每个像素点,然后将像素点由具体的字符来替换,从而实现字符化处理,感兴趣的可以了解一下

前面介绍了一篇java实现图片灰度化处理的小demo,接下来再介绍一个有意思的东西,将一个图片转换成字符图片

借助前面图片灰度化处理的知识点,若我们希望将一张图片转成字符图片,同样可以遍历每个像素点,然后将像素点由具体的字符来替换,从而实现字符化处理

基于上面这个思路,具体的实现就很清晰了

@Test
public void testRender() throws IOException {
    String file = "http://i0.download.fd.52shubiao.com/t_960x600/g1/M00/10/17/oYYBAFWvR5-IeXHuAAd5kPb8eSgAACm0QF50xIAB3mo414.jpg";
    // 从网络上下载图片
    BufferedImage img = ImageIO.read(FileReadUtil.getStreamByFileName(file));


    int w = img.getWidth(), h = img.getHeight();
    // 创建新的字符图片画板
    BufferedImage gray = new BufferedImage(w, h, img.getType());
    Graphics2D g2d = gray.createGraphics();
    g2d.setColor(null);
    g2d.fillRect(0, 0, w, h);

    Font font = new Font("宋体", Font.BOLD, 1);
    g2d.setFont(font);
    for (int x = 0; x < w; x ++) {
        for (int y = 0; y < h; y ++) {
   g2d.setColor(ColorUtil.int2color(img.getRGB(x, y)));
            g2d.drawString("灰", x, y);
        }
    }
    g2d.dispose();
    System.out.printf("渲染完成");
}

注意上面的实现,在会字符的时候,先取出源像素点的色彩,然后重新设置给g2d,这个int转color也比较简单,实现如下

public static Color int2color(int color) {
    int a = (0xff000000 & color) >>> 24;
    int r = (0x00ff0000 & color) >> 16;
    int g = (0x0000ff00 & color) >> 8;
    int b = (0x000000ff & color);
    return new Color(r, g, b, a);
}

这样就实现了一个基础版的转字符图了,实际跑一下看看效果

这下尴尬了,输出的并不是我们预期的字符图,那么问题出在哪呢?

仔细看上面的文字大小为1,文字太小,导致即使是有字符组件的图,最终肉眼看起来和原图也没啥区别

那么我们就试一下将这个文字搞大点,将n*n个像素点作为一个文字渲染区域,这样我们需要调整一下遍历的步长;其次就是这个区域的颜色怎么定

直接取均值

/**
 * 求取多个颜色的平均值
 *
 * @return
 */
Color getAverage(BufferedImage image, int x, int y, int w, int h) {
    int red = 0;
    int green = 0;
    int blue = 0;

    int size = 0;
    for (int i = y; (i < h + y) && (i < image.getHeight()); i++) {
        for (int j = x; (j < w + x) && (j < image.getWidth()); j++) {
            int color = image.getRGB(j, i);
            red += ((color & 0xff0000) >> 16);
            green += ((color & 0xff00) >> 8);
            blue += (color & 0x0000ff);
            ++size;
        }
    }

    red = Math.round(red / (float) size);
    green = Math.round(green / (float) size);
    blue = Math.round(blue / (float) size);
    return new Color(red, green, blue);
}

另外的就是改一下遍历的步长

@Test
public void testRender() throws IOException {
    String file = "http://i0.download.fd.52shubiao.com/t_960x600/g1/M00/10/17/oYYBAFWvR5-IeXHuAAd5kPb8eSgAACm0QF50xIAB3mo414.jpg";
    // 从网络上下载图片
    BufferedImage img = ImageIO.read(FileReadUtil.getStreamByFileName(file));


    int w = img.getWidth(), h = img.getHeight();
    // 创建新的灰度图片画板
    BufferedImage gray = new BufferedImage(w, h, img.getType());
    Graphics2D g2d = gray.createGraphics();
    g2d.setColor(null);
    g2d.fillRect(0, 0, w, h);

    int size = 12;
    Font font = new Font("宋体", Font.BOLD, size);
    g2d.setFont(font);
    for (int x = 0; x < w; x += size) {
        for (int y = 0; y < h; y += size) {
            Color avgColor = getAverage(img, x, y, size, size);
            g2d.setColor(avgColor);
            g2d.drawString("灰", x, y);
        }
    }
    g2d.dispose();
    System.out.printf("渲染完成");
}

再次执行之后结果如下,实现了我们的预期效果

最后再介绍一个更好用的姿势,直接使用开源项目https://github.com/liuyueyi/quick-media 来实现图片字符画
使用这个项目的 image-plugins 之后,生成一个灰度图就很简单了

public void testCharImg() throws IOException {
    String img = "http://hbimg.b0.upaiyun.com/2b79e7e15883d8f8bbae0b1d1efd6cf2c0c1ed1b10753-cusHEA_fw236";
    BufferedImage out = ImgPixelWrapper.build().setSourceImg(img).setBlockSize(2)
            .setPixelType(PixelStyleEnum.CHAR_COLOR)
            .setChars("小灰灰blog")
            .build()
            .asBufferedImg();
    System.out.println(out);
}

注意这个ImgPixelWrapper封装类,处理基础的字符处理之外,还支持生成灰度图,gif图转字符动画,图片像素化(如马赛克...)

至于quick-media这个项目就更有意思了,java侧若想生成酷炫的二维码,选择它绝对不会让你失望;有兴趣的小伙伴可以瞅一瞅

到此这篇关于Java图片转字符图片的生成方法的文章就介绍到这了,更多相关Java图片转字符图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java快速排序和选择排序实现实例解析

    java快速排序和选择排序实现实例解析

    这篇文章主要为大家介绍了java快速排序和选择排序实现实例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 浅谈java线程状态与线程安全解析

    浅谈java线程状态与线程安全解析

    本文主要介绍了浅谈java线程状态与线程安全解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Arrays.asList方法总结

    Arrays.asList方法总结

    本文主要对Arrays.asList方法进行总结。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • SpringBoot整合Xxl-Job的完整步骤记录

    SpringBoot整合Xxl-Job的完整步骤记录

    这篇文章主要给大家介绍了关于SpringBoot整合Xxl-Job的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java实现多个单张tif文件合并成一个多页tif文件

    Java实现多个单张tif文件合并成一个多页tif文件

    业务部门需要将多个单张的tiff文件,合并成一个多页的tiff文件,本文就来介绍一下如何实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • SpringCloud实现全链路灰度发布的示例详解

    SpringCloud实现全链路灰度发布的示例详解

    灰度发布是指在软件或服务发布过程中,将新版本的功能或服务以较小的比例引入到生产环境中,仅向部分用户或节点提供新功能的一种发布策略,下面我们就来学习一下SpringCloud如何实现全链路灰度发布
    2023-11-11
  • SpringAOP事务配置语法及实现过程详解

    SpringAOP事务配置语法及实现过程详解

    这篇文章主要介绍了SpringAOP事务配置语法及实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • SpringAop中的Advice通知实例

    SpringAop中的Advice通知实例

    这篇文章主要介绍了SpringAop中的Advice通知详解,Spring的AOP功能中一个关键概念是通知Advice与切点Pointcut表达式相关联在特定节点织入一些逻辑,Spring提供了五种类型的通知,需要的朋友可以参考下
    2023-09-09
  • Java大数据开发Hadoop MapReduce

    Java大数据开发Hadoop MapReduce

    MapReduce的思想核心是“分而治之”,适用于大量复杂的任务处理场景(大规模数据处理场景)Map负责“分”,即把复杂的任务分解为若干个“简单的任务”来并行处理。可以进行拆分的前提是这些小任务可以并行计算,彼此间几乎没有依赖关系
    2023-03-03
  • @Autowired注入为null的原因与解决方法

    @Autowired注入为null的原因与解决方法

    我们经常会通过@Autowired注解将某个类注到另一个类中,但是会发现注不进去,报NULL,所以本文就给大家分析了@Autowired 注入为null 的原因与解决方法,需要的朋友可以参考下
    2023-09-09

最新评论