How to implement Custom cropping using golang

huangapple go评论71阅读模式
英文:

How to implement Custom cropping using golang

问题

我正在寻找一种在一组图像上进行自定义裁剪的方法。与通常的按照高度和宽度进行裁剪不同,我希望能够获得一个像多边形或六边形一样裁剪的输出图像。我正在使用库github.com/fogleman/gg和内置模块"image"以及github.com/disintegration/imaging,但我没有找到自定义裁剪的方法。我还尝试了一些在线的SaaS服务,如imgix或imageresizer.io,但它们似乎没有提供这样的功能。我知道使用Go语言可能是正确的选择,也许我没有找得够仔细,请帮忙看看。

我的示例代码如下:

var image image.Image
dc := NewContext(1000, 1000)
image = imaging.Fill(profile, 800, 750, imaging.Center, imaging.Lanczos)
// 裁剪需要在这里进行
dc.DrawImage(image, 123, 250)
英文:

Am looking to do custom cropping on a set of images, Instead of cropping normally, using height and width i want the flexibility of getting an output image that is cropped like a polygon or an hexagon for example, Am using the library github.com/fogleman/gg, and the built in module "image", and github.com/disintegration/imaging, but I didn't find a way to customize the cropping, i also looked for an online SaaS to do this, like imgix or imageresizer.io, but they don't seem to offer that, i know golang is the right language for this maybe i didn't look hard enough, please Help

my sample Code looks like:

var image image.Image
dc := NewContext(1000, 1000)
image = imaging.Fill(profile, 800, 750, imaging.Center, imaging.Lanczos)
// Cropping needs to happen here
dc.DrawImage(image, 123, 250)

答案1

得分: 2

稍微比预期的长一点,但是这是一个将带有透明背景的 PNG 图像裁剪为矩形的代码。你可以通过修改 getPixAlpha 函数来实现不同形状的裁剪。

只需添加包名,它应该包含导入部分,然后添加一个名为 test.png 的图像,它将创建一个名为 test-output.png 的图像。

注意:如果要将其用作服务,你可能需要进行一些微小的修改。

type Pixel struct {
    R int
    G int
    B int
    A int
}

func LogPanic(err error, msg string) {
    if err != nil {
        log.Printf("ERROR: %v %s", err, msg)
        panic(err)
    }
}

func getPixAlpha(x, y, halfWidth int) int {
    if x < halfWidth-y || x > halfWidth+y {
        return 0
    }
    if y > halfWidth+x {
        return 0
    }
    if x > halfWidth*3-y && y > halfWidth*3-x {
        return 0
    }
    return int(255)
}

func getPixels(file io.Reader) ([][]Pixel, error) {
    img, _, err := image.Decode(file)
    LogPanic(err, "error reading image")
    bounds := img.Bounds()
    width, height := bounds.Max.X, bounds.Max.Y
    var pixels [][]Pixel
    for x := 0; x < width; x++ {
        var row []Pixel
        for y := 0; y < height; y++ {
            row = append(row, rgbaToPixel(img.At(x, y).RGBA()))
        }
        pixels = append(pixels, row)
    }
    return pixels, nil
}

func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) Pixel {
    return Pixel{int(r / 257), int(g / 257), int(b / 257), int(a / 257)}
}

func getRgbaPic(pixels [][]Pixel) [][]Pixel {
    dx := len(pixels)
    dy := len(pixels[0])
    for x := 0; x < dx; x++ {
        for y := 0; y < dy; y++ {
            pixels[x][y].A = getPixAlpha(x, y, len(pixels)/2)
        }
    }
    return pixels
}

func main() {
    file, err := os.Open("./test.png")
    LogPanic(err, "Error opening file")
    defer file.Close()
    pixels, err := getPixels(file)
    LogPanic(err, "Error reading image")
    pixels = getRgbaPic(pixels)
    img := image.NewRGBA(image.Rect(0, 0, len(pixels), len(pixels[0])))
    for x := 0; x < len(pixels); x++ {
        for y := 0; y < len(pixels[0]); y++ {
            img.Set(x, y, color.RGBA{
                uint8(pixels[x][y].R),
                uint8(pixels[x][y].G),
                uint8(pixels[x][y].B),
                uint8(pixels[x][y].A),
            })
        }
    }
    buf := &bytes.Buffer{}
    err = png.Encode(buf, img)
    LogPanic(err, "Error encoding")
    err = ioutil.WriteFile("test-output.png", buf.Bytes(), 0666)
    LogPanic(err, "Error writing file")
}
英文:

A bit longer than expected but here you have PNG image cropping with transparent background to a rectangle. You can modify the code for different shapes by changing the getPixAlpha function.

Just add the package name and it should include the imports, then add an image test.png and it should create a test-output.png

Note: You may want to make some minor modifications for using it as a service.

type Pixel struct {
R int
G int
B int
A int
}
func LogPanic(err error, msg string) {
if err != nil {
log.Printf(&quot;ERROR: %v %s&quot;, err, msg)
panic(err)
}
}
func getPixAlpha(x, y, halfWidth int) int {
if x &lt; halfWidth-y || x &gt; halfWidth+y {
return 0
}
if y &gt; halfWidth+x {
return 0
}
if x &gt; halfWidth*3-y &amp;&amp; y &gt; halfWidth*3-x {
return 0
}
return int(255)
}
func getPixels(file io.Reader) ([][]Pixel, error) {
img, _, err := image.Decode(file)
LogPanic(err, &quot;error reading image&quot;)
bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
var pixels [][]Pixel
for x := 0; x &lt; width; x++ {
var row []Pixel
for y := 0; y &lt; height; y++ {
row = append(row, rgbaToPixel(img.At(x, y).RGBA()))
}
pixels = append(pixels, row)
}
return pixels, nil
}
func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) Pixel {
return Pixel{int(r / 257), int(g / 257), int(b / 257), int(a / 257)}
}
func getRgbaPic(pixels [][]Pixel) [][]Pixel {
dx := len(pixels)
dy := len(pixels[0])
for x := 0; x &lt; dx; x++ {
for y := 0; y &lt; dy; y++ {
pixels[x][y].A = getPixAlpha(x, y, len(pixels)/2)
}
}
return pixels
}
func main() {
file, err := os.Open(&quot;./test.png&quot;)
LogPanic(err, &quot;Error opening file&quot;)
defer file.Close()
pixels, err := getPixels(file)
LogPanic(err, &quot;Error reading image&quot;)
pixels = getRgbaPic(pixels)
img := image.NewRGBA(image.Rect(0, 0, len(pixels), len(pixels[0])))
for x := 0; x &lt; len(pixels); x++ {
for y := 0; y &lt; len(pixels[0]); y++ {
img.Set(x, y, color.RGBA{
uint8(pixels[x][y].R),
uint8(pixels[x][y].G),
uint8(pixels[x][y].B),
uint8(pixels[x][y].A),
})
}
}
buf := &amp;bytes.Buffer{}
err = png.Encode(buf, img)
LogPanic(err, &quot;Error encoding&quot;)
err = ioutil.WriteFile(&quot;test-output.png&quot;, buf.Bytes(), 0666)
LogPanic(err, &quot;Error writing file&quot;)
}

huangapple
  • 本文由 发表于 2021年12月13日 19:32:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/70333956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定