在 GoLang 中将图像转换为 Base64
Converting Images to Base64 in GoLang
我正在尝试使用 Base64 编码转换图像并将它们保存到数据库中。这是我的程序:
- HTML 页面显示一个用于浏览图像的按钮
- 正在通过以下代码处理图像:
func HandleUpload(w http.ResponseWriter, r *http.Request, formFileName string) (string, string, string, error) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(1 << 2)
file, handler, err := r.FormFile(formFileName)
if err != nil {
// If there is an error that means form is empty. Return nil for err in order
// to validate result as required.
return "", "", "", nil
}
defer file.Close()
fmt.Printf("Uploaded File: %+v\n", handler.Filename)
fmt.Printf("File Size: %+v\n", handler.Size)
fmt.Printf("MIME Header: %+v\n", handler.Header)
tempFile, err := ioutil.TempFile(TmpDirectory, "upload-*.png")
if err != nil {
log.Println(err)
return "", "", "", err
}
defer tempFile.Close()
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
log.Println(err)
return "", "", "", err
}
tempFile.Write(fileBytes)
fmt.Fprintf(w, "Successfully Uploaded File\n")
// create a new buffer base on file size
fInfo, _ := tempFile.Stat()
var size int64 = fInfo.Size()
buf := make([]byte, size)
// read file content into buffer
fReader := bufio.NewReader(tempFile)
fReader.Read(buf)
contentType := http.DetectContentType(fileBytes)
switch contentType {
case "image/png":
fmt.Println("Image type is already PNG.")
case "image/jpeg":
fmt.Println("Image type is JPG, converting it to PNG.")
img, err := jpeg.Decode(bytes.NewReader(fileBytes))
if err != nil {
return "", "", "", errors.Wrap(err, "unable to decode jpeg")
}
buf := new(bytes.Buffer)
if err := png.Encode(buf, img); err != nil {
return "", "", "", errors.Wrap(err, "unable to encode png")
}
}
//convert the buffer bytes to base64 string - use buf.Bytes() for new image
imgBase64Str := base64.StdEncoding.EncodeToString(buf)
filePath := filepath.Join(TmpDirectory, tempFile.Name())
return handler.Filename, filePath, imgBase64Str, nil}
- 返回的
ImageBase64Str
被写入数据库,尽管我认为 PostgreSQL 数据库在输入时可以接受一个限制。我的 ImageBase64Str
长 71000 个字符! 为什么?它看起来像这样:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
我假设这不是预期的输出。
有人可以帮忙吗?
语句buf := make([]byte, size)
分配了一片零字节。语句 imgBase64Str := base64.StdEncoding.EncodeToString(buf)
将那些零字节编码为 base64,给出 result you observe.
数据的 base64 编码比原始数据大 4 / 3 倍。大图像将产生大编码。
函数不需要临时文件。使用从表单文件中提取的字节。
这是代码的简化和修复版本:
func HandleUpload(w http.ResponseWriter, r *http.Request, formFileName string) (string, string, error) {
// Maximum upload of 10 MB files r.ParseMultipartForm(1 << 2)
file, hdr, err := r.FormFile(formFileName)
if err != nil {
// If there is an error that means form is empty. Return nil for err in order
// to validate result as required.
return "", "", nil
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
log.Println(err)
return "", "", err
}
contentType := http.DetectContentType(data)
switch contentType {
case "image/png":
fmt.Println("Image type is already PNG.")
case "image/jpeg":
img, err := jpeg.Decode(bytes.NewReader(data))
if err != nil {
return "", "", fmt.Errorf("unable to decode jpeg: %w", err)
}
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
return "", "", fmt.Errorf("unable to encode png: %w", err)
}
data = buf.Bytes()
default:
return "", "", fmt.Errorf("unsupported content typo: %s", contentType)
}
imgBase64Str := base64.StdEncoding.EncodeToString(data)
return hdr.Filename, imgBase64Str, nil
}
我正在尝试使用 Base64 编码转换图像并将它们保存到数据库中。这是我的程序:
- HTML 页面显示一个用于浏览图像的按钮
- 正在通过以下代码处理图像:
func HandleUpload(w http.ResponseWriter, r *http.Request, formFileName string) (string, string, string, error) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(1 << 2)
file, handler, err := r.FormFile(formFileName)
if err != nil {
// If there is an error that means form is empty. Return nil for err in order
// to validate result as required.
return "", "", "", nil
}
defer file.Close()
fmt.Printf("Uploaded File: %+v\n", handler.Filename)
fmt.Printf("File Size: %+v\n", handler.Size)
fmt.Printf("MIME Header: %+v\n", handler.Header)
tempFile, err := ioutil.TempFile(TmpDirectory, "upload-*.png")
if err != nil {
log.Println(err)
return "", "", "", err
}
defer tempFile.Close()
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
log.Println(err)
return "", "", "", err
}
tempFile.Write(fileBytes)
fmt.Fprintf(w, "Successfully Uploaded File\n")
// create a new buffer base on file size
fInfo, _ := tempFile.Stat()
var size int64 = fInfo.Size()
buf := make([]byte, size)
// read file content into buffer
fReader := bufio.NewReader(tempFile)
fReader.Read(buf)
contentType := http.DetectContentType(fileBytes)
switch contentType {
case "image/png":
fmt.Println("Image type is already PNG.")
case "image/jpeg":
fmt.Println("Image type is JPG, converting it to PNG.")
img, err := jpeg.Decode(bytes.NewReader(fileBytes))
if err != nil {
return "", "", "", errors.Wrap(err, "unable to decode jpeg")
}
buf := new(bytes.Buffer)
if err := png.Encode(buf, img); err != nil {
return "", "", "", errors.Wrap(err, "unable to encode png")
}
}
//convert the buffer bytes to base64 string - use buf.Bytes() for new image
imgBase64Str := base64.StdEncoding.EncodeToString(buf)
filePath := filepath.Join(TmpDirectory, tempFile.Name())
return handler.Filename, filePath, imgBase64Str, nil}
- 返回的
ImageBase64Str
被写入数据库,尽管我认为 PostgreSQL 数据库在输入时可以接受一个限制。我的ImageBase64Str
长 71000 个字符! 为什么?它看起来像这样:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
我假设这不是预期的输出。
有人可以帮忙吗?
语句buf := make([]byte, size)
分配了一片零字节。语句 imgBase64Str := base64.StdEncoding.EncodeToString(buf)
将那些零字节编码为 base64,给出 result you observe.
数据的 base64 编码比原始数据大 4 / 3 倍。大图像将产生大编码。
函数不需要临时文件。使用从表单文件中提取的字节。
这是代码的简化和修复版本:
func HandleUpload(w http.ResponseWriter, r *http.Request, formFileName string) (string, string, error) {
// Maximum upload of 10 MB files r.ParseMultipartForm(1 << 2)
file, hdr, err := r.FormFile(formFileName)
if err != nil {
// If there is an error that means form is empty. Return nil for err in order
// to validate result as required.
return "", "", nil
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
log.Println(err)
return "", "", err
}
contentType := http.DetectContentType(data)
switch contentType {
case "image/png":
fmt.Println("Image type is already PNG.")
case "image/jpeg":
img, err := jpeg.Decode(bytes.NewReader(data))
if err != nil {
return "", "", fmt.Errorf("unable to decode jpeg: %w", err)
}
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
return "", "", fmt.Errorf("unable to encode png: %w", err)
}
data = buf.Bytes()
default:
return "", "", fmt.Errorf("unsupported content typo: %s", contentType)
}
imgBase64Str := base64.StdEncoding.EncodeToString(data)
return hdr.Filename, imgBase64Str, nil
}