package common import ( "bytes" "image" "image/color" _ "image/jpeg" // 注册解码器(dHash 全量解码用) _ "image/png" ) // ImageDHash64 整图 64 位 dHash(9x8 灰度采样,与 ffmpeg scale=9:8 同语义)。 // 两图相似度 = 哈希异或的位 1 数(汉明距离),≤ CleanHashHamming 阈值视为近重复 // (数据清洗桶内多样性保留用,见 consts.CleanBuckets)。 func ImageDHash64(data []byte) (uint64, error) { src, _, err := image.Decode(bytes.NewReader(data)) if err != nil { return 0, err } return hashOf(src) } // hashOf 图像 dHash:采样 9 列 x 8 行(全域拉伸),逐行比较相邻列明暗得 64 位 func hashOf(src image.Image) (uint64, error) { b := src.Bounds() w, h := b.Dx(), b.Dy() if w < 1 || h < 1 { return 0, image.ErrFormat } var gray color.Gray shade := func(x, y int) uint32 { gray = color.GrayModel.Convert(src.At(b.Min.X+x, b.Min.Y+y)).(color.Gray) return uint32(gray.Y) } var h64 uint64 for r := 0; r < 8; r++ { y := (h - 1) * r / 7 for c := 0; c < 8; c++ { xl := (w - 1) * c / 8 xr := (w - 1) * (c + 1) / 8 h64 <<= 1 if shade(xl, y) < shade(xr, y) { h64 |= 1 } } } return h64, nil }