hi~我是郑突突
今天我们学习:java图片与字节流的相互转换。
场景:用户端上传一个图片,图片转换成字节流,字节流使用Base64编码,然后服务端收到Base64编码后的字符串,然后转换成图片,最终实现图片的传输。
为什么要使用Base64?
我们知道在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。
而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,
由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。
所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。我们的数据传输基本上使用ascil码传输。
图片转换成字节流,保存的是每个像素点的rgb值?基数是256,但我们的数据传输,比如说255 就是11111111,就会显示128 个特殊符号字符、外来语字母和图形符号。就是乱码。
Base64的实现原理:实现原理
首先将图片转换成字节流
static byte[] image2Bytes(String imgSrc) throws Exception {
FileInputStream fin = new FileInputStream(new File(imgSrc));
//可能溢出,简单起见就不考虑太多,如果太大就要另外想办法,比如一次传入固定长度byte[]
byte[] bytes = new byte[fin.available()];
//将文件内容写入字节数组,提供测试的case
fin.read(bytes);
fin.close();
return bytes;
}
byte[] b1 = image2Bytes(path+"\\Jordan.jpg"); //path是绝对路径
byte[] b1 = image2Bytes(path+"\\Jordan.jpg"); //path是绝对路径
System.out.println(new String(b1));
System.out.println("b1=" + Arrays.toString(b1));
为什么会有负数?
因为涉及到补码,比如说255,就是1111111,然后啥啥啥的,反正就变成了复数,这里的负数就是128以后的ascil码值了,就是“乱码”。
字节流的Base64编码和解码
byte[] b1 = image2Bytes(path+"\\Jordan.jpg"); //path是绝对路径
System.out.println(new String(b1));
System.out.println("*图片的字节数组 = " + Arrays.toString(b1));
byte[] b2 = Base64.getEncoder().encode(b1);
System.out.println("编码后的字节数组 = "+Arrays.toString(b2));
System.out.println("编码后的字节数组对应的ascil码值 = "+new String(b2));
byte[] b3 = Base64.getDecoder().decode(b2);
System.out.println("解码后的字节数组 = "+Arrays.toString(b3));
还有更多的基于Base64编码的不同方法,有基于url的,基于http的。
读者可以自行去搜索。
static void buff2Image(byte[] b,String tagSrc) throws Exception {
FileOutputStream fout = new FileOutputStream(tagSrc);
//将字节写入文件
fout.write(b);
fout.close();
}
buff2Image(b3, path+"\\test.jpg");
完成了图像的传递!!