源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

go语言实现将重要数据写入图片中

  • 时间:2022-02-07 22:17 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:go语言实现将重要数据写入图片中
原理:将数据的二进制形式写入图像红色通道数据二进制的低位 只支持png格式的输出 写入数据 go run shadow.go -in="c.jpg" -data="hide me" -out="out.png" 读取数据 go run shadow.go -in="out.png"
[u]复制代码[/u] 代码如下:
package main import (     "errors"     "flag"     "fmt"     "image"     "image/color"     _ "image/jpeg"     "image/png"     "log"     "math"     "os" ) var FLAG = [4]byte{0x13, 0x14, 0x52, 0x00} //shadow flag. //byte to 8 bits func Byte2bits(b byte) (a [8]byte) {     var c uint8 = 7     var i uint8     for i = 0; i < 8; i++ {         a[i] = b >> (c - i) & 1     }     return } //8 bits to byte. func Bits2Byte(a [8]byte) (b byte) {     for i := 0; i < 8; i++ {         b += a[i] * uint8(math.Pow(2, float64(7-i)))     }     return } //uint32 to 4 bytes. func Uint32ToBytes(i uint32) (b [4]byte) {     b[0] = uint8(i >> 24)     b[1] = uint8(i >> 16 & 0xffff)     b[2] = uint8(i >> 8 & 0xff)     b[3] = uint8(i & 0xff)     return } //4 bytes to uint32. func Bytes2Uint32(b [4]byte) (i uint32) {     var j uint32     for ; j < 4; j++ {         i += uint32(b[j]) << (24 - j*8)     }     return } func BuildShadowHeader(length uint32) (b [8]byte) {     var i int     for ; i < 4; i++ {         b[i] = FLAG[i]     }     a := Uint32ToBytes(length)     for ; i < 8; i++ {         b[i] = a[i-4]     }     return } func WriteShadow(b []byte, im image.Image) (out image.Image, err error) {     max := im.Bounds().Max.X*im.Bounds().Max.Y/8 - 64     b_len := len(b)     if len(b) > max {         return nil, errors.New("image does not have enough space for shadow.")     }     head := BuildShadowHeader(uint32(b_len))     var bb byte     var bs [8]byte     var i int     out, err = SetImage(im, func(index, x, y int, in, out image.Image) {         rgba := readRGBAColor(im.At(x, y))         if index < b_len*8+64 {             if index < 64 {                 bb = head[index/8]             } else {                 bb = b[index/8-8]             }             bs = Byte2bits(bb)             i = index % 8             if bs[i] != rgba.R&1 {                 if bs[i] == 0 {                     rgba.R -= 1                 } else {                     rgba.R += 1                 }             }         }         if v := out.(*image.RGBA); v != nil {             v.SetRGBA(x, y, rgba)         }     })     if err != nil {         return nil, err     }     return } func ReadShadowData(im image.Image) (b []byte, err error) {     head, err := ReadShadowHeader(im)     if err != nil {         return nil, err     }     length := int(ReadShadowLength(head))     var bk []byte = make([]byte, length*8)     b = make([]byte, length)     _, err = SetImage(im, func(index, x, y int, in, out image.Image) {         if index >= 64 && index < length*8+64 {             R := readRGBAColor(im.At(x, y)).R             bk[index-64] = uint8(R & 1)         }     })     var bb [8]byte     var bs []byte     for i := 0; i < length; i++ {         bs = bk[8*i : 8*(i+1)]         for j := 0; j < 8; j++ {             bb[j] = bs[j]         }         b[i] = Bits2Byte(bb)     }     return } func ReadShadowHeader(im image.Image) (b [8]byte, err error) {     var bm [64]byte     _, err = SetImage(im, func(index, x, y int, in, out image.Image) {         rgba := readRGBAColor(im.At(x, y))         if index < 64 {             bm[index] = uint8(rgba.R & 1)         }     })     if err != nil {         return     }     var bb [8]byte     var bs []byte     for i := 0; i < 8; i++ {         bs = bm[8*i : 8*(i+1)]         for j := 0; j < 8; j++ {             bb[j] = bs[j]         }         b[i] = Bits2Byte(bb)     }     return } func ReadShadowFlag(b [8]byte) (a [4]byte) {     for i := 0; i < 4; i++ {         a[i] = b[i]     }     return } func ReadShadowLength(b [8]byte) uint32 {     var bb [4]byte     for i := 4; i < 8; i++ {         bb[i-4] = b[i]     }     return Bytes2Uint32(bb) } func OpenImage(path string) (image.Image, error) {     im_read, err := os.Open(path)     defer im_read.Close()     if err != nil {         return nil, err     }     im, _, err := image.Decode(im_read)     if err != nil {         return nil, err     }     return im, nil } //modify image func SetImage(im image.Image, f func(index, x, y int, in, out image.Image)) (out image.Image, err error) {     if f == nil {         return im, nil     }     index := 0     bounds := im.Bounds()     out = image.NewRGBA(bounds)     var m *image.RGBA = out.(*image.RGBA)     for y := bounds.Min.Y; y < bounds.Max.Y; y++ {         for x := bounds.Min.X; x < bounds.Max.X; x++ {             m.Set(x, y, im.At(x, y))             f(index, x, y, im, out)             index += 1         }     }     return out, nil } //conert any color to RABGA color. func readRGBAColor(from_color color.Color) color.RGBA {     return color.RGBAModel.Convert(from_color).(color.RGBA) } //only write to jpeg formats. func WriteImage(path string, im image.Image) error {     out, err := os.OpenFile(path, os.O_CREATE, os.ModePerm)     defer out.Close()     if err != nil {         return err     }     err = png.Encode(out, im)     if err != nil {         return err     }     return nil } var read_in string var write_out string var data string func init() {     flag.StringVar(&read_in, "in", "", "image path read in.")     flag.StringVar(&write_out, "out", "out.jpg", "image path write out.")     flag.StringVar(&data, "data", "", "data to shadow.") } func errHandle(err error) {     if err != nil {         log.Fatal(err)     } } func main() {     flag.Parse()     if read_in == "" {         fmt.Println("Options:")         flag.PrintDefaults()         return     }     im, err := OpenImage(read_in)     errHandle(err)     if data != "" {         out, err := WriteShadow([]byte(data), im)         errHandle(err)         err = WriteImage(write_out, out)         errHandle(err)     } else {         head, err := ReadShadowHeader(im)         errHandle(err)         _flag := ReadShadowFlag(head)         if _flag != FLAG {             fmt.Println("image doesn't have shadow data.")             return         }         data, err := ReadShadowData(im)         errHandle(err)         fmt.Println("shadow:", string(data))     } }
以上所述就是本文的全部内容了,希望大家能够喜欢。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部