Image Go-将base64字符串保存到文件

Image Go-将base64字符串保存到文件,image,go,base64,Image,Go,Base64,所以。。我有一个base64编码的字符串,我需要解码,检查它的宽度和高度,然后保存到文件中。然而。。我一直在保存一个损坏的图像文件 package server import ( "encoding/base64" "errors" "io" "os" "strings" "image" _ "image/gif" _ "image/jpeg" _ "image/png" ) var ( ErrBucket

所以。。我有一个base64编码的字符串,我需要解码,检查它的宽度和高度,然后保存到文件中。然而。。我一直在保存一个损坏的图像文件

package server

import (
    "encoding/base64"
    "errors"
    "io"
    "os"
    "strings"

    "image"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"
)

var (
    ErrBucket       = errors.New("Invalid bucket!")
    ErrSize         = errors.New("Invalid size!")
    ErrInvalidImage = errors.New("Invalid image!")
)

func saveImageToDisk(fileNameBase, data, bucket string) (string, error) {
    idx := strings.Index(data, ";base64,")
    if idx < 0 {
        return "", ErrInvalidImage
    }

    reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data[idx+8:]))
    imgCfg, fmt, err := image.DecodeConfig(reader)
    if err != nil {
        return "", err
    }

    if imgCfg.Width != 750 || imgCfg.Height != 685 {
        return "", ErrSize
    }

    fileName := fileNameBase + "." + fmt
    f, err := os.Create(fileName)
    if err != nil {
        return "", err
    }

    _, err = io.Copy(f, reader)
    f.Close()

    return fileName, err
}
包服务器
进口(
“编码/base64”
“错误”
“io”
“操作系统”
“字符串”
“图像”
_“图像/gif”
_“图像/jpeg”
_“图像/png”
)
变量(
ErrBucket=errors.New(“无效的bucket!”)
ErrSize=错误。新建(“无效大小!”)
ErrInvalidImage=errors.New(“无效图像!”)
)
func saveImageToDisk(fileNameBase,数据,bucket字符串)(字符串,错误){
idx:=strings.Index(数据为“base64”)
如果idx<0{
返回“”,ErrInvalidImage
}
reader:=base64.NewDecoder(base64.StdEncoding,strings.NewReader(数据[idx+8:]))
imgCfg,fmt,err:=image.DecodeConfig(读取器)
如果错误!=零{
返回“”,错误
}
如果imgCfg.宽度!=750 | | imgCfg.高度!=685{
返回“”,错误大小
}
文件名:=fileNameBase+“+fmt
f、 错误:=os.Create(文件名)
如果错误!=零{
返回“”,错误
}
_,err=io.Copy(f,读卡器)
f、 关闭()
返回文件名,错误
}
它确实保存了一个文件。。根据在线base64到图像转换器,我正在测试的base64是有效的。有什么帮助吗


下面是我正在使用的base64字符串(func中的数据)

这些代码的主要问题是,当您读取io.Reader时,光标不会返回到第一个。您已经在解码图像配置上读取了io.Reader。所以,当您将其写入文件时,它将一直读取到EOF(可能不是您的数据)

我不知道如何将io.Reader重置为第一个,但我写了一个解决方法,使其工作:

import (
    "encoding/base64"
    "errors"
    "strings"

    "image"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"
    "io/ioutil"
    "bytes"
)

var (
    ErrBucket       = errors.New("Invalid bucket!")
    ErrSize         = errors.New("Invalid size!")
    ErrInvalidImage = errors.New("Invalid image!")
)

func saveImageToDisk(fileNameBase, data string) (string, error) {
    idx := strings.Index(data, ";base64,")
    if idx < 0 {
        return "", ErrInvalidImage
    }
    reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data[idx+8:]))
    buff := bytes.Buffer{}
    _, err := buff.ReadFrom(reader)
    if err != nil {
        return "", err
    }
    imgCfg, fm, err := image.DecodeConfig(bytes.NewReader(buff.Bytes()))
    if err != nil {
        return "", err
    }

    if imgCfg.Width != 750 || imgCfg.Height != 685 {
        return "", ErrSize
    }

    fileName := fileNameBase + "." + fm
    ioutil.WriteFile(fileName, buff.Bytes(), 0644)

    return fileName, err
}
导入(
“编码/base64”
“错误”
“字符串”
“图像”
_“图像/gif”
_“图像/jpeg”
_“图像/png”
“io/ioutil”
“字节”
)
变量(
ErrBucket=errors.New(“无效的bucket!”)
ErrSize=错误。新建(“无效大小!”)
ErrInvalidImage=errors.New(“无效图像!”)
)
func saveImageToDisk(fileNameBase,数据字符串)(字符串,错误){
idx:=strings.Index(数据为“base64”)
如果idx<0{
返回“”,ErrInvalidImage
}
reader:=base64.NewDecoder(base64.StdEncoding,strings.NewReader(数据[idx+8:]))
buff:=字节。缓冲区{}
_,err:=buff.ReadFrom(读取器)
如果错误!=零{
返回“”,错误
}
imgCfg,fm,err:=image.DecodeConfig(bytes.NewReader(buff.bytes()))
如果错误!=零{
返回“”,错误
}
如果imgCfg.宽度!=750 | | imgCfg.高度!=685{
返回“”,错误大小
}
文件名:=fileNameBase+“+fm”
ioutil.WriteFile(文件名,buff.Bytes(),0644)
返回文件名,错误
}

这些代码的主要问题是,当您读取io.Reader时,光标不会返回到第一个。您已经在解码图像配置上读取了io.Reader。所以,当您将其写入文件时,它将一直读取到EOF(可能不是您的数据)

我不知道如何将io.Reader重置为第一个,但我写了一个解决方法,使其工作:

import (
    "encoding/base64"
    "errors"
    "strings"

    "image"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"
    "io/ioutil"
    "bytes"
)

var (
    ErrBucket       = errors.New("Invalid bucket!")
    ErrSize         = errors.New("Invalid size!")
    ErrInvalidImage = errors.New("Invalid image!")
)

func saveImageToDisk(fileNameBase, data string) (string, error) {
    idx := strings.Index(data, ";base64,")
    if idx < 0 {
        return "", ErrInvalidImage
    }
    reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data[idx+8:]))
    buff := bytes.Buffer{}
    _, err := buff.ReadFrom(reader)
    if err != nil {
        return "", err
    }
    imgCfg, fm, err := image.DecodeConfig(bytes.NewReader(buff.Bytes()))
    if err != nil {
        return "", err
    }

    if imgCfg.Width != 750 || imgCfg.Height != 685 {
        return "", ErrSize
    }

    fileName := fileNameBase + "." + fm
    ioutil.WriteFile(fileName, buff.Bytes(), 0644)

    return fileName, err
}
导入(
“编码/base64”
“错误”
“字符串”
“图像”
_“图像/gif”
_“图像/jpeg”
_“图像/png”
“io/ioutil”
“字节”
)
变量(
ErrBucket=errors.New(“无效的bucket!”)
ErrSize=错误。新建(“无效大小!”)
ErrInvalidImage=errors.New(“无效图像!”)
)
func saveImageToDisk(fileNameBase,数据字符串)(字符串,错误){
idx:=strings.Index(数据为“base64”)
如果idx<0{
返回“”,ErrInvalidImage
}
reader:=base64.NewDecoder(base64.StdEncoding,strings.NewReader(数据[idx+8:]))
buff:=字节。缓冲区{}
_,err:=buff.ReadFrom(读取器)
如果错误!=零{
返回“”,错误
}
imgCfg,fm,err:=image.DecodeConfig(bytes.NewReader(buff.bytes()))
如果错误!=零{
返回“”,错误
}
如果imgCfg.宽度!=750 | | imgCfg.高度!=685{
返回“”,错误大小
}
文件名:=fileNameBase+“+fm”
ioutil.WriteFile(文件名,buff.Bytes(),0644)
返回文件名,错误
}

另一个答案对我不起作用,我希望能够将图像保存为文件,而不考虑图像格式:

package main

import (
    "bytes"
    "encoding/base64"
    "image/gif"
    "image/jpeg"
    "image/png"
    "log"
    "os"
    "strings"

    _ "github.com/jinzhu/gorm/dialects/postgres"
)

const data = `data:image/gif;base64,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`

func main() {
    idx := strings.Index(data, ";base64,")
    if idx < 0 {
        panic("InvalidImage")
    }
    ImageType := data[11:idx]
    log.Println(ImageType)

    unbased, err := base64.StdEncoding.DecodeString(data[idx+8:])
    if err != nil {
        panic("Cannot decode b64")
    }
    r := bytes.NewReader(unbased)
    switch ImageType {
    case "png":
        im, err := png.Decode(r)
        if err != nil {
            panic("Bad png")
        }

        f, err := os.OpenFile("example.png", os.O_WRONLY|os.O_CREATE, 0777)
        if err != nil {
            panic("Cannot open file")
        }

        png.Encode(f, im)
    case "jpeg":
        im, err := jpeg.Decode(r)
        if err != nil {
            panic("Bad jpeg")
        }

        f, err := os.OpenFile("example.jpeg", os.O_WRONLY|os.O_CREATE, 0777)
        if err != nil {
            panic("Cannot open file")
        }

        jpeg.Encode(f, im, nil)
    case "gif":
        im, err := gif.Decode(r)
        if err != nil {
            panic("Bad gif")
        }

        f, err := os.OpenFile("example.gif", os.O_WRONLY|os.O_CREATE, 0777)
        if err != nil {
            panic("Cannot open file")
        }

        gif.Encode(f, im, nil)
    }
}
主程序包
进口(
“字节”
“编码/base64”
“图像/gif”
“图像/jpeg”
“图像/png”
“日志”
“操作系统”
“字符串”
_“github.com/jinzhu/gorm/diagnols/postgres”
)
const data=`data:image/gif;base64,(7)Gvvvvv8+fhw/vv8+fhw/vv8/9/5+Pv9/6+Pd98F9/f+8+Pd98F8/8+6+6+6+6+8+6+fff9/8+f9 ww6/8+ff8/8+fn/fn/fn/9 wfn/9-www7/9 wwwwwwwwwwwwwwwwwww8/8/8/8/8/wwwwwwwwwwwwwwwwww8/8/8/8/wwwwwwwww8/8/8/8/8/8/wwwwwwwwwww8/8/www8/8/wwwwww8/8/8/ww8/8/wwwww8/8/8/8/8/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swM8月8日,8月8日,一份研究报告在一份研究报告上发表了一份研究报告。8月8日,在一份研究报告中,一份研究了一份关于一份工作的书。5月5日,一份工作+Pj/+PQCST(一份研究报告)在一份研究报告中提出了一份关于一份关于一份关于一份关于一份关于一份工作的文件,一份关于一份关于一份关于一份关于一份工作+Pj+Pj+Pj/+资格的文件,以及一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份关于一份工作的文件的文件的非政府工作的文文文文文文文文文文文文文文的研究,一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于YWZ78AAAAD///8AAP9mZv///wAAAAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAakgalaaaaAa9EqaaaAa9EqaAaAa9Avkslme6NFQ05QYCvLpuHdRxBwW4NehxOykupZJGrmixOkFGUNQlnixJeidb0SqHgMyJSOjM1BkZomYop0Gm2Oe2Lit2Moopy7Gnwy9CjIyCSRyM0AvksLm6NfQdJ0LxNqNqNqNqNqNbNqNqNbNqNbNqNbNbNqNbNbNbJ6Zr6Zr6ZrZr2ZrZrZrZrYxRyxRyxZyxZyxZyxDxWxWxWxWxWxWxVxVxVxVxVxVkKvKvKvKKvKKKUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnn