我正在尝试加载一个大图像(780 MB)与Golangs ImageMagick库,并更改图像的格式从PNG到PTIF(金字塔tiff)。当我运行该程序时,不同的事情可能会发生:
- 有时会关闭Vscode(内存消耗高)
- 当它挂起的时候,它不会停止程序,但是它也不会再使用任何资源(观察htop)。
- 有时我会得到错误
runtime error: gobytes: length out of range
,这似乎发生在它大于cgo中maxAlloc的值时(ImageMagick使用C代码)。错误来自https://go.dev/src/runtime/string.go第304行。 - 它将在一段时间后停止调试,并在Vscode中显示消息“进程x已退出,状态为-9”
当我设置断点时,在StoreImage函数中的byteBuf := mim.mw.GetImageBlob()
之前一切正常。
我在联想Linux笔记本电脑上有16 GB的内存,我已经把我的交换文件增加到8 GB,但这只帮助我用ImageMagick在CLI中更改格式(转换collage.png测试.ptif),它在应用程序中仍然不起作用。我猜这是内存问题,但16 GB不应该足够用于780 MB的图像吗?有什么建议吗?代码适用于较小的图像。
package main
import (
"bytes"
"fmt"
"io"
"log"
"os"
"gopkg.in/gographics/imagick.v3/imagick"
)
type MyImageMagick struct {
mw *imagick.MagickWand
}
func (mim *MyImageMagick) convert() {
f, err := os.Open("collage.png")
if err != nil {
log.Fatal(err)
}
if err := mim.LoadImage(f); err != nil {
log.Fatal(err)
}
r, err := mim.StoreImage("ptif")
if err != nil {
log.Fatal(err)
}
t, err := os.Create("testptif")
if err != nil {
log.Fatal(err)
}
n, err := io.Copy(t, r)
if err != nil {
log.Fatal(err)
}
}
func (mim *MyImageMagick) LoadImage(reader io.Reader) error {
var buf bytes.Buffer
if _, err := buf.ReadFrom(reader); err != nil {
return err
}
if err := mim.mw.ReadImageBlob(buf.Bytes()); err != nil {
return err
}
return nil
}
func (mim *MyImageMagick) StoreImage(format string) (io.Reader, error) {
if err := mim.mw.SetImageFormat(format); err != nil {
return nil, err
}
byteBuf := mim.mw.GetImageBlob()
return bytes.NewReader(byteBuf), nil
}
func main() {
imagick.Initialize()
defer imagick.Terminate()
mim := &MyImageMagick{mw: imagick.NewMagickWand()}
mim.convert()
}
1条答案
按热度按时间jk9hmnmh1#
libvips可以快速完成此类处理,并且使用的内存相对较少。
因此,一个1gb的PNG文件(15,000 x 26,000像素)在12秒内转换为锥形TIFF,需要210MB内存。
有几个Go语言绑定,但不幸的是,它们似乎都有各种各样的问题。也许你可以直接用
vips
命令来实现。转换成金字塔形tiff的例子如下:您可以为tiff写入设置各种其他选项:
https://www.libvips.org/API/current/VipsForeignSave.html#vips-tiffsave