怎么样用Java实现将一张图片转成字符画??

输入:一张图片

输出:一个txt文档,由字符组成,看起来很像那张照片的字符画。

基本思想:凭据照片的灰度接纳差别的字符画出来,形成一个灰度表。

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

public class Test {

public static void main(String[] args) throws IOException {

String path = "D:/logo.jpg";//导入的图片

String base = "love";//将会用这个字符串里的字符填充图片

BufferedImage image = ImageIO.read(new File(path));//读入图片,并用图片缓冲区工具来吸收

//双层for循环,遍历图片

for (int y = 0; y < image.getHeight(); y++) {//先竖向遍历,再横向遍历,即一行一行的找,后面也会一行一行的打印

for (int x = 0; x < image.getWidth(); x++) {

int color = image.getRGB(x, y);//图片缓冲区自带的方式,可以获得当前点的颜色值,返回值是int类型

int r=(color>>16)&0xff;

int g=(color>>8)&0xff;

int b=color&0xff;

float gray = 0.299f * r + 0.578f * g + 0.114f * b;//灰度值盘算公式,牢固比例,无需明白

int index = Math.round(gray * (base.length()) / 255);

if(index>=base.length()) {

System.out.print(" ");//白色的地方打空格,相当于白色靠山,这样图片轮廓对照显著

}else {

System.out.print(base.charAt(index));//有颜色的地方打字符

}

}

System.out.println();//一行打完,换行

}

}

}

代码思绪

整体思绪为导入想好处置的图片,遍历,获得每个像素点的颜色,然后将其转换成灰度值(也就是把彩色转换成是非),凭据获得的灰度值盘算字符串索引,到达效果就是差别颜色可以对应差别的下标,以此来匹配字符串中的字符,最后根据原有的坐标点把这些字符打印出来即可

界说好想要填充的字符串

导入想要处置的图片,需要用到BufferedImage(图片缓冲区)这个工具

遍历整张图片,这里需要注重,外层循环遍历y轴,内层遍历x轴,由于打印的时刻需要一行一行打印,打完一行要换行

凭据getRGB(x,y)方式,传入当前的坐标点,获得当前点的颜色

从获得的颜色中单独拆分出r,g,b的值

凭据获得的rgb盘算对应的灰度值

凭据灰度值盘算索引

打印

难点解说

若何获得RGB

int color = image.getRGB(x, y);//图片缓冲区自带的方式,可以获得当前点的颜色值,返回值是int类型

int r=(color>>16)&0xff;

int g=(color>>8)&0xff;

int b=color&0xff;

1

2

3

4

首先明确一点,所谓的rgb就是三原色,red,green,blue,无论是ps照样程序,都市通过给rgb赋值来拼成一个新的颜色。通过etRGB(x,y)获得的颜色是一个int类型,我们用color来示意。这个值包罗四部分内容,分别为a,r,g,b,即透明度,red,green,blue。每一部分正好占一个字节。以是我们要做的就是从这个int中去单独获得从左数第二,第三,第四字节的数值。

怎么做呢?先来回首两个位运算的基本知识:

“&”,与,都是0则效果为0,都是1效果为1,一个1一个0效果为0.从数学上明白,&操作符其实是在取交集。

7&5=?

首先换算成二进制,7的二进制是0111,5的二进制是0101

0111&0101=0101,照样5。

通过上面的盘算有没有发现一个纪律,若是我想要让一个数和另一个数&完效果照样这个数自己怎么办?好比我想让0101,0111,0011和一个数&完效果照样他们自己,那么这个数应该是多少。

“>>”,右移.

8>>2,示意8向右平移两位,效果为2.

8的二进制1000,右移两位,0010.

现在想想,怎么样通过上面两个符号从一个int中获得某一个字节的数值,好比获得第二字节的值,也就是r的值。

冒充你们想了20分钟。

我们用二进制来看,假设我们获得的color换算成二进制是:

01111100 01011010 10001101 00111110

我们要获得从左数第二个字节的值,怎么办?

首先,把这个数向右平移两个字节,也就是16位,那么就是color>>16,效果为

00000000 00000000 01111100 01011010

此时,再和11111111与一下,是不是就获得这个数自己了。

00000000 00000000 01111100 01011010

&

00000000 00000000 00000000 11111111

=

00000000 00000000 00000000 01011010

现在获得的就是r的值。写法:(color>>16)& 0xff.

0x示意16进制,16进制的ff示意的就是二进制的8个1。

以此类推,获得g就是(color>>8)& 0xff,获得b就是color & 0xff。

注:这里注重,方式不唯一,也可以先与后右移。这种方式是用位运算符来做的,固然也能转换成二进制数组然后拆分。那么为什么要用位运算符来做呢,第一是利便,第二就是很有逼格啊老铁。

若何让差别颜色匹配差别字符

int index = Math.round(gray * (base.length()) / 255);

1

gray是我们求出的灰度值,它的最大值也是255。差别颜色获得的gray不一样,同理,gray/255获得的就是差别颜色对应的一个比例,用这个比例乘以字符串长度就完成了差别颜色或者说差别颜色段匹配了差别的字符下标。因此获得gray * (base.length()) / 255,然后通过Math.round()方式四舍五入取整。

这里需要注重一下, 这样打印出来的字符图片色调会对照深,为了让颜色区分更显著,我们可以让一些接近于白色的浅色都打印成空格,那么我们就写成

int index = Math.round(gray * (base.length()+1) / 255);

1

把字符串长度加一,然后再做乘除操作,这样会让一部分颜色对应的索引大于字符串长度。

我们打印的时刻是这样判断的,若是index大于即是字符串长度就打印空格,若是不是才打印字符。

为什么我的图片只能打一半

eclipse的控制台输出的行数有限,跨越划定行数就覆盖了。这时可以把y++,改成y+=2,相当于每隔两个点取一下颜色并打印,也就是把原图纵向上缩小了一半。为了保持原图的比例,同理也可以把x做响应调整。

OUTOFMEMORYERROR错误

内存溢出,图片太大了,换个小一点的图片

为什么用汉字来打印图案会扭曲

字母或字符占得巨细比汉字要小,汉字所占的空间很大,若是根据原有的点来打印汉字,由于汉字的宽度险些比字母大一倍,以是会被挤出去,造成了扭曲。解决方式:改变y和x的自增数,也就是把x++改成+2,+3这样的,横向上每隔两个点打印一下,给汉字预留出空间

原文链接:https://www.cnblogs.com/wangshuaiandroid/p/12863393.html

本站声明:网站内容来源于网络,若有侵权,请联系我们,我们将及时处置。

java字符拼成_Java字符拼成图片(image-ASCII)(非原创)相关推荐

  1. java long string 转换_Java long 转成 String的实现

    Java long 转成 String的实现 第一种: String s = String.valueOf(long) 第二种: String s = Long.toString(long) 补充知识 ...

  2. java oracle中文乱码_java字符编码和oracle乱码

    编码问题我仍旧没搞懂,最根本的从哪里来就没搞懂.当页面发送请求,编码到后台是什么编码呢?好吧,我默认的都是utf-8.后台接收参数后,可以在控制台打印出来,我也不清楚是什么编码.然后,就是数据库问题. ...

  3. java 字符流读取_Java 字符流读写文件

    据说,java读写文件要写很多,贼麻烦,不像c艹,几行代码就搞定.只能抄抄模板拿来用了. 输入输出流分字节流和字符流.先看看字符流的操作,字节转化为字符也可读写. 一.写入文件 1.FileWrite ...

  4. java 源码分析_Java 源代码编译成 Class 文件的过程分析

    原标题:Java 源代码编译成 Class 文件的过程分析 在上篇文章< Java三种编译方式:前端编译 JIT编译 AOT编译 >中了解到了它们各有什么优点和缺点,以及前端编译+JIT编 ...

  5. java 字符终端库_Java 字符终端上获取输入三种的方式分享

    在java 字符终端上获取输入有三种方式: 1.java.lang.system.in (目前jdk版本均支持) 2.java.util.scanner (jdk版本>=1.5) 3.java. ...

  6. java 符号乱码怎么办_java字符乱码怎么办

    java字符乱码怎么办? 我尝试了所有的设置编码的方法: 1.重新给字符串编码再解码name = URLEncoder.encode(name, "ISO-8859-1"); na ...

  7. java字符转变汉子_java字符编码转换研究(转) 第一部分收藏

    未找到原出处,请见谅. 1. 概述 本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2 ...

  8. java字符编码采用_JAVA字符编码三:Java应用中的编码问题

    1. 概述 本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是" ...

  9. java字符编码问题_JAVA字符编码系列三:Java应用中的编码问题

    1. 概述 本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是" ...

  10. java定义字符串数组_java字符数组用法总结,java字符串数组的定义与使用

    java字符数组,java数组的定义与使用 二维数组 String[] str = new String[5]; //创建一个长度为5的String(字符串)型的一维数组 String[] str = ...

最新文章

  1. 链表问题15——将搜索二叉树转换成双向链表(方法二)
  2. 安卓 AsyncHttpClient - “Content-Type not allowed!”
  3. Track与nqa联动 VS 静态路由优先级相同
  4. 机器学习笔记:Adam
  5. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象
  6. log4j2配置文件的故事
  7. 前端学习(3165):react-hello-react之UUID库
  8. 身份证合法验证查询易语言代码
  9. ARM体系结构与编程 书
  10. 企业微信开发实战:自建审批流引擎
  11. Tomcat安装配置及CATALINA_HOME environment variable is not defined correctly问题的解决
  12. 可靠性(reliability)弱点度量
  13. LGP970刷机心得
  14. 网站漏洞安全渗透测试公司组建方案
  15. Hadoop-day07(MapReduce三个小案例)
  16. 无蓝光的护眼灯有哪些品牌?盘点无蓝光护眼灯排行榜
  17. 经营收款限制个人收款码,商户的个税会受影响吗?
  18. 四、搭建第一个直播系统
  19. 前端架构师神技,三招统一团队代码风格
  20. static定义静态方法

热门文章

  1. VMware Perl SDK error “Server Version Unavailable .. line 545”
  2. [转] C# mysql 事务回滚
  3. SharePoint 2007 做Migration中需要注意的一些问题
  4. 【读史笔记】《晋书·卫玠列传》
  5. vue2项目中全局引入scss变量
  6. usc计算机博士游戏专业,USC工科博士专业排名,必然得仔细的看
  7. erlang连接数据库mysql_[原]Erlang连接mysql问题解决
  8. python3生成exe文件_python3.7打包成exe就三步
  9. python百度关键词自动提交订单_百度链接提交-主动推送Python版
  10. 两个乒乓球队进行比赛 各出3人c语言_19年国际乒乓球大赛时间出炉:比赛的密集程度令人窒息!...