为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 如何将图像相互连接/附加

Golang 如何将图像相互连接/附加

Go
千万里不及你 2021-12-20 17:06:33
Go 有很棒的图像处理和数据库,但是我无法从较小的图像创建一个大图像。有谁知道如何在 Golang 中获取两个 png 或 jpeg 文件并将它们连接起来形成一个包含两个(或更多)文件的大图像?我目前正在阅读这样的 png 文件:imgFile, err := os.Open(path)if err != nil {    return Image{}, err}img, _, err := image.Decode(imgFile)if err != nil {    return Image{}, err}rgba := image.NewRGBA(img.Bounds())if rgba.Stride != rgba.Rect.Size().X*4 {    return Image{}, fmt.Errorf("unsupported stride")}draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)我对如何获取此 png RGBA 数据并与其他 RGBA 数据连接和/或将其组合成“空”图像感到困惑。
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

创建一个新的空图像 (NewRGBA),其边界足够大以容纳两个图像。然后使用该Draw方法在这个新的大图像的适当部分绘制每个图像。


以下是代码步骤。


加载两个图像。


imgFile1, err := os.Open("test1.jpg")

if err != nil {

    fmt.Println(err)

}

imgFile2, err := os.Open("test2.jpg")

if err != nil {

    fmt.Println(err)

}

img1, _, err := image.Decode(imgFile1)

if err != nil {

    fmt.Println(err)

}

img2, _, err := image.Decode(imgFile2)

if err != nil {

    fmt.Println(err)

}

让我们在第一个图像的右侧绘制第二个图像。所以它的起点应该是第一个图像的宽度在(w, 0)哪里w。第一个图像的右下角将是第二个图像的左下角。


//starting position of the second image (bottom left)

sp2 := image.Point{img1.Bounds().Dx(), 0}

它应该在一个足以容纳它的矩形中。


//new rectangle for the second image

r2 := image.Rectangle{sp2, sp2.Add(img2.Bounds().Size())}

现在创建一个大矩形,其宽度足以容纳两个图像。


//rectangle for the big image

r := image.Rectangle{image.Point{0, 0}, r2.Max}

注意此大图像将具有第二个图像的高度。如果第一张图像更高,它将被裁剪。


创建一个新图像。


rgba := image.NewRGBA(r)

现在您可以将这两个图像绘制到这个新图像中


draw.Draw(rgba, img1.Bounds(), img1, image.Point{0, 0}, draw.Src)

draw.Draw(rgba, r2, img2, image.Point{0, 0}, draw.Src)

由于我们在r2第一张图片的右侧创建了它,因此第二张图片将被绘制到右侧。


最后就可以导出了。


out, err := os.Create("./output.jpg")

if err != nil {

    fmt.Println(err)

}


var opt jpeg.Options

opt.Quality = 80


jpeg.Encode(out, rgba, &opt)


查看完整回答
反对 回复 2021-12-20
?
jeck猫

TA贡献1909条经验 获得超7个赞

如果你把一些东西变成函数并创建一个结构来理解每个像素,你的生活会容易得多。


// Create a struct to deal with pixel

type Pixel struct {

    Point image.Point

    Color color.Color

}


// Keep it DRY so don't have to repeat opening file and decode

func OpenAndDecode(filepath string) (image.Image, string, error) {

    imgFile, err := os.Open(filepath)

    if err != nil {

        panic(err)

    }

    defer imgFile.Close()

    img, format, err := image.Decode(imgFile)

    if err != nil {

        panic(err)

    }

    return img, format, nil

}


// Decode image.Image's pixel data into []*Pixel

func DecodePixelsFromImage(img image.Image, offsetX, offsetY int) []*Pixel {

    pixels := []*Pixel{}

    for y := 0; y <= img.Bounds().Max.Y; y++ {

        for x := 0; x <= img.Bounds().Max.X; x++ {

            p := &Pixel{

                Point: image.Point{x + offsetX, y + offsetY},

                Color: img.At(x, y),

            }

            pixels = append(pixels, p)

        }

    }

    return pixels

}


查看完整回答
反对 回复 2021-12-20
?
慕森卡

TA贡献1806条经验 获得超8个赞

我正是为此目的建立了一个图书馆。


您可以按如下方式使用它;


import gim "github.com/ozankasikci/go-image-merge"


grids := []*gim.Grid{

    {ImageFilePath: "test1.jpg"},

    {ImageFilePath: "test2.png"},

}


// merge the images into a 2x1 grid

rgba, err := gim.New(grids, 2, 1).Merge()


// save the output to jpg or png

file, err := os.Create("file/path.jpg|png")

err = jpeg.Encode(file, rgba, &jpeg.Options{Quality: 80})

https://github.com/ozankasikci/go-image-merge


查看完整回答
反对 回复 2021-12-20
  • 3 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号