go语言image、file、base64、buffer之间的互相转换

本文介绍了如何在Go语言中使用image和base64进行图像数据的编码与解码,涉及基础概念、接口操作及实际案例,展示了从Base64到文件、buffer、Image以及反向转换的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本笔记只作为学习笔记,本次参考内容来自以下链接:

https://studygolang.com/articles/2581
https://studygolang.com/pkgdoc
https://zhuanlan.zhihu.com/p/339477329

image

image包实现了一个基本的2D图像库,该包中包含基本的接口叫做image,这个里面包含color,这个将在image/color中描述,

image接口的值创建方式有如下几种:

1调用NewRGBA和NewPaletted

2解码一个包含gif.jpen或者png格式的image数据的io.Reader

首先介绍一些image接口

type Image    //image是一个从颜色模型中采取color.Color的矩形网格
type Image interface {
	ColorModel() color.Model //ColorModel 返回图片的 color.Model
	Bounds() Rectangle    //图片中非0color的区域
	At(x, y int) color.Color  //返回指定点的像素color.Color
}

任何一个struct只要实现了image中的三个方法,便实现了image接口。

总的来说,image存放了一个图像的全部信息,可以通过使用image,对图像进行转换和处理。

file

// File represents an open file descriptor.
type File struct {
	*file // os specific
}

File代表一个文件描述对象。

base64

百度百科中对base64的描述如下:

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。
Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。

也就是说:Base64就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集,(另加一个“=”,实际是65个字符)。任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。
知乎大佬的图(我不知道怎么去水印)
base64的转换:

首先将字符串(图片等)转换成二进制序列,然后按每6个二进制位为一组,分成若干组,如果不足6位,则低位补0。每6位组成一个新的字节,高位补00,构成一个新的二进制序列,最后根据base64索引表中的值找到对应的字符。

总的来说:base64对于我来说可以用来做图片类型的转换,从而将图片存储在文件中或进行其他操作。

buffer

对于go语言来说:

buffer 是缓冲器的意思,Go语言要实现缓冲读取需要使用到 bufio 包。bufio 包本身包装了 io.Reader 和 io.Writer 对象,同时创建了另外的 Reader 和 Writer 对象,因此对于文本 I/O 来说,bufio 包提供了一定的便利性。
buffer 缓冲器的实现原理就是,将文件读取进缓冲(内存)之中,再次读取的时候就可以避免文件系统的 I/O 从而提高速度。同理在进行写操作时,先把文件写入缓冲(内存),然后由缓冲写入文件系统。

相互转换

package main

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/jpeg"
	"io/ioutil"
	"os"
)
func showErr(err error){
	if err!=nil {
		panic(err)
	}
}

func main() {
	/*
	https://studygolang.com/articles/2581
	https://www.cnblogs.com/ghj1976/p/3443638.html
	 */

	//base64 -> file
	//成图片文件并把文件写入到buffer
	ddd, _ := base64.StdEncoding.DecodeString("./test.jpg")
	//buffer输出到jpg文件中(不做处理,直接写到文件)
	err2 := ioutil.WriteFile("./output.jpg", ddd, 0666)
	showErr(err2)


	//base64 -> buffer
	ddd2, _ := base64.StdEncoding.DecodeString("./test.jpg") //成图片文件并把文件写入到buffer
	bbb := bytes.NewBuffer(ddd2)                           	// 必须加一个buffer 不然没有read方法就会报错

	//buffer-> ImageBuff
	m, _, _ := image.Decode(bbb)                            // 图片文件解码
	rgbImg := m.(*image.YCbCr)
	subImg := rgbImg.SubImage(image.Rect(0, 0, 200, 200)).(*image.YCbCr) //图片裁剪x0 y0 x1 y1


	//img -> file
	f, _ := os.Create("test.jpg")     //创建文件
	defer f.Close()                   		//关闭文件
	jpeg.Encode(f, subImg, nil)       	//写入文件

	//img -> base64
	emptyBuff := bytes.NewBuffer(nil)                  //开辟一个新的空buff
	jpeg.Encode(emptyBuff, subImg, nil)                //img写入到buff
	dist := make([]byte, 50000)                        //开辟存储空间
	base64.StdEncoding.Encode(dist, emptyBuff.Bytes()) //buff转成base64
	fmt.Println(string(dist))                          //输出图片base64(type = []byte)
	_ = ioutil.WriteFile("./base64pic.txt", dist, 0666) //buffer输出到jpg文件中(不做处理,直接写到文件)

	//imgFile -> base64
	ff, _ := ioutil.ReadFile("output2.jpg")               //我还是喜欢用这个快速读文件
	bufstore := make([]byte, 5000000)                     //数据缓存
	base64.StdEncoding.Encode(bufstore, ff)               // 文件转base64
	_ = ioutil.WriteFile("./output2.jpg.txt", dist, 0666) //直接写入到文件就ok完活了。
}
### 将Base64字符串转换为Node.js中的文件流 在Node.js环境中,可以利用`Buffer`类来处理二进制数据。对于Base64编码的字符串转成文件流的操作,主要分为两步:先将Base64字符串解码为Buffer对象;再通过管道或者其他方式写入目标文件。 创建一个Buffer实例时指定输入为base64格式的数据[^1]: ```javascript const fs = require('fs'); // 假设这是从某处获取到的一个图片或其他类型的Base64编码串(去掉前缀data:image/png;base64,) let base64String = '...'; // 创建buffer并指明其内容是以base64形式表示 let bufferData = Buffer.from(base64String, 'base64'); ``` 接着就可以把得到的Buffer作为源传递给其他可读/可写的stream接口了。比如保存至本地磁盘上的某个位置: ```javascript // 使用writeFile方法直接写出整个buffer到文件中 fs.writeFile('./output.png', bufferData, (err) => { if (err) throw err; console.log('The file has been saved!'); }); ``` 如果希望更高效地操作大文件,则应该考虑采用Stream的方式逐步传输数据而不是一次性加载全部内容于内存之中。此时可以通过Readable Stream配合pipe()函数轻松完成此任务: ```javascript const { Readable } = require('stream'); function createReadStreamFromBuffer(buffer){ let stream = new Readable(); stream._read = () => {}; // _read is required but you can noop it. stream.push(buffer); stream.push(null); // Indicates the end of the data. return stream; } createReadStreamFromBuffer(bufferData).pipe(fs.createWriteStream('./output_stream.png')); ``` 上述代码展示了如何基于传入的Base64字符串构建出对应的Buffer对象,并进一步将其转化为文件流的形式存储下来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值