Principle: Writes the binary form of the data to the image red channel data binary low
supports only output in PNG format
Write Data
Go run shadow.go-in= "c.jpg"-data= "Hide Me"-out= "Out.png"
Reading data
Go run shadow.go-in= "Out.png"
Copy Code code as follows:
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 >> & 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 spaces 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 >= && 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))
}
}
The above mentioned is the entire content of this article, I hope you can enjoy.