如何使用 Golang 设置 DPI?

how to set DPI using Golang?

Golang图片包在某种程度上非常好用,但缺少设置图片DPI的支持。我检查了生成文件的文件头,FF D8 FF DB 看起来像 jpeg raw。 AFAIK,raw 不像 jfif 那样带有 DPI。所以这是我的问题,如何设置生成图像的 DPI?或者如何将 raw 转换为 jfif,我知道我可以从中编辑文件的特定位来设置 DPI?以前我在我的应用程序中嵌入了一个 AdvancedBatchConverter 可执行文件并使用 exec.Command(fmt.Sprintf("%s/AdvancedBatchConverter/abc.exe", cwd), outputFile, "/jfif", fmt.Sprintf("/convert=%s", jfifFileName)) 来完成这个技巧,但实际上,每次我看代码时都对它感到厌恶。

我相信您正在寻找 exif 值 XResolutionYResolution

我的理解是原生 jpeg 编码器没有任何 exif 数据选项。

https://github.com/dsoprea/go-exif会让你修改exif数据。

此外,我相信如果您先将 jpeg 写入 bytes.Buffer 或类似文件,然后附加 exif,您就可以在内存中完成整个操作,而无需先刷新到磁盘。

希望对您有所帮助。

github.com/dsoprea/go-exif/v2 可以 reader 并写入 exif 数据。 与其他包 github.com/dsoprea/go-jpeg-image-structure 这是代码示例。用于将 DPI(XResolution, YResolution) 写入图像。

import( 
    exif2 "github.com/dsoprea/go-exif/v2"
    exifcommon "github.com/dsoprea/go-exif/v2/common"
    jpegstructure "github.com/dsoprea/go-jpeg-image-structure"
)
func SetExifData(filepath string) error {
jmp := jpegstructure.NewJpegMediaParser()

intfc, err := jmp.ParseFile(filepath)
log.PanicIf(err)

sl := intfc.(*jpegstructure.SegmentList)

// Make sure we don't start out with EXIF data.
wasDropped, err := sl.DropExif()
log.PanicIf(err)

if wasDropped != true {
    fmt.Printf("Expected the EXIF segment to be dropped, but it wasn't.")
}

im := exif2.NewIfdMapping()

err = exif2.LoadStandardIfds(im)
log.PanicIf(err)

ti := exif2.NewTagIndex()
rootIb := exif2.NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.EncodeDefaultByteOrder)

err = rootIb.AddStandardWithName("XResolution", []exifcommon.Rational{{Numerator: uint32(96), Denominator: uint32(1)}})
log.PanicIf(err)

err = rootIb.AddStandardWithName("YResolution", []exifcommon.Rational{{Numerator: uint32(96), Denominator: uint32(1)}})
log.PanicIf(err)

err = sl.SetExif(rootIb)
log.PanicIf(err)

b := new(bytes.Buffer)

err = sl.Write(b)
log.PanicIf(err)

if err := ioutil.WriteFile(filepath, b.Bytes(), 0644); err != nil {
    fmt.Printf("write file err: %v", err)
}
return nil
}