在Golang中比较base64图像字符串

huangapple go评论109阅读模式
英文:

Comparing base64 image strings in Golang

问题

我有一个服务,可以比较两个Base64编码的图像字符串。

我的初步尝试发现,尽管实际图像(JPG)是相同的(大小、分辨率、尺寸等),但元数据存在差异。

有没有办法去除大部分动态元数据,只比较图像的视觉方面?

目前,我正在使用以下代码...

package converter

import (
	"bufio"
	"encoding/base64"
	"log"
	"os"
)

func Base64(path string) (string, error) {
	imgFile, err := os.Open(path)
	if err != nil {
		log.Fatalln(err)
	}

	defer imgFile.Close()

	// 根据文件大小创建一个新的缓冲区
	fInfo, _ := imgFile.Stat()
	var size int64 = fInfo.Size()
	buf := make([]byte, size)

	// 将文件内容读入缓冲区
	fReader := bufio.NewReader(imgFile)
	fReader.Read(buf)

	// 将缓冲区字节转换为Base64字符串 - 对于新图像,请使用buf.Bytes()
	imgBase64Str := base64.StdEncoding.EncodeToString(buf)

	return imgBase64Str, nil
}
英文:

I have a service that compares two base64 encoded image strings

My initial attempt revealed that there is differences in metadata while the actual image (JPG) in this case is identical (size,resolution,dimensions,etc).

Is there a way to strip away much of the dynamic metadata so that I can just compare the visual aspect of the image?

Currently, I am using the following...

package converter

import (
	"bufio"
	"encoding/base64"
	"log"
	"os"
)

func Base64(path string) (string, error) {
	imgFile, err := os.Open(path)
	if err != nil {
		log.Fatalln(err)
	}

	defer imgFile.Close()

	// create a new buffer base on file size
	fInfo, _ := imgFile.Stat()
	var size int64 = fInfo.Size()
	buf := make([]byte, size)

	// read file content into buffer
	fReader := bufio.NewReader(imgFile)
	fReader.Read(buf)

	// convert the buffer bytes to base64 string - use buf.Bytes() for new image
	imgBase64Str := base64.StdEncoding.EncodeToString(buf)

	return imgBase64Str,nil
}

答案1

得分: 3

感知哈希是一个用于计算图像的哈希值的库,该哈希值基于图像的视觉特征。github.com/carlogit/phash是一个使用Go语言实现的库。它提供了创建和比较两个哈希值的函数,以给出表示两个图像相似程度的“距离”。

出于兴趣,我尝试了一下,它很容易使用,并且在一些测试图像上效果很好。例如:

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 距离:0

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 距离:2

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 距离:32

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/carlogit/phash"
)

func main() {
	if len(os.Args) < 3 {
		log.Fatalf("usage: %s <ImageFileA> <ImageFileB>\n", os.Args[0])
	}

	a := hash(os.Args[1])
	b := hash(os.Args[2])
	distance := phash.GetDistance(a, b)

	fmt.Printf("距离:%d\n", distance)
}

//hash返回图像的感知哈希值
func hash(filename string) string {
	img, err := os.Open(filename)
	if err != nil {
		log.Fatal(err)
	}
	defer img.Close()

	ahash, err := phash.GetHash(img)
	if err != nil {
		log.Fatal(err)
	}
	return ahash
}
英文:

Perceptual Hash is a library to calculate a phash; a hash of an image based on visual characteristics. github.com/carlogit/phash is a golang implementation. It has functions to create and compare two hashes to give a 'distance' indicating how dissimilar two images are.

Out of interest I gave it a try, it's simple to use and effective with some test images. For example:

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 distance: 0

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 distance: 2

在Golang中比较base64图像字符串 在Golang中比较base64图像字符串 distance: 32

package main

import (
	&quot;fmt&quot;
	&quot;log&quot;
	&quot;os&quot;

	&quot;github.com/carlogit/phash&quot;
)

func main() {
	if len(os.Args) &lt; 3 {
		log.Fatalf(&quot;usage: %s &lt;ImageFileA&gt; &lt;ImageFileB&gt;\n&quot;, os.Args[0])
	}

	a := hash(os.Args[1])
	b := hash(os.Args[2])
	distance := phash.GetDistance(a, b)

	fmt.Printf(&quot;distance: %d\n&quot;, distance)
}

//hash returns a phash of the image
func hash(filename string) string {
	img, err := os.Open(filename)
	if err != nil {
		log.Fatal(err)
	}
	defer img.Close()

	ahash, err := phash.GetHash(img)
	if err != nil {
		log.Fatal(err)
	}
	return ahash
}

huangapple
  • 本文由 发表于 2016年7月20日 03:19:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/38466804.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定