使用Go进行裁剪和创建缩略图

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

Cropping and creating thumbnails with Go

问题

有没有办法通过给定尺寸和偏移量来使用Go裁剪图像?

我想要的是像这个PHP函数一样灵活的功能:
http://php.net/manual/en/function.imagecopyresampled.php

我找到了这个库:https://github.com/nfnt/resize
但是这个库似乎没有偏移选项。

我需要能够裁剪原始图像的任何区域。不仅仅是缩小,还要能够对裁剪后的图像进行不同的定位。

有没有关于如何实现这个功能的建议?

英文:

Is there a way for me to crop an image with Go by giving dimensions and offsets?

I'm thinking of something flexible like this php function:
http://php.net/manual/en/function.imagecopyresampled.php

I found this: https://github.com/nfnt/resize
But that library does not seem to have an offset option.

I need to be able to crop any area of the original image. Not just scaling down, but also a different positioning of the cropped image.

Any suggestions on how I can achieve this?

答案1

得分: 11

我将回答自己的问题,以便对其他Go的新手有所帮助。

阅读这两篇文章对我在Go中如何裁剪图像有很大帮助。无需使用第三方库。你可以通过点和矩形来决定如何裁剪图像,这是一种非常简洁的方法。

http://blog.golang.org/go-image-package

http://blog.golang.org/go-imagedraw-package

英文:

I'll answer my own question so that it can be of help to other newcomers of Go.

Reading these two articles helped me greatly to understand how to crop images in Go. No need for third libraries. You decide how to crop an image with points and rectangles which is a very neat way of doing it.

http://blog.golang.org/go-image-package

http://blog.golang.org/go-imagedraw-package

答案2

得分: 7

这是一个简单的程序,用于裁剪图像。它会将给定矩形外的图像部分裁剪掉。

package main

import (
	"fmt"
	"image"
	"log"
	"os"

	"image/png"
)

func main() {
	if err := run(); err != nil {
		log.Fatalln(err)
	}
}

func run() error {
	img, err := readImage("pic.png")
	if err != nil {
		return err
	}

	// 我已经硬编码了一个裁剪矩形,起点 (0,0),终点 (100, 100)。
	img, err = cropImage(img, image.Rect(0, 0, 100, 100))
	if err != nil {
		return err
	}

	return writeImage(img, "pic-cropped.png")
}

// readImage 从磁盘读取图像文件。我们假设文件是 png 格式。
func readImage(name string) (image.Image, error) {
	fd, err := os.Open("pic.png")
	if err != nil {
		return nil, err
	}
	defer fd.Close()

	// image.Decode 需要你导入正确的图像包。我们已经导入了 "image/png",所以 Decode 可以用于 png 文件。如果我们需要解码 jpeg 文件,那么我们需要导入 "image/jpeg"。
	//
	// 忽略的返回值是图像格式名称。
	img, _, err := image.Decode(fd)
	if err != nil {
		return nil, err
	}

	return img, nil
}

// cropImage 接受一个图像并将其裁剪为指定的矩形。
func cropImage(img image.Image, crop image.Rectangle) (image.Image, error) {
	type subImager interface {
		SubImage(r image.Rectangle) image.Image
	}

	// img 是一个 Image 接口。这个检查是否底层值有一个名为 SubImage 的方法。如果有,那么我们可以使用 SubImage 来裁剪图像。
	simg, ok := img.(subImager)
	if !ok {
		return nil, fmt.Errorf("图像不支持裁剪")
	}

	return simg.SubImage(crop), nil
}

// writeImage 将图像写回磁盘。
func writeImage(img image.Image, name string) error {
	fd, err := os.Create(name)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}
英文:

Here's a simple program that crops an image. If chops off the image outside of a given rectangle.

package main

import (
	"fmt"
	"image"
	"log"
	"os"

	"image/png"
)

func main() {
	if err := run(); err != nil {
		log.Fatalln(err)
	}
}

func run() error {
	img, err := readImage("pic.png")
	if err != nil {
		return err
	}

	// I've hard-coded a crop rectangle, start (0,0), end (100, 100).
	img, err = cropImage(img, image.Rect(0, 0, 100, 100))
	if err != nil {
		return err
	}

	return writeImage(img, "pic-cropped.png")
}

// readImage reads a image file from disk. We're assuming the file will be png
// format.
func readImage(name string) (image.Image, error) {
	fd, err := os.Open("pic.png")
	if err != nil {
		return nil, err
	}
	defer fd.Close()

	// image.Decode requires that you import the right image package. We've
	// imported "image/png", so Decode will work for png files. If we needed to
	// decode jpeg files then we would need to import "image/jpeg".
	//
	// Ignored return value is image format name.
	img, _, err := image.Decode(fd)
	if err != nil {
		return nil, err
	}

	return img, nil
}

// cropImage takes an image and crops it to the specified rectangle.
func cropImage(img image.Image, crop image.Rectangle) (image.Image, error) {
	type subImager interface {
		SubImage(r image.Rectangle) image.Image
	}

	// img is an Image interface. This checks if the underlying value has a
	// method called SubImage. If it does, then we can use SubImage to crop the
	// image.
	simg, ok := img.(subImager)
	if !ok {
		return nil, fmt.Errorf("image does not support cropping")
	}

	return simg.SubImage(crop), nil
}

// writeImage writes an Image back to the disk.
func writeImage(img image.Image, name string) error {
	fd, err := os.Create(name)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}

答案3

得分: 2

这是一个关于图像处理的代码示例,你可以在这个答案中找到更详细的解释。SubImage方法适用于大多数图像格式(除了Uniform)。由于它不属于主要接口,你需要进行断言才能使用它。

package main

import (
    "fmt"
    "image"
    "image/jpeg"
    "log"
    "os"
)

func main() {
    image_file, err := os.Open("somefile.jpeg")
    if err != nil {
        log.Fatal(err)
    }
    my_image, err := jpeg.Decode(image_file)
    if err != nil {
        log.Fatal(err)
    }

    my_sub_image := my_image.(interface {
        SubImage(r image.Rectangle) image.Image
    }).SubImage(image.Rect(0, 0, 10, 10))

    output_file, outputErr := os.Create("output.jpeg")
    if outputErr != nil {
        log.Fatal(outputErr)
    }
    jpeg.Encode(output_file, my_sub_image, nil)

}

希望对你有帮助!

英文:

It is explained better in this answer. The SubImage method is implemented for most of the image formats (seems to be all but Uniform). Since it does not belong to the main interface you need to assert it in order to use it.

package main
import (
"fmt"
"image"
"image/jpeg"
"log"
"os"
)
func main() {
image_file, err := os.Open("somefile.jpeg")
if err != nil {
log.Fatal(err)
}
my_image, err := jpeg.Decode(image_file)
if err != nil {
log.Fatal(err)
}
my_sub_image := my_image.(interface {
SubImage(r image.Rectangle) image.Image
}).SubImage(image.Rect(0, 0, 10, 10))
output_file, outputErr := os.Create("output.jpeg")
if outputErr != nil {
log.Fatal(outputErr)
}
jpeg.Encode(output_file, my_sub_image, nil)
}

答案4

得分: 1

https://github.com/gographics/imagick 似乎有你需要的内容:https://godoc.org/github.com/gographics/imagick/imagick#MagickWand.CropImage

英文:

https://github.com/gographics/imagick seems to have what you need : https://godoc.org/github.com/gographics/imagick/imagick#MagickWand.CropImage

huangapple
  • 本文由 发表于 2015年9月13日 07:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/32544927.html
匿名

发表评论

匿名网友

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

确定