国土空间规划成果,要求jpeg图片至少有300dpi,
要求300dpi的原因主要是因为300dpi通常来说能保证打印机打印出来的成果看起来会比较清析。
为了实现这个需求,我把google,百度,github,golang官网甚至最火的chat-gpt都翻了个底朝天。
总之,结果就是目前golang生态体系中暂时还没有实现了获取jpg图片dpi的接口。
所以我打算写一个来补一下这个生态的缺口。

dpi和ppi是不是同一个东西?

要获取dpi首先得知道dpi是个什么东西。


image.png

还不清楚的可以自己去这个链接里面看,人家已经总结得很好了,我就不再赘述了。
https://blog.csdn.net/iteye_19871/article/details/81965791

jpg文件的编码规范

无论是golang标准库里面的image包,还是第二方包,都没有提供dpi获取的方法。
image包中通过Config可以获取到:ColorModel、Width、Height这三个属性

type Config struct {    
  ColorModel    color.Model     
  Width, Height int 
}

通过这几天最火的gpt来查找,说是可以用第三方库github.com/dsoprea/go-exif/v2来实现。

正在思考,请等待......

Go语言无法直接获取JPEG图片的DPI,可以通过使用第三方库exif来获取。

exif是一个Go语言库,用于解析JPEG图像的元数据,包括DPI。

使用exif库,可以使用以下代码获取JPEG图片的DPI:

package main

import (
    "fmt"
    "log"
    "os"
    "github.com/dsoprea/go-exif/v2"
)

func main() {
    // 打开图片文件
    file, err := os.Open("test.jpg")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 解析图片文件的元数据
    exifData, err := exif.ReadExifData(file)
    if err != nil {
        log.Fatal(err)
    }

    // 获取DPI
    xResolution, err := exifData.Get("XResolution")
    if err != nil {
        log.Fatal(err)
    }
    yResolution, err := exifData.Get("YResolution")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("XResolution: %v, YResolution: %v\n", xResolution, yResolution)
}

image.png

很明显,代码不对,但是提供了一个很好的实现思路,可以按这个思路去找,每次查询返回的结果会不太一样。


image.png

最简单的方法是从二进制中去解析:

正规的官方网站:https://exiftool.org/TagNames/JPEG.html
jpg的编码大概长这样:

image.png

最有用的就是前面一部分了,我们要的信息在APP0里面。
可以看一下APP0里面的内容:


image.png

图中的00 60 00 60 ,x方向密度和y方向密度就是我们要的信息了。


image.png

我们把16进制的60转换一下,值正好是96,与我们在windows中看到的一样。


image.png

image.png