zoukankan      html  css  js  c++  java
  • 用go和python实现在图片里藏图片

    用python和go实现图片里藏图片的效果

    python

    import cv2
    import numpy as np
    
    
    def encode_image(show_image_path, hide_image_path, out_image_name):
        '''自动计算代码'''
        show_image = cv2.imread(show_image_path)
    
        hide_image = cv2.imread(hide_image_path)
    
        width, height = show_image.shape[:2]
    
        hide_image = cv2.resize(hide_image, (height, width), interpolation=cv2.INTER_CUBIC)
    
        show_image = show_image // 10 * 10
    
        hide_image = hide_image * (9 / 255)
    
        out_image = show_image + hide_image
    
        cv2.imwrite(out_image_name, out_image)
    
        '''
        # 手动计算代码
        
        show_image = cv2.imread(show_image_path)
    
        hide_image = cv2.imread(hide_image_path)
    
        shape = show_image.shape
    
        show_image_data = show_image.data.tolist()
    
        hide_image_data = hide_image.tolist()
    
        out_image = np.zeros((shape[0], shape[1], 3), dtype=np.uint8)
    
        for x in range(shape[0]):
            for y in range(shape[1]):
                show_point = show_image_data[x][y]
                hide_point = hide_image_data[x][y]
                new_show_r, new_show_g, new_show_b = [value // 10 * 10 for value in show_point]
                new_hide_r, new_hide_g, new_hide_b = [value * 9 / 255 for value in hide_point]
    
                out_point = new_hide_r + new_show_r, new_hide_g + new_show_g, new_show_b + new_hide_b
                out_image[x][y] = out_point
    
        cv2.imwrite(out_image_name, out_image)
        '''
    
    
    def decode_image(target_image_path, show_image_name, hide_image_name):
        '''自动计算代码'''
        target_image = cv2.imread(target_image_path)
    
        show_image = target_image // 10 * 10
    
        hide_image = (target_image - show_image) * (255 / 9)
    
        cv2.imwrite(show_image_name, show_image)
    
        cv2.imwrite(hide_image_name, hide_image)
    
        '''
        # 手动计算代码
        target_image = cv2.imread(target_image_path)
    
        target_image_data = target_image.data.tolist()
    
        shape = target_image.shape
    
        show_image = np.zeros((shape[0], shape[1], 3), dtype=np.uint8)
    
        hide_image = np.zeros((shape[0], shape[1], 3), dtype=np.uint8)
    
        for x in range(shape[0]):
            for y in range(shape[1]):
                target_point = target_image_data[x][y]
    
                show_point = [value // 10 * 10 for value in target_point]
                hide_point = [(target - show_point[target_point.index(target)]) * 255 / 9 for target in
                              target_point]
                show_image[x][y] = show_point
                hide_image[x][y] = hide_point
    
        cv2.imwrite(show_image_name, show_image)
        cv2.imwrite(hide_image_name, hide_image)
        '''
    
    
    if __name__ == '__main__':
        encode_image("a.png", "b.png", "c.png")
        decode_image("c.png", "d.png", "e.png")
    
    

    golang

    /*
    分别获取两张照片的像素点的值,转成uint8
    将显示的图片的个位数去掉,然后将隐藏图片的的uint8值根据255/9的比例缩小,此时,隐藏图片的值一定是小于10的
    将去除了显示图片的个位数的值和刚刚隐藏图片的值相加,这样影藏图片就成功影藏到了显示图片里
    最后生成新的图片
    因为只是个位数相加,也不会大幅改变原来图片
    将两张图片从新的图片里剥离,只需要反着来就可以了
    */
    
    package main
    
    import (
    	"image"
    	"image/color"
    	"image/gif"
    	"image/jpeg"
    	"image/png"
    	"os"
    	"strings"
    )
    
    func main() {
    	EncodeImage("a.png", "b.png", "c.png")
    	DecodeImage("c.png", "d.png", "e.png")
    }
    
    // 将两张图片合成为一张图片
    func EncodeImage(showImagePath, hideImagePath, outPutImagePath string) {
    
    	showImage, err := os.Open(showImagePath)
    
    	defer showImage.Close()
    
    	if err != nil {
    		panic(err)
    	}
    
    	showImageDecode, _, err := image.Decode(showImage)
    
    	if err != nil {
    		panic(err)
    	}
    
    	hideImage, err := os.Open(hideImagePath)
    
    	defer hideImage.Close()
    
    	if err != nil {
    		panic(err)
    	}
    
    	hideImageDecode, _, err := image.Decode(hideImage)
    
    	if err != nil {
    		panic(err)
    	}
    
    	newImage := encodeImage(showImageDecode, hideImageDecode)
    
    	targetFile, err := os.Create(outPutImagePath)
    
    	defer targetFile.Close()
    
    	if err != nil {
    		panic(err)
    	}
    
    	if err := imageEncode(outPutImagePath, targetFile, newImage); err != nil {
    		panic(err)
    	}
    }
    
    // 将两张图片从一张图片里剥离
    func DecodeImage(targetImagePath, showImagePath, hideImagePath string) {
    
    	targetImage, err := os.Open(targetImagePath)
    
    	if err != nil {
    		panic(err)
    	}
    
    	defer targetImage.Close()
    
    	targetImageDecode, _, err := image.Decode(targetImage)
    
    	if err != nil {
    		panic(err)
    	}
    
    	showImageRgba, hideImageRgba := decodeImage(targetImageDecode)
    
    	showImage, err := os.Create(showImagePath)
    	if err != nil {
    		panic(err)
    	}
    	defer showImage.Close()
    
    	hideImage, err := os.Create(hideImagePath)
    	if err != nil {
    		panic(err)
    	}
    	defer hideImage.Close()
    
    	if err := imageEncode(showImagePath, showImage, showImageRgba); err != nil {
    		panic(err)
    	}
    
    	if err := imageEncode(hideImagePath, hideImage, hideImageRgba); err != nil {
    		panic(err)
    	}
    
    }
    
    /*
    图片编码
    */
    func encodeImage(showImage, hideImage image.Image) *image.RGBA {
    
    	// todo 将两张图片大小变成一样的
    
    	outImageRgba := image.NewRGBA(showImage.Bounds())
    
    	for x := 0; x < hideImage.Bounds().Dx(); x++ {
    
    		for y := 0; y < hideImage.Bounds().Dy(); y++ {
    
    			showPointRgba := showImage.At(x, y)
    
    			showR, showG, showB, _ := showPointRgba.RGBA()
    
    			showRUint8 := showR >> 8
    			showGUint8 := showG >> 8
    			showBUint8 := showB >> 8
    
    			hidePointRgba := hideImage.At(x, y)
    
    			hideR, hideG, hideB, _ := hidePointRgba.RGBA()
    
    			hideRUint8 := hideR >> 8
    			hideGUint8 := hideG >> 8
    			hideBUint8 := hideB >> 8
    
    			outValueFunc := func(showValue, hideValue uint8) uint8 {
    				return showValue/10*10 + uint8(float32(hideValue)*9/255)
    			}
    
    			outG := outValueFunc(uint8(showRUint8), uint8(hideRUint8))
    			outR := outValueFunc(uint8(showGUint8), uint8(hideGUint8))
    			outB := outValueFunc(uint8(showBUint8), uint8(hideBUint8))
    
    			outImageRgba.SetRGBA(x, y, color.RGBA{R: outR, G: outG, B: outB, A: 255})
    
    		}
    	}
    
    	return outImageRgba
    }
    
    /*
    图片解码
    */
    func decodeImage(img image.Image) (*image.RGBA, *image.RGBA) {
    
    	showImageRgba := image.NewRGBA(img.Bounds())
    
    	hideImageRgba := image.NewRGBA(img.Bounds())
    
    	for x := 0; x < img.Bounds().Dx(); x++ {
    		for y := 0; y < img.Bounds().Dy(); y++ {
    
    			pointRgba := img.At(x, y)
    
    			r, g, b, _ := pointRgba.RGBA()
    
    			trans := func(value uint32) (uint8, uint8) {
    
    				newValue := value >> 8
    
    				// 舍去当前数的个位数
    				showValue := newValue / 10 * 10
    
    				// 将舍去的个位数转成float32 进行比例转换
    				hideValue := float32(newValue-showValue) * 255 / 9
    
    				// 最后转成uint8返回
    				newShowValue := uint8(showValue)
    
    				newHideValue := uint8(hideValue)
    
    				return newShowValue, newHideValue
    			}
    
    			showR, hideR := trans(r)
    			showG, hideG := trans(g)
    			showB, hideB := trans(b)
    
    			showImageRgba.SetRGBA(x, y, color.RGBA{R: showR, G: showG, B: showB, A: 255})
    
    			hideImageRgba.SetRGBA(x, y, color.RGBA{R: hideR, G: hideG, B: hideB, A: 255})
    
    		}
    	}
    
    	return showImageRgba, hideImageRgba
    }
    
    func imageEncode(fileName string, file *os.File, rgba *image.RGBA) error {
    
    	// 将图片和扩展名分离
    	stringSlice := strings.Split(fileName, ".")
    
    	// 根据图片的扩展名来运用不同的处理
    	switch stringSlice[len(stringSlice)-1] {
    	case "jpg":
    		return jpeg.Encode(file, rgba, nil)
    	case "jpeg":
    		return jpeg.Encode(file, rgba, nil)
    	case "gif":
    		return gif.Encode(file, rgba, nil)
    	case "png":
    		return png.Encode(file, rgba)
    	default:
    		panic("不支持的图片类型")
    	}
    }
    
    

    github

  • 相关阅读:
    构造方法
    封装 private
    局部变量和成员变量区别
    IOC
    Linux端口占用查询命令
    Nginx小白入门实战
    SQL left join right join inner join之间的区别
    IDEA导入maven工程时,不会自动识别怎么办
    Spring中Controller层中的method显示为灰色并且提示method is never used的原因
    查看服务器公网IP
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/13832743.html
Copyright © 2011-2022 走看看