Golang将ImageMagick对象转换为[]byte。

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

Golang Converting Image magick object to []byte

问题

我正在使用以下代码从Amazon S3获取对象,并在执行调整大小和裁剪操作后,希望将其存储在S3上。但问题是我无法将mw(Image Magick对象)转换为字节数组,以便用于在S3上存储。此外,在当前方法中,它使用jpeg.Encode。如果图像是.png或.gif格式,我们如何将其转换为[]byte?

请问如何通过传递纵横比而不是裁剪坐标来均匀裁剪图像?就像在.NET中那样使用imgStream.Crop((int)originalWidth, ((int)(originalWidth / masterAspectRatio)), Gravity.Center)。我问这个问题的原因是库中没有提供这种灵活性的方法。

s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
params := &s3.GetObjectInput{
    Bucket: aws.String(bucketName),
    Key:    aws.String(keyName),
}

out, err := s3Client.GetObject(params)

if err != nil {
    log.Fatal(err)
}

img, err := ioutil.ReadAll(out.Body)
if err != nil {
    log.Fatal(err)
}

mw := imagick.NewMagickWand()

err = mw.ReadImageBlob(img)
if err != nil {
    log.Fatal(err)
}

// 在mw对象上执行调整大小和裁剪操作

buf := new(bytes.Buffer)
err = jpeg.Encode(buf, mw, nil)
sendmw_s3 := buf.Bytes()

paramsPut := &s3.PutObjectInput{
    Bucket: aws.String(masterBucketName),
    Key:    aws.String(keyName),
    Body:   bytes.NewReader(sendmw_s3),
}

resp, err := s3Client.PutObject(paramsPut)
if err != nil {
    log.Fatal(err)
}

错误信息:

cannot use mw (type *imagick.MagickWand) as type image.Image in argument to jpeg.Encode:
    *imagick.MagickWand does not implement image.Image (missing At method)
英文:

I am using the following code which fetch the object from Amazon s3 and after performing resizing and cropping. I want to store it on s3. But the problem is i am not able convert the mw (Image maigck object) to byte array. Which will be used for storing it on s3. Moreover in current method it uses jpeg.Encode. What if the image in .png or .gif format. How will we convert it to []byte?

Could you please also tell me how to evenly crop an image just passing the aspect ratio not cropping coordinates. imgStream.Crop((int)originalWidth, ((int)(originalWidth / masterAspectRatio)), Gravity.Center) like we do it in .net. Reason i am asking is there is no method in library which provides this flexibility.

s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
            params := &s3.GetObjectInput{
    		Bucket: aws.String(bucketName),
    		Key: aws.String(keyName),
    	    }
    
    	out, err := s3Client.GetObject(params)
    
    	if err != nil {
      		 log.Fatal(err)
    	}
    
    	img, err := ioutil.ReadAll(out.Body)
    	if err != nil {
    	    log.Fatal(err)
    	}      
    	
    	mw := imagick.NewMagickWand()	
    
    	err = mw.ReadImageBlob(img)
    	if err != nil {
    	    log.Fatal(err)
    	}
   
        //Perform resizing and cropping on mw object

        buf := new(bytes.Buffer)
    	err = jpeg.Encode(buf, mw, nil)
    	sendmw_s3 := buf.Bytes()
    
    	 paramsPut := &s3.PutObjectInput{
                        Bucket:         aws.String(masterBucketName),
                        Key:            aws.String(keyName),
                        Body:         bytes.NewReader(sendmw_s3),
                }
    
        resp, err := s3Client.PutObject(paramsPut)
    	if err != nil {
    	    log.Fatal(err)
    	}

Error :

 cannot use mw (type *imagick.MagickWand) as type image.Image in argument to jpeg.Encode:
	*imagick.MagickWand does not implement image.Image (missing At method)

答案1

得分: 2

你需要使用func (mw *MagickWand) GetImageBlob() []byte函数。

它返回一个字节切片,其中包含当前文件格式(JPEG、gif、PNG...)的完整编码图像。

因此,返回的数据可以保存到磁盘上,或者原样发送到S3。

请参阅https://gowalker.org/github.com/gographics/imagick/imagick#MagickWand_GetImageBlob获取文档。

英文:

You need to use the func (mw *MagickWand) GetImageBlob() []byte function.

It returns a slice of bytes containing a complete encoded image for the current file format (JPEG, gif, PNG...).

The returned data can therefore be saved to disk, or sent to s3 as-is.

See https://gowalker.org/github.com/gographics/imagick/imagick#MagickWand_GetImageBlob for the documentation.

答案2

得分: 1

这个问题实际上有两个部分,@SirDarius已经回答了其中一个部分,他建议使用GetImageBlob()来获取图像的二进制数据。你还可以使用SetImageFormat()在生成二进制数据之前更改图像的格式。

关于裁剪的部分,我确定有很多种方法可以使用ImageMagick来实现。我通常的做法是,首先将图像进行变换,使较小的尺寸适应所需的目标分辨率,然后裁剪掉溢出的部分。

// 创建一个新的图像,使最小的尺寸适应,并且其余部分超出尺寸
size := fmt.Sprintf("%dx%d^+0+0", w, h)
tx := wand.TransformImage("", size)

// 居中裁剪掉图像的额外部分
tx.SetImageGravity(imagick.GRAVITY_CENTER)
offsetX := -(int(w) - int(tx.GetImageWidth())) / 2
offsetY := -(int(h) - int(tx.GetImageHeight())) / 2
err := tx.ExtentImage(w, h, offsetX, offsetY)
...
英文:

This question is actually two questions, and @SirDarius answered one of them, by suggesting the use of GetImageBlob(). You can also use SetImageFormat() to change the image format before generating the blob.

For the part about the crop, I am sure there are a bunch of ways to do this with ImageMagick. The way I have done it, to achieve a center crop is to first transform the image so that the smaller dimension fits into my desired target resolution. And then to crop away the parts that overflow.

// Create a new image where smallest dimension is fit
// and the rest overflows the dimensions
size := fmt.Sprintf("%dx%d^+0+0", w, h)
tx := wand.TransformImage("", size)

// Center Crop away the extra parts of the image, to perform
tx.SetImageGravity(imagick.GRAVITY_CENTER)
offsetX := -(int(w) - int(tx.GetImageWidth())) / 2
offsetY := -(int(h) - int(tx.GetImageHeight())) / 2
err := tx.ExtentImage(w, h, offsetX, offsetY)
...

huangapple
  • 本文由 发表于 2016年2月3日 21:51:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/35178934.html
匿名

发表评论

匿名网友

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

确定