首頁  >  文章  >  後端開發  >  Golang 為 jpeg 映像產生一致的雜湊值,而無需寫入磁碟

Golang 為 jpeg 映像產生一致的雜湊值,而無需寫入磁碟

WBOY
WBOY轉載
2024-02-11 16:33:08664瀏覽

Golang 为 jpeg 图像生成一致的哈希值,而无需写入磁盘

在開發過程中,我們經常需要比較影像檔案的相似度,以便進行影像辨識、去重等操作。而產生影像的雜湊值是一種常見的方法。通常,我們需要將影像寫入磁碟,然後再讀取出來進行哈希計算。然而,使用Golang程式語言,我們可以輕鬆實現在生成jpeg映像的同時,直接計算一致的雜湊值,而無需寫入磁碟。這為我們節省了時間和磁碟空間,並提高了效率。本文將詳細介紹如何在Golang中實現這項功能。

問題內容

golang 成像新手

我正在嘗試為 jpeg 圖像生成一致的哈希值。 當我以 JPEG 格式寫入磁碟(這是預期的)後重新加載圖像時,加載圖像並在原始位元組上生成哈希值會產生不同的雜湊值。一旦我將 RBGA 作為 JPEG 寫入磁碟,像素就會被修改,這會破壞我之前計算的雜湊值。

僅對檔案 hash("abc.jpeg") 進行雜湊處理就表示我必須寫入磁碟;讀回;產生雜湊值等..

  • 在讀取/寫入時是否可以使用任何設定來控制輸出 jpeg 像素的行為
  • 我是否應該使用 *image.RGBA?輸入影像是 *image.YCbCr?
#
// Open the input image file
inputFile, _ := os.Open("a.jpg")
defer inputFile.Close()

// Decode the input image
inputImage, _, _ := image.Decode(inputFile)

// Get the dimensions of the input image
width := inputImage.Bounds().Dx()
height := inputImage.Bounds().Dy()
subWidth := width / 4
subHeight := height / 4

// Create a new image
subImg := image.NewRGBA(image.Rect(0, 0, subWidth, subHeight))
draw.Draw(subImg, subImg.Bounds(), inputImage, image.Point{0, 0}, draw.Src)

// id want the hashes to be the same for read / write but they will always differ
hash1 := sha256.Sum256(imageToBytes(subImg))
fmt.Printf("<---OUT [%s] %x\n", filename, hash1)
jpg, _ := os.Create("mytest.jpg")
_ = jpeg.Encode(jpg, subImg, nil)
jpg.Close()

// upon reading it back in the pixels are ever so slightly diff
f, _ := os.Open("mytest.jpg")
img, _, _ := image.Decode(f)
jpg_input := image.NewRGBA(img.Bounds())
draw.Draw(jpg_input, img.Bounds(), img, image.Point{0, 0}, draw.Src)
hash2 := sha256.Sum256(imageToBytes(jpg_input))
fmt.Printf("--->IN  [%s] %x\n", filename, hash2)

            // real world use case is..
            // generate subtile of large image plus hash
            // if hash in a dbase
            //    pixel walk to see if hash collision occurred
            //    if pixels are different
            //       deal with it...
            ///   else
            //      object.filename = dbaseb.filename
            // else
            //     add filename to dbase with hash as the lookup
            //     write to jpeg to disk

解決方法

您可以使用雜湊作為編寫器的目標,並使用 io.MultiWriter 在寫入檔案時計算雜湊:

hash:=sha256.New()
jpeg.Encode(io.MultiWriter(file,hash),img,nil)
hashValue:=hash.Sum(nil)

以上是Golang 為 jpeg 映像產生一致的雜湊值,而無需寫入磁碟的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除