Golang实现PNG图片上传至IPFS的方法

Golang实现PNG图片上传至IPFS的方法 大家好,我正在尝试将PNG图片上传到IPFS,我的机器上运行着一个守护进程。下面的代码会返回一个CID/哈希值,但当我尝试通过 https://ipfs.io/Ipfs/CID 查看时,图片并没有显示。与JS代码对比,我猜测问题可能在于我没有传递任何元数据。

我打开图片,解码它,转换为字节,然后使用导入的 shell "github.com/ipfs/go-ipfs-api" 将其上传到IPFS。有人能帮助我吗?

代码:

func ReadImageBytes(path_image string) []byte {
	inputFile, _ := os.Open(path_image)

	inputFile.Close()

	File, err := os.Open(path_image)
	if err != nil {
		log.Fatal(err)
	}
	defer File.Close()

	img, err := png.Decode(File)
	if err != nil {
		log.Fatal(err)
	}

	sz := img.Bounds()
	raw := make([]uint8, (sz.Max.X-sz.Min.X)*(sz.Max.Y-sz.Min.Y)*4)
	idx := 0
	for y := sz.Min.Y; y < sz.Max.Y; y++ {
		for x := sz.Min.X; x < sz.Max.X; x++ {
			r, g, b, a := img.At(x, y).RGBA()
			raw[idx], raw[idx+1], raw[idx+2], raw[idx+3] = uint8(r), uint8(g), uint8(b), uint8(a)
			idx += 4
		}
	}
	return raw
}`

func UploadIPFS(data []byte) (string, error) {

    sh := shell.NewShell("localhost:5001")

    reader := bytes.NewReader(data)

    fileHash, err := sh.Add(reader)

    if err != nil {

        return "", err

    }

    return fileHash, nil

}

更多关于Golang实现PNG图片上传至IPFS的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现PNG图片上传至IPFS的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的代码问题在于将PNG图片解码后重新编码为原始像素数据,这破坏了PNG的文件格式。IPFS需要完整的PNG文件字节,而不是解码后的像素数据。以下是修正后的代码:

import (
    "bytes"
    "io"
    "os"
    
    shell "github.com/ipfs/go-ipfs-api"
)

// 直接读取PNG文件原始字节
func ReadImageBytes(path_image string) ([]byte, error) {
    file, err := os.Open(path_image)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    
    // 读取整个文件
    return io.ReadAll(file)
}

// 上传到IPFS
func UploadIPFS(data []byte) (string, error) {
    sh := shell.NewShell("localhost:5001")
    reader := bytes.NewReader(data)
    
    // 使用Add方法上传原始PNG数据
    cid, err := sh.Add(reader)
    if err != nil {
        return "", err
    }
    
    return cid, nil
}

// 使用示例
func main() {
    // 读取PNG文件
    data, err := ReadImageBytes("image.png")
    if err != nil {
        panic(err)
    }
    
    // 上传到IPFS
    cid, err := UploadIPFS(data)
    if err != nil {
        panic(err)
    }
    
    println("Uploaded CID:", cid)
}

如果你需要处理图片但保持PNG格式,可以使用image/png包重新编码:

import (
    "bytes"
    "image/png"
    "os"
)

func ReadAndEncodePNG(path_image string) ([]byte, error) {
    file, err := os.Open(path_image)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    
    // 解码PNG
    img, err := png.Decode(file)
    if err != nil {
        return nil, err
    }
    
    // 重新编码为PNG
    var buf bytes.Buffer
    if err := png.Encode(&buf, img); err != nil {
        return nil, err
    }
    
    return buf.Bytes(), nil
}

关键点是:IPFS的Add方法需要完整的文件字节流,对于PNG图片,应该直接上传文件的原始字节或正确编码后的PNG数据,而不是解码后的像素数组。

回到顶部