亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

go語言實現將重要數據寫入圖片中

2020-04-01 19:15:35
字體:
來源:轉載
供稿:網友
本文給大家分享的是go語言實現將數據的二進制形式寫入圖像紅色通道數據二進制的低位,從而實現將重要數據隱藏,有需要的小伙伴參考下吧。
 

原理:將數據的二進制形式寫入圖像紅色通道數據二進制的低位
只支持png格式的輸出
寫入數據
go run shadow.go -in="c.jpg" -data="hide me" -out="out.png"
讀取數據
go run shadow.go -in="out.png"

 

復制代碼代碼如下:

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))
    }
}

 

以上所述就是本文的全部內容了,希望大家能夠喜歡。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品视频成人| 日韩成人在线免费观看| 国产亚洲精品美女久久久久| www.99久久热国产日韩欧美.com| 欧美成人手机在线| 欧美日韩国产丝袜另类| 97香蕉久久超级碰碰高清版| 97免费视频在线| 欧美激情免费观看| 亚洲欧美国产另类| 亚洲成色999久久网站| 国产日韩欧美黄色| 国产精品久久久久久久av电影| 国产欧美欧洲在线观看| 亚洲人成电影网站色www| 国产欧美精品一区二区| 欧美高清理论片| 国产福利精品av综合导导航| 欧美黑人国产人伦爽爽爽| 日本精品免费观看| 中文在线资源观看视频网站免费不卡| 久久中文字幕视频| 97在线观看视频国产| 国产精品女人网站| 成人精品网站在线观看| 国产成+人+综合+亚洲欧美丁香花| 久久亚洲精品成人| 欧美高清在线观看| 亚洲色图欧美制服丝袜另类第一页| 欧美激情视频免费观看| 成人自拍性视频| 欧美在线视频观看免费网站| 91在线免费网站| 亚洲成年人在线| 日韩网站免费观看| 国产精品美女www爽爽爽视频| 亚洲国产91精品在线观看| 欧美激情综合色| 国产精品久久久| 久久香蕉国产线看观看av| 欧美激情videoshd| 亚洲www永久成人夜色| 亚洲精品国精品久久99热| 欧美国产第二页| 亚洲精品国产精品自产a区红杏吧| 92国产精品久久久久首页| 久久久国产视频| 欧美在线视频观看免费网站| 中文字幕亚洲一区在线观看| 国产激情综合五月久久| 亚洲国产精品成人va在线观看| 久久精品亚洲94久久精品| 欧美成人剧情片在线观看| 久久久中精品2020中文| 2019中文字幕免费视频| 亚洲一区二区三区四区在线播放| 国产精品国产三级国产aⅴ9色| 欧美高清一级大片| 亚洲欧美国产精品| 欧美亚洲成人免费| 亚洲天堂久久av| 日韩中文视频免费在线观看| 亚洲成人网久久久| 欧美激情精品久久久久久变态| 日本免费在线精品| 欧美巨乳在线观看| 欧美成人免费大片| 亚洲欧美日韩网| 亚洲福利在线观看| 精品国产999| 亚洲综合在线中文字幕| 这里只有精品在线观看| 亚洲男人第一av网站| 久久精品视频免费播放| 日韩国产欧美精品在线| 亚洲18私人小影院| 亚洲无亚洲人成网站77777| 欧美xxxx做受欧美| 尤物精品国产第一福利三区| 97在线免费视频| x99av成人免费| 伊人伊成久久人综合网小说| 久久免费视频在线观看| 美日韩精品免费观看视频| 中文字幕精品在线| 亚洲xxxx3d| 亚洲一区制服诱惑| 精品人伦一区二区三区蜜桃免费| 97在线免费视频| 国产精品久久久久7777婷婷| 久久久久中文字幕2018| 日本亚洲欧美三级| 亚洲欧美资源在线| 高清亚洲成在人网站天堂| 欧美日韩在线视频一区| www.美女亚洲精品| 欧美巨猛xxxx猛交黑人97人| 欧美夫妻性生活视频| 久久综合伊人77777| 国产精品极品在线| 欧美理论电影网| 国产亚洲欧美日韩美女| 日本高清不卡的在线| 国产视频丨精品|在线观看| 亚洲四色影视在线观看| 亚洲18私人小影院| 国内精品小视频在线观看| 精品偷拍一区二区三区在线看| 国产精品亚洲网站| 国产mv久久久| 91精品视频专区| 久久97久久97精品免视看| 久久免费视频观看| 68精品国产免费久久久久久婷婷| 欧美怡红院视频一区二区三区| 国产精品一久久香蕉国产线看观看| 亚洲一区999| 欧美精品久久一区二区| 国产美女直播视频一区| 色阁综合伊人av| 精品亚洲男同gayvideo网站| 国产精品高清在线观看| 亚洲精品欧美一区二区三区| 亚洲无限乱码一二三四麻| 国产精品一区二区在线| 久久躁日日躁aaaaxxxx| 国产精品爱久久久久久久| 久久99久国产精品黄毛片入口| 中文字幕亚洲一区二区三区五十路| 精品一区二区三区三区| 亚洲电影免费观看高清完整版| 国产日韩在线视频| 亚洲图片在区色| 国产精品中文字幕久久久| 国产亚洲精品美女| 国产精品亚洲片夜色在线| 成人午夜高潮视频| 国产精品旅馆在线| 日韩精品久久久久久福利| 国产亚洲精品久久久优势| 欧美国产中文字幕| 欧美体内谢she精2性欧美| 日本欧美精品在线| 亚洲精品一区二区三区婷婷月| 亚洲在线第一页| 国产精品一久久香蕉国产线看观看| 国产精品99久久久久久人| 国产欧美精品一区二区三区-老狼| 91在线免费网站| 日韩电影视频免费| 热久久99这里有精品| 亚洲色图在线观看| 国产午夜一区二区| 亚洲国产精品一区二区三区| 亚洲欧洲中文天堂| 97香蕉超级碰碰久久免费软件| 日韩av中文字幕在线| 777777777亚洲妇女| 欧美激情第三页| 欧美精品在线第一页| 中文日韩在线观看| 视频在线观看一区二区| 久久精品中文字幕免费mv| 国产精品电影一区|