Go 发送前调整图像大小

Go 发送前调整图像大小,go,go-gin,Go,Go Gin,我想有一个gin路由,将发送一个图像(jpeg)作为响应,但不是发送保存到磁盘的原始图像,我想先调整它的大小(缩略图大小) 到目前为止,我可以使用c.File(filepath字符串)发送图像,但这不允许我调整图像大小。有没有办法不用在磁盘上创建一个新文件就可以做到这一点?是的,你可以使用内置的软件包调整它的大小,我只是为你创建了它,使用不同的调整大小选项和字节/纯图像输出,选择你想要的。我过去没有使用过这个特殊的包,所以欢迎对这段代码进行任何修改/推荐。代码: package main im

我想有一个gin路由,将发送一个图像(jpeg)作为响应,但不是发送保存到磁盘的原始图像,我想先调整它的大小(缩略图大小)


到目前为止,我可以使用
c.File(filepath字符串)
发送图像,但这不允许我调整图像大小。有没有办法不用在磁盘上创建一个新文件就可以做到这一点?

是的,你可以使用内置的软件包调整它的大小,我只是为你创建了它,使用不同的调整大小选项和字节/纯图像输出,选择你想要的。我过去没有使用过这个特殊的包,所以欢迎对这段代码进行任何修改/推荐。代码:

package main

import (
    "bytes"
    "image"
    "image/color"
    "image/draw"
    "image/jpeg"
    "io/ioutil"
    "log"
    "math"
    "os"
)

func main() {
    f, err := os.Open("resources/image.jpg")
    if err != nil {
        log.Fatal(err)
    }

    //encoding message is discarded, because OP wanted only jpg, else use encoding in resize function
    img, _, err := image.Decode(f)
    if err != nil {
        log.Fatal(err)
    }

    //this is the resized image
    resImg := resize(img, 20, 20)

    //this is the resized image []bytes
    imgBytes := imgToBytes(resImg)

    //optional written to file
    err = ioutil.WriteFile("resources/test.jpg", imgBytes, 0777)
    if err != nil {
        log.Fatal(err)
    }
}

func resize(img image.Image, length int, width int) image.Image {
    //truncate pixel size
    minX := img.Bounds().Min.X
    minY := img.Bounds().Min.Y
    maxX := img.Bounds().Max.X
    maxY := img.Bounds().Max.Y
    for (maxX-minX)%length != 0 {
        maxX--
    }
    for (maxY-minY)%width!= 0 {
        maxY--
    }
    scaleX := (maxX - minX) / length
    scaleY := (maxY - minY) / width

    imgRect := image.Rect(0, 0, length, width)
    resImg := image.NewRGBA(imgRect)
    draw.Draw(resImg, resImg.Bounds(), &image.Uniform{C: color.White}, image.ZP, draw.Src)
    for y := 0; y < width; y += 1 {
        for x := 0; x < length; x += 1 {
            averageColor := getAverageColor(img, minX+x*scaleX, minX+(x+1)*scaleX, minY+y*scaleY, minY+(y+1)*scaleY)
            resImg.Set(x, y, averageColor)
        }
    }
    return resImg
}

func getAverageColor(img image.Image, minX int, maxX int, minY int, maxY int) color.Color {
    var averageRed float64
    var averageGreen float64
    var averageBlue float64
    var averageAlpha float64
    scale := 1.0 / float64((maxX-minX)*(maxY-minY))

    for i := minX; i < maxX; i++ {
        for k := minY; k < maxY; k++ {
            r, g, b, a := img.At(i, k).RGBA()
            averageRed += float64(r) * scale
            averageGreen += float64(g) * scale
            averageBlue += float64(b) * scale
            averageAlpha += float64(a) * scale
        }
    }

    averageRed = math.Sqrt(averageRed)
    averageGreen = math.Sqrt(averageGreen)
    averageBlue = math.Sqrt(averageBlue)
    averageAlpha = math.Sqrt(averageAlpha)

    averageColor := color.RGBA{
        R: uint8(averageRed),
        G: uint8(averageGreen),
        B: uint8(averageBlue),
        A: uint8(averageAlpha)}

    return averageColor
}

func imgToBytes(img image.Image) []byte {
    var opt jpeg.Options
    opt.Quality = 80

    buff := bytes.NewBuffer(nil)
    err := jpeg.Encode(buff, img, &opt)
    if err != nil {
        log.Fatal(err)
    }

    return buff.Bytes()
}


主程序包
进口(
“字节”
“图像”
“图像/颜色”
“图像/绘图”
“图像/jpeg”
“io/ioutil”
“日志”
“数学”
“操作系统”
)
func main(){
f、 err:=os.Open(“resources/image.jpg”)
如果错误!=零{
log.Fatal(错误)
}
//编码消息被丢弃,因为OP只需要jpg,否则在resize函数中使用编码
img,u,err:=image.Decode(f)
如果错误!=零{
log.Fatal(错误)
}
//这是已调整大小的图像
resImg:=调整大小(img,20,20)
//这是调整大小的图像[]字节
imgBytes:=imgToBytes(重定)
//可选写入文件
err=ioutil.WriteFile(“resources/test.jpg”,imgBytes,0777)
如果错误!=零{
log.Fatal(错误)
}
}
func resize(img image.image,length int,width int)image.image{
//截断像素大小
minX:=img.Bounds().Min.X
minY:=img.Bounds().Min.Y
maxX:=img.Bounds().Max.X
maxY:=img.Bounds().Max.Y
对于(最大最小)%length!=0{
马克斯--
}
对于(最大最小)%width!=0{
马克西--
}
scaleX:=(最大-最小)/长度
scaleY:=(最大-最小)/宽度
imgRect:=image.Rect(0,0,长度,宽度)
resImg:=image.NewRGBA(imgRect)
draw.draw(resImg,resImg.Bounds(),&image.Uniform{C:color.White},image.ZP,draw.Src)
对于y:=0;y
这意味着我必须先将调整大小的文件保存到磁盘上(在extend中,在发送响应后请注意删除它)。当然,这没什么大不了的,我可以这么做,谢谢你的代码,我可能最终会这样做。不,我的例子提供的正好相反,它生成一个[]字节,你可以在你的回答中使用。哦,你是对的,我的错。我没有想到这一点。这正是我想要的答案,谢谢。我得到一个警告,ZP贬值了。你试过什么?包括你的代码。你遇到了什么问题?