一、实现方法

字符画实际上是将图片的每一个像素点,按一定的标准(如灰度值等)替换为字符(如图所示,图示为黑色背景,白色字体)。

二、图片转字符画 实现过程

①读取图片(这里使用java.jwt自带的BufferedImage对象读取)

  /** 获取最原生的BufferedImage对象 */public static BufferedImage getBufferedImage(final String src) throws FileNotFoundException, IOException {return ImageIO.read(new FileInputStream(new File(src.trim())));}

②对图片进行处理(如压缩、灰度化、二值化等),一般来说,先二值/灰度化后再压缩,效果比较好,当然具体情况具体分析

下面贴上代码

 /*** 按设置的宽度高度比例压缩图片文件,如果width和height都大于0,则以此为基准进行压缩(可能造成图片变型)* * @param oldFile*            要进行压缩的文件全路径* @param newFile*            新文件* @param width*            宽度* @param height*            高度* @return 返回压缩后的文件的全路径*/
public static BufferedImage zipImageFileWithRate(BufferedImage image, int width, int height) {if (image == null) {return null;}if(width<=0&&height<=0){return image;}/* 对服务器上的临时文件进行处理 *//* 按比例压缩 */int w = image.getWidth(null);int h = image.getHeight(null);double bili;if (width > 0&&height<=0) {bili = width / (double) w;height = (int) (h * bili);} else if (height > 0&&width<=0) {bili = height / (double) h;width = (int) (w * bili);}BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D graphics = buffImg.createGraphics();graphics.getFontRenderContext();graphics.setBackground(new Color(255, 255, 255));graphics.setColor(new Color(255, 255, 255));graphics.fillRect(0, 0, width, height);graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);StringOutputter.print("压缩图片 (宽:?,高:?)==>成功", width,height);return buffImg;
}/*** 根据路径获取灰度化后的图片*/
public static BufferedImage getGrayBufferedImage(final BufferedImage image)throws FileNotFoundException, IOException {int width = image.getWidth();int height = image.getHeight();BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int rgb = image.getRGB(i, j);grayImage.setRGB(i, j, rgb);}}return grayImage;
}
/*** 获取二值化图片*/
public static BufferedImage getBinaryBufferedImage(final BufferedImage image) {if (image == null) {return null;}int width = image.getWidth();int height = image.getHeight();BufferedImage binaryImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int rgb = image.getRGB(i, j);binaryImage.setRGB(i, j, rgb);}}return binaryImage;
}

③遍历图片,根据灰度值,从已知的字符字典里获取字符,并写入txt文件

     /*** 获取图片在x,y轴的rgb值*/public static RgbPixel getScreenPixel(BufferedImage image, int x, int y) {if (isLegal(image, x, y)) {RgbPixel rgb = new RgbPixel();int pix = image.getRGB(x, y);rgb.setRed((pix & 0xff0000) >> 16);// 最高8位为Redrgb.setGreen((pix & 0x00ff00) >> 8);// 中间8位为Greenrgb.setBlue((pix & 0x0000ff));// 最低8位为Bluereturn rgb;}return null;}/* 主要实现函数,遍历整张图片 */public static void write(BufferedImage image,FileOutputStream fop) throws IOException{/* 遍历整个图像,xy像素点填充字符 */for (int j = image.getMinY(); j < image.getHeight(); j++) {for (int i = image.getMinX(); i < image.getWidth(); i++) {RgbPixel pixel = PictureReader.getScreenPixel(image, i, j);int index = RgbNumberWritter.getChar(pixel);fop.write(DICTORY.charAt(index));// 插入字符fop.write(32);// 加个空格,防止图片会看起来扁了一半}/* 填充换行符 */fop.write(10);}}

这里为了方便,自己写了一个RgbPixel类(getter和setter没有贴出)

    public class RgbPixel {private int red;private int green;private int blue;public double getGray(){/** 灰度值公式:Gray=R×0.299+G×0.587+B×0.114*/double gray=red*0.299+green*0.587+blue*0.114;return gray;}

从字符字典中获取对应字符(根据灰度值):DICTORY是字典,下标越大,代表其灰度值越大

 private final static String DICTORY=" .,·-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\\/{}[]?23456789AJKLICFDBEGHMNPQRSTUVWXYZ%&#$0O@";private final static int DICTORY_LEN=DICTORY.length();/** 获取该灰度值对应下标 */public static int getChar(RgbPixel rgb){double key =DICTORY_LEN- Math.round(rgb.getGray()/STEP);if(key>=1){key-=1;}return (int)key;}

通过上面几个步骤,可以很快的生成对应的txt文本:

三、字符画(txt)转图片

(一)、方法

字符画转图片,只需要读取txt文本里的文本信息,然后直接画在图片上即可,
Graphics提供了drawString方法,可以很方便的生成,需要注意的是,为了生成的图片能尽可能的还原图片,所以建议使用等宽字体,并且调整好图片的大小(字体的单位是pt,像素单位是px,具体请参考:https://blog.csdn.net/gogl/article/details/48584191 、 https://blog.csdn.net/flyeek/article/details/43934945 )
为什么还要多此一举把txt生成图片呢?因为我电脑上的文本阅读器功能比较少,不能将文字缩放成特别小的尺寸,所以生成的字符画看不到全局,而图片可以。

这里挖个坑,剩下的以后写,部分代码如下

(二)、代码

public static boolean writePictureFromFile(File file,String output,int IMAGE_WIDTH , int IMAGE_HEIGHT,final int fontSize,boolean whiteBackGround){boolean flag=false;if(file!=null&&file.exists()&&!file.isDirectory()){BufferedReader reader = null;try {reader = new BufferedReader(new FileReader(file));//像素点和字体大小转化
//              IMAGE_WIDTH*=ptToPx(fontSize);
//              IMAGE_HEIGHT*=(ptToPx(fontSize)+2);IMAGE_WIDTH*=((fontSize&1)==0? fontSize:fontSize+1); IMAGE_HEIGHT*=(fontSize+2);
//              StringOutputter .print("produce a image with Width:? ,Height:?",IMAGE_WIDTH,IMAGE_HEIGHT);BufferedImage bimage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,BufferedImage.TYPE_INT_RGB);//获取图像上下文Graphics g = createGraphics(bimage,IMAGE_WIDTH,IMAGE_HEIGHT,fontSize,whiteBackGround);String line;//图片中文本行高FontMetrics metrics = g.getFontMetrics();
//              final int Y_LINEHEIGHT =  (ptToPx(fontSize)+2);//一般是像素大小+2final int Y_LINEHEIGHT = metrics.getHeight(); //相当于fontsize+2;
//              StringOutputter.print("@ :height:? ,Y_LINEHEIGHT: ?", height,Y_LINEHEIGHT);int lineNum = 1;try {while((line = reader.readLine()) != null){
//                      StringOutputter.print("Get Line[?]:?",lineNum,line);g.drawString(line, 0, lineNum * Y_LINEHEIGHT);
//                      StringOutputter.print("lineNum * Y_LINEHEIGHT: ? ,width:?", lineNum * Y_LINEHEIGHT,metrics.stringWidth(line));lineNum++;}g.dispose();//保存为jpg图片FileOutputStream out = new FileOutputStream(output);ImageIO.write(bimage, "JPEG", out);out.close();StringOutputter.print("写文本图片(像素:(?,?))==>成功 (输出路径:?)",IMAGE_WIDTH,IMAGE_HEIGHT, output);} catch (IOException e) {e.printStackTrace();return false;}return true;} catch (FileNotFoundException e) {e.printStackTrace();return false;}finally{if(reader!=null){try {reader.close();} catch (IOException e) {e.printStackTrace();}}}}return flag;}
/*** 获取图片的上下文,设置样式* @param image 处理的图片对象* @param IMAGE_WIDTH 宽* @param IMAGE_HEIGHT 高* @param fontSize 字体大小* @param whiteBackGround 是否为白底黑字* @return*/
private static Graphics createGraphics(final BufferedImage image,final int IMAGE_WIDTH,final  int IMAGE_HEIGHT,final int fontSize,final boolean whiteBackGround){if(IMAGE_WIDTH>0&&IMAGE_HEIGHT>0){//创建图片Graphics g = image.createGraphics();//设置背景色if(whiteBackGround){g.setColor(null); }else{g.setColor(Color.BLACK);}g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);//绘制背景//设置前景色if(whiteBackGround){g.setColor(Color.BLACK); }else{g.setColor(Color.WHITE); }g.setFont(new Font(FONT_NAME, Font.PLAIN, fontSize)); //设置字体return g;}return null;
}

四、代码共享

挖个坑以后填…

【图片、字符画互转】字符画实现(JAVA)相关推荐

  1. python图像转字符画_python图像处理-字符画风格图片

    前言 字符画图片,顾名思义就是由一个个字符组成的图片,下面这张图片很容易帮助你理解,如果我们可以将字符排列好,让他看上去像一个物体的形状,那么最后再将它输出保存为一张图片就可以实现了. 下面的这些形状 ...

  2. python学习之手把手教你将图片变成黑白或彩色字符画(骚操作)

    文章目录 前言 一.字符画的实现原理 二.黑白字符画实现代码 三.彩色字符画生成 代码实现: 总结 前言 字符画这个话题,似乎早在贴吧时代就已经被玩烂了.在百度图片随便一搜索,就能够看到非常多.然后在 ...

  3. vue-quill-editor上传内容由于图片是base64的导致字符太长的问题解决

    vue-quill-editor上传内容由于图片是base64的导致字符太长的问题解决 参考文章: (1)vue-quill-editor上传内容由于图片是base64的导致字符太长的问题解决 (2) ...

  4. 仿抖音--将图片转化成对应的字符图片

    起初看到抖音上的那个将图片转化成对应的字符图片的视频,心动不已,哇!这哥们也太有心了吧,虽说莉哥好看,但你做这图要花多长时间呀!值不值啊! 后来我才知道,java实现的话简直一秒钟的事. 第一开始只能 ...

  5. 仅仅有人物没背景的图片怎么弄_纯干货//只会画人物不会画背景?这3种方法教你快速画背景!...

    很多同学只会画人物不会画背景,于是就想到了一些骚操作-- 1.万年"留白"党:不会画干脆就不画,一片白板走天下!喂喂喂,你就这么随便留一大片空白的背景,对得起可爱的纱雾妹妹吗! 2 ...

  6. 【python】将图片绘制成像素风的画,Tiler

    这个项目超级火! 将图片转化成像素风的画. 不要问,问就是Tiler! 项目地址: git clone https://github.com/nuno-faria/tiler.git 安装依赖包: p ...

  7. 使用Python完成曾火爆全网的图片转符号图片、GIF图像转字符GIF动画操作

    前言 这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题 于是乎,我自己开发了一款面试宝典,希 ...

  8. excel 画散点图 怎么设置图片的分辨率_Slynyrd像素画教程:像素画基础教程

    Slynyrd像素画教程:像素画基础教程 作者:Slynyrd[1] 翻译:三二 (转载请注明出处) 关注公众号:教你画像素画 微信号:pixelfish 微博:教你画像素画2014 在合适的条件下, ...

  9. 仅仅有人物没背景的图片怎么弄_只会画人物不会画背景?这3种方法教你快速画背景!...

    原标题:只会画人物不会画背景?这3种方法教你快速画背景! 很多同学只会画人物不会画背景,于是就想到了一些骚操作-- 1.万年"留白"党:不会画干脆就不画,一片白板走天下! 喂喂喂, ...

  10. python画正方形-用python画正方形

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 我正在学习python学习教程,我无法打开屏幕进行绘图. 我没有发现错误,它只是 ...

最新文章

  1. 控制器属性传值的一些小问题
  2. linux不保存退出命令_面试提问说出16个linux命令,能凑齐不!高频22个Linux命令在这里...
  3. linux修改容器内的mysql端口映射_修改docker容器端口映射的方法
  4. 打开pix4d无有效许可_我市两家企业通过危险废物综合经营许可证专家核查
  5. 实现EventHandler的监测
  6. simply scheme 第一章 练习+ 看书计划
  7. Linux与Windows中的UTC时间
  8. 获取 子文件夹 后缀_后期制作老司机教你一键批量生成项目文件夹
  9. oracle 10g的进程主要分为,Oracle10g 后台进程列表
  10. LSTM背后的数学原理
  11. hadoop无法停止
  12. Xeam Visual Installer白金版,Xeam Visual Installer完整用户体验
  13. uniapp 获取android设备 GPS 信号强弱
  14. 花花的森林(倍增,LCA
  15. 流浪地球的终点正是三体人要逃离的地方
  16. 日志易之配置日志内容黑名单
  17. 数加使用自定义调度资源进行数据同步
  18. 记一次spark两个大表join数据倾斜调优
  19. 所有手机都支持物联卡吗,物联卡为什么手机不能用
  20. 条形码、二维码的生成与扫描、解析本地二维码

热门文章

  1. python 爬取链家二手房信息
  2. c语言程序设计课程表,c语言怎样编写课程表,请问程序怎样写?
  3. lan pci 联想开机_联想笔记本bios怎么设置 联想笔记本进入bios方法【详解】
  4. g729编解码的总结
  5. 华为给出的测试账号里面的题
  6. Java为什么要面向接口编程
  7. 使用typescript开发集成阿里云短信接口
  8. php mktime 2037,phpmktime计算两时间之差_PHP教程
  9. POI 4.1.2 word转html(保留样式及图片)
  10. 启动马达接线实物图_常见电机控制实物接线图,简单原理分析,学习入门,值得收藏...