调整图像大小

Jor*_*ero 19 image-processing go

我在这里使用Go resize包:https://github.com/nfnt/resize

1)我从S3中提取图像,如下:

image_data, err := mybucket.Get(key)
// this gives me data []byte
Run Code Online (Sandbox Code Playgroud)

2)之后,我需要调整图像大小:

new_image := resize.Resize(160, 0, original_image, resize.Lanczos3)
// problem is that the original_image has to be of type image.Image
Run Code Online (Sandbox Code Playgroud)

3)将图像上传到我的S3存储桶

err : = mybucket.Put('newpath', new_image, 'image/jpg', 'aclstring')
// problem is that new image needs to be data []byte
Run Code Online (Sandbox Code Playgroud)

如何将data []字节转换为---> image.Image并返回----> data [] byte ??

在此先感谢您的帮助!

Jim*_*imB 44

阅读http://golang.org/pkg/image

// you need the image package, and a format package for encoding/decoding
import (
    "bytes"
    "image"
    "image/jpeg"

    "github.com/nfnt/resize"

    // if you don't need to use jpeg.Encode, import like so:
    // _ "image/jpeg"
)

// Decoding gives you an Image.
// If you have an io.Reader already, you can give that to Decode 
// without reading it into a []byte.
image, _, err := image.Decode(bytes.NewReader(data))
// check err

newImage := resize.Resize(160, 0, original_image, resize.Lanczos3)

// Encode uses a Writer, use a Buffer if you need the raw []byte
err = jpeg.Encode(someWriter, newImage, nil)
// check err
Run Code Online (Sandbox Code Playgroud)

  • 你从哪里导入这个`resize`包? (8认同)
  • 我看到很多人专门推荐这个库,但是我刚刚查了一下,已经不再支持了。您可能想寻找其他选项,例如@Inkeliz 答案。 (7认同)
  • 下划线是你如何导入东西只是为了它的副作用(在这种情况下注册解码器).不使用下划线导入使用`jpeg.Encode`.`bytes`是标准库中的包. (3认同)

Max*_*kiy 11

想要快29倍吗?尝试惊人的vipsthumbnail:

sudo apt-get install libvips-tools
vipsthumbnail --help-all
Run Code Online (Sandbox Code Playgroud)

这将调整大小,并将保存结果很好地保存到文件中:

vipsthumbnail original.jpg -s 700x200 -o 700x200.jpg -c
Run Code Online (Sandbox Code Playgroud)

来自Go的电话:

func resizeExternally(from string, to string, width uint, height uint) error {
    var args = []string{
        "--size", strconv.FormatUint(uint64(width), 10) + "x" +
            strconv.FormatUint(uint64(height), 10),
        "--output", to,
        "--crop",
        from,
    }
    path, err := exec.LookPath("vipsthumbnail")
    if err != nil {
        return err
    }
    cmd := exec.Command(path, args...)
    return cmd.Run()
}
Run Code Online (Sandbox Code Playgroud)

  • 在不希望系统调用的情况下,也存在[绑定](https://github.com/DAddYE/vips). (6认同)
  • 观察到您通过这种方法使用可移植性是很有用的。使用纯 Go 可以为 Go 支持的每个操作系统/架构提供可移植性。 (3认同)
  • 这个答案与原来的问题有什么关系? (3认同)
  • @gbenroscience 哎呀我有一个拼写错误,我的意思是说“失去可移植性”。我的意思是,由于它调用外部程序,因此您的 Go 程序不是自包含的,也不是纯粹的 Go 可以为您提供的可移植性。已接受答案中的代码在这方面更好。 (2认同)

Ink*_*liz 5

OP 正在使用特定的库/包,但我认为“Go Resizing Images”的问题可以在没有该包的情况下解决。

您可以使用golang.org/x/image/draw以下方法调整图像大小:

input, _ := os.Open("your_image.png")
defer input.Close()

output, _ := os.Create("your_image_resized.png")
defer output.Close()

// Decode the image (from PNG to image.Image):
src, _ := png.Decode(input)

// Set the expected size that you want:
dst := image.NewRGBA(image.Rect(0, 0, src.Bounds().Max.X/2, src.Bounds().Max.Y/2))

// Resize:
draw.NearestNeighbor.Scale(dst, dst.Rect, src, src.Bounds(), draw.Over, nil)

// Encode to `output`:      
png.Encode(output, dst)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我选择draw.NearestNeighbor,因为它更快,但看起来更糟。但还有其他方法,您可以在https://pkg.go.dev/golang.org/x/image/draw#pkg-variables 上看到:

  • draw.NearestNeighbor
    NearestNeighbor 是最近邻插值器。它非常快,但通常会给出非常低质量的结果。放大时,结果将看起来“块状”。

  • draw.ApproxBiLinear
    ApproxBiLinear 是最近邻和双线性插值器的混合。它很快,但通常会给出中等质量的结果。

  • draw.BiLinear
    BiLinear 是帐篷内核。它很慢,但通常会给出高质量的结果。

  • draw.CatmullRom
    CatmullRom 是 Catmull-Rom 内核。它非常慢,但通常会提供非常高质量的结果。