图片转字符图片(一)

简介: 图片转字符图片

序言

这个是从抖音上学来的,一开始刷抖音,遇到不少字符串跳舞的视频,因此来实践一下

主要分为三个部分

  1. 静态图片转静态图片
  2. gif 转 gif
  3. 视频转视频

静态图片转静态图片

其实原理很简单,读取图片的像素,新建一张大小一样的图片,根据原图像素的灰度,决定是不是要显示出来,并在新图相应的位置添加字符,这样就完成了

借助前辈写的工具,主要包含一下四个类:
AnimatedGifEncoder
GifDecoder
LZWEncoder
NeuQuant

源地址
https://github.com/rtyley/animated-gif-lib-for-java
ps: 网上各种版本的太多,不清楚这个是不是原作者,github上搜GifDecoder,有不少

环境:

JDK 1.8
注:Java原生代码实现使用jdk内部的GIFImageReader、GIFImageWriter等类,maven在编译的时候会提示这是sun公司的私有API,在1.7、1.8版的JDK中已经删除,所以是有风险的。在此使用ImageIO这个类来进行图片的操作。

主要代码如下所示:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName: ImgUtil
 * @Description: TODO
 * @author jiang
 * @date 2018年8月14日 下午10:15:56
 * 
 */
public class ImgUtil {

    static Logger logger = LoggerFactory.getLogger(ImgUtil.class);

    public static boolean toTextImg(String inputFile, String outputFile, final String base, int threshold) {

//        String blackFile = "F:/123/head_black.png";
        BufferedImage src = null;
        BufferedImage tag = null;
        boolean res = false;
        try {
            src = ImageIO.read(new FileInputStream(inputFile));
            int[] rgb = new int[3];
            int width = src.getWidth();
            int height = src.getHeight();
            int minx = src.getMinX();
            int miny = src.getMinY();
            // 黑白化
/*-                        
            src = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, null);
            res = ImageIO.write(src, blackFile.substring(blackFile.lastIndexOf(".") + 1), new File(blackFile));
            src = ImageIO.read(new FileInputStream(blackFile));*/

            tag = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics g = tag.getGraphics();
            g.setFont(new Font("微软雅黑", Font.PLAIN, 10));// 设置字体
            g.setColor(Color.BLUE);// 设置颜色
            for (int x = minx; x < width; x += 6) {
                for (int y = miny; y < height; y += 6) {
                    int pixel = src.getRGB(x, y); // 下面三行代码将一个数字转换为RGB数字
                    rgb[0] = (pixel & 0xff0000) >> 16;// red
                    rgb[1] = (pixel & 0xff00) >> 8;// green
                    rgb[2] = (pixel & 0xff);// blue
                    final float gray = 0.299f * rgb[0] + 0.578f * rgb[1] + 0.114f * rgb[2];
                    final int index = Math.round(gray * (base.length() + 1) / 255);
//                    logger.debug("{},{}",index,base.length() / threshold);
                    if (index <= threshold) {
                        g.drawString(String.valueOf(base.charAt(index % base.length())), x, y);// 文字的编写及位置
                    }

                    /*-
                    if (rgb[0] + rgb[1] + rgb[2] <= 500) {
                        System.out.println("i=" + i + ",j=" + j + ":(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")");
                        g.drawString("v", i, j);// 文字的编写及位置
                    }*/
                }
            }
            g.dispose();

            // 输出图片
            res = ImageIO.write(tag, outputFile.substring(outputFile.lastIndexOf(".") + 1),
                    new File(outputFile));
            logger.debug("字符化结果:{}", res);
        } catch (IOException e) {
            logger.error("err", e);
            return false;
        }
        return true;
    }

}

代码的思路很简单,src.getRGB(x, y)获取具体像素点的颜色值,共六位,每两位一个颜色值,依次是red green blue,类似的使用(pixel & 0xff0000) >> 16获取第一位的红色等,根据灰度公式Gray = R*0.299 + G*0.587 + B*0.114计算灰度(百度颜色灰度公式,有很多来计算心理灰度的解决方案),选择合适的灰度替换上合适的字符即可

源码地址:
https://github.com/Ruffianjiang/java4fun/tree/master/img2text

参考:

  1. https://blog.csdn.net/chwshuang/article/details/64923345
目录
相关文章
|
存储 缓存 JSON
Unity资源热更新知识梳理及工作流介绍
研究了大半年的热更,才做出了一套相对完善的热更架构。不得不说,这块的知识点还是多而杂的,值得专门开篇博文来记录梳理。
3057 0
|
11月前
|
运维 监控 Linux
BPF及Linux性能调试探索初探
BPF技术从最初的网络数据包过滤发展为强大的系统性能优化工具,无需修改内核代码即可实现实时监控、动态调整和精确分析。本文深入探讨BPF在Linux性能调试中的应用,介绍bpftune和BPF-tools等工具,并通过具体案例展示其优化效果。
501 14
|
11月前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
缓存 监控 固态存储
在Linux中,如何管理和优化文件系统的性能?
在Linux中,如何管理和优化文件系统的性能?
native本地编包 || deb打包 || 构建第一个deb包hello
native本地编包 || deb打包 || 构建第一个deb包hello
native本地编包 || deb打包 || 构建第一个deb包hello
|
搜索推荐 安全 Java
elasticsearch安装详细教程
elasticsearch安装详细教程
|
存储 网络协议 应用服务中间件
Linux EX200-RHCSA考题『上篇』
在练习期间,除了您就坐位置的台式机之外,还将使用多个虚拟系统。您不具有台式机系统的根访问权,但具有对虚拟系统的完全根访问权。
1816 0
Linux EX200-RHCSA考题『上篇』
|
算法 计算机视觉 索引
试分析:编码器- 解码器网络结构的设计理念
试分析:编码器- 解码器网络结构的设计理念
1108 0
试分析:编码器- 解码器网络结构的设计理念
|
机器学习/深度学习 存储 人工智能
反向传播不香了?解读 Hinton 大佬的 Forward-Forward 算法
反向传播不香了?解读 Hinton 大佬的 Forward-Forward 算法