Maison  >  Article  >  développement back-end  >  Golang génère des hachages cohérents pour les images JPEG sans écrire sur le disque

Golang génère des hachages cohérents pour les images JPEG sans écrire sur le disque

WBOY
WBOYavant
2024-02-11 16:33:08663parcourir

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

Pendant le processus de développement, nous devons souvent comparer la similitude des fichiers image pour la reconnaissance d'images, la déduplication et d'autres opérations. Générer un hachage d'une image est une approche courante. Habituellement, nous devons écrire l'image sur le disque, puis la lire pour le calcul du hachage. Cependant, en utilisant le langage de programmation Golang, nous pouvons facilement calculer directement des valeurs de hachage cohérentes tout en générant des images JPEG sans écrire sur le disque. Cela nous fait gagner du temps et de l'espace disque et augmente l'efficacité. Cet article détaillera comment implémenter cette fonctionnalité dans Golang.

Contenu des questions

Nouveau dans Golang Imaging

J'essaie de générer des hachages cohérents pour les images jpeg. Lorsque je recharge l'image après l'avoir écrite sur le disque au format JPEG (ce qui est attendu), le chargement de l'image et la génération du hachage sur les octets bruts produisent un hachage différent. Une fois que j'écris le RBGA sur le disque au format JPEG, les pixels sont modifiés, ce qui corrompt le hachage que j'ai calculé plus tôt.

Le simple fait de hacher le fichier hash("abc.jpeg") signifie que je dois écrire sur le disque ; générer des hachages, etc... 

  • Existe-t-il un paramètre que je peux utiliser pour contrôler le comportement des pixels JPEG de sortie lors de la lecture/écriture
  • Dois-je utiliser *image.RGBA ? L'image d'entrée est *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

Solution de contournement

Vous pouvez utiliser un hachage comme cible de l'écrivain et utiliser io.MultiWriter pour calculer le hachage lors de l'écriture du fichier :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer