Reputation: 3853
I am using the Go resize package here: https://github.com/nfnt/resize
I am pulling an Image from S3, as such:
image_data, err := mybucket.Get(key)
// this gives me data []byte
After that, I need to resize the image:
new_image := resize.Resize(160, 0, original_image, resize.Lanczos3)
// problem is that the original_image has to be of type image.Image
Upload the image to my S3 bucket
err : = mybucket.Put('newpath', new_image, 'image/jpg', 'aclstring')
// problem is that new image needs to be data []byte
How do I transform a data []byte
to ---> image.Image
and back to ----> data []byte
?
Upvotes: 43
Views: 76415
Reputation: 96
No third party package. The following code can reduce the image size to minimum 50px height.
func resizeImage(img image.RGBA, height int) image.RGBA {
if height < 50 {
return img
}
bounds := img.Bounds()
imgHeight := bounds.Dy()
if height >= imgHeight {
return img
}
imgWidth := bounds.Dx()
resizeFactor := float32(imgHeight) / float32(height)
ratio := float32(imgWidth) / float32(imgHeight)
width := int(float32(height) * ratio)
resizedImage := image.NewRGBA(image.Rect(0, 0, width, height))
var imgX, imgY int
var imgColor color.Color
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
imgX = int(resizeFactor*float32(x) + 0.5)
imgY = int(resizeFactor*float32(y) + 0.5)
imgColor = img.At(imgX, imgY)
resizedImage.Set(x, y, imgColor)
}
}
return *resizedImage
}
Upvotes: 0
Reputation: 1091
The OP is using a specific library/package, but I think that the issue of "Go Resizing Images" can be solved without that package.
You can resize de image using 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)
In that case I choose draw.NearestNeighbor
, because it's faster, but looks worse. but there's other methods, you can see on https://pkg.go.dev/golang.org/x/image/draw#pkg-variables:
draw.NearestNeighbor
NearestNeighbor is the nearest neighbor interpolator. It is very fast, but usually gives very low quality results. When scaling up, the result will look 'blocky'.
draw.ApproxBiLinear
ApproxBiLinear is a mixture of the nearest neighbor and bi-linear interpolators. It is fast, but usually gives medium quality results.
draw.BiLinear
BiLinear is the tent kernel. It is slow, but usually gives high quality results.
draw.CatmullRom
CatmullRom is the Catmull-Rom kernel. It is very slow, but usually gives very high quality results.
Upvotes: 59
Reputation: 109367
Read http://golang.org/pkg/image
// you need the image package, and a format package for encoding/decoding
import (
"bytes"
"image"
"image/jpeg" // if you don't need to use jpeg.Encode, use this line instead
// _ "image/jpeg"
"github.com/nfnt/resize"
)
// 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
Upvotes: 66
Reputation: 135
You could use bimg, which is powered by libvips (a fast image processing library written in C).
If you are looking for a image resizing solution as a service, take a look to imaginary
Upvotes: 5
Reputation: 3022
Want to do it 29 times faster? Try amazing vipsthumbnail
instead:
sudo apt-get install libvips-tools
vipsthumbnail --help-all
This will resize and nicely crop saving result to a file:
vipsthumbnail original.jpg -s 700x200 -o 700x200.jpg -c
Calling from 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()
}
Upvotes: 10