package imageproc import ( "fmt" "image" "github.com/airbusgeo/godal" log "github.com/sirupsen/logrus" "gocv.io/x/gocv" ) func GTiffToJPG(ftiff, fjpg string) 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)) if len(bands) < 3 { err = fmt.Errorf("TIFF file %s has less than 3 bands", ftiff) log.Error(err) return err } // 获取图像大小 width := bands[0].Structure().SizeX height := bands[0].Structure().SizeY // 读取每个波段并转换为 8 位 img := gocv.NewMatWithSize(height, width, gocv.MatTypeCV16UC3) for i := 1; i <= 3; i++ { band := ds.Bands()[i-1] data := make([]uint16, width*height) err = band.Read(0, 0, data, width, height) if err != nil { log.Printf("Error reading band %d: %v", i, err) return err } // 计算最小值和最大值 var minVal, maxVal uint16 = 65535, 0 for _, value := range data { if value < minVal { minVal = value } if value > maxVal { maxVal = value } } // 将 16 位数据缩放到 8 位并存储到图像的相应通道 for y := 0; y < height; y++ { for x := 0; x < width; x++ { value := data[y*width+x] scaledValue := uint8(float64(value-minVal) / float64(maxVal-minVal) * 255) img.SetUCharAt(y, x*3+(i-1), scaledValue) } } // 将 16 位数据存储到图像的相应通道 // for y := 0; y < height; y++ { // for x := 0; x < width; x++ { // value := data[y*width+x] // img.SetShortAt(y, x*3+(i-1), int16(value)) // } // } } // 调整图像大小 resizedImg := gocv.NewMat() gocv.Resize(img, &resizedImg, image.Point{X: 2336, Y: 2336}, 0, 0, gocv.InterpolationCubic) // 保存为 JPG 文件 ok := gocv.IMWrite(fjpg, resizedImg) if !ok { err = fmt.Errorf("error saving %s", fjpg) return err } return nil }