Files
sjy01-image-proc/producer/jpg.go
2024-05-29 15:24:40 +08:00

85 lines
1.9 KiB
Go

package imageproc
import (
"fmt"
"image"
"github.com/airbusgeo/godal"
log "github.com/sirupsen/logrus"
"gocv.io/x/gocv"
)
func GTiffToJPG(ftiff, fjpg string, reversed bool) error {
// 打开 TIFF 文件
ds, err := godal.Open(ftiff)
if err != nil {
log.Printf("Error opening TIFF file %s: %v", ftiff, err)
return err
}
defer ds.Close()
bands := ds.Bands()
log.Infof("TIFF file %s has %d bands", ftiff, len(bands))
// 获取图像大小
width := bands[0].Structure().SizeX
height := bands[0].Structure().SizeY
bandsCnt := len(bands)
// 创建 16 位图像矩阵
var img gocv.Mat
defer img.Close()
if bandsCnt == 1 {
img = gocv.NewMatWithSize(height, width, gocv.MatTypeCV16UC1)
} else {
bandsCnt = 3 // 只取前三个波段
img = gocv.NewMatWithSize(height, width, gocv.MatTypeCV16UC3)
}
// 读取每个波段并存储到图像矩阵中
for i := 0; i < bandsCnt; i++ {
band := bands[i]
data := make([]uint16, width*height)
err = band.Read(0, 0, data, width, height)
if err != nil {
fmt.Printf("Error reading band %d: %v\n", i, err)
return err
}
// 将 16 位数据存储到图像的相应通道
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
value := data[y*width+x]
img.SetShortAt(y, x*bandsCnt+i, int16(value))
}
}
}
// 重采样图像
gocv.Resize(img, &img, image.Point{X: img.Cols() / 2, Y: img.Rows() / 2}, 0, 0, gocv.InterpolationCubic)
// 创建 8 位图像矩阵
img8 := gocv.NewMat()
defer img8.Close()
if bandsCnt == 1 {
img.ConvertToWithParams(&img8, gocv.MatTypeCV8UC1, 1.0/256.0*2, 0)
} else {
img.ConvertToWithParams(&img8, gocv.MatTypeCV8UC3, 1.0/256.0*2, 0)
if reversed {
channels := gocv.Split(img8)
gocv.Merge([]gocv.Mat{channels[2], channels[1], channels[0]}, &img8)
for _, ch := range channels {
ch.Close()
}
}
}
ok := gocv.IMWrite(fjpg, img8)
if !ok {
err = fmt.Errorf("error saving %s", fjpg)
return err
}
return nil
}