【问题标题】:Golang Converting Image magick object to []byteGolang将图像魔术对象转换为[]字节
【发布时间】:2016-02-03 13:51:31
【问题描述】:

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

能否请您告诉我如何仅通过纵横比而不是裁剪坐标来均匀裁剪图像。 imgStream.Crop((int)originalWidth, ((int)(originalWidth / masterAspectRatio)), Gravity.Center) 就像我们在 .net 中一样。我要问的原因是库中没有提供这种灵活性的方法。

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)
        }

错误:

 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)

【问题讨论】:

  • 对 imagick API 的快速检查将我带到gowalker.org/github.com/gographics/imagick/…,它似乎返回了一个已编码的 []byte 所需格式(JPEG、Gif ...)。这不是你需要的吗?
  • @SirDarius 谢谢,没注意到。
  • 另外,SetImageFormat()可以在调用GetImageBlob()之前转换格式

标签: go go-imagick


【解决方案1】:

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

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

因此可以将返回的数据保存到磁盘,或按原样发送到 s3。

有关文档,请参阅 https://gowalker.org/github.com/gographics/imagick/imagick#MagickWand_GetImageBlob

【讨论】:

    【解决方案2】:

    这个问题其实是两个问题,@SirDarius 回答了其中一个,建议使用GetImageBlob()。您也可以在生成 blob 之前使用SetImageFormat() 更改图像格式。

    关于作物的部分,我相信 ImageMagick 有很多方法可以做到这一点。我实现中心裁剪的方法是首先转换图像,使较小的尺寸适合我想要的目标分辨率。然后裁剪掉溢出的部分。

    // 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)
    ...
    

    【讨论】:

    • 但是在这里你没有使用纵横比。我有这样的要求,比如假设图像的纵横比为 16:9,然后我需要将其转换为最接近的 4:3 纵横比。那么,我如何使用上述方法
    • 哦,那你不想要中心裁剪。你想要一个合身和垫
    • 目前,我使用的是mw.CropImage(uint(originalWidth), (uint(originalWidth / masterAspectRatio)), 0, 0)。但它从原点裁剪图像并保持前面提到的宽度和高度。因此,如果假设我想将纵横比从 16:9 更改为 4:3,那么我想从两侧裁剪宽度,类似地,如果我想将纵横比从 4:3 更改为 16:9 然后我需要从两侧裁剪高度以获得所需纵横比的图像。
    • 那么,正如我在.net 中的问题中提到的那样,它可以像imgStream.Crop((int)originalWidth, ((int)(originalWidth / masterAspectRatio)), Gravity.Center 一样完成。同样,我该怎么做这是我的问题
    • 出于好奇,您是否尝试过我的建议,或者您只是看着它并认为它不是您想要的?因为在你发表评论之后,现在听起来你确实想要一个合适的中心作物,这就是我的做法
    猜你喜欢
    • 2018-01-25
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多