Skip to content

Instantly share code, notes, and snippets.

@jan4984
Created January 26, 2018 14:11
Show Gist options
  • Save jan4984/5d11acb3d9b8ce3d3c5a37c82c5035db to your computer and use it in GitHub Desktop.
Save jan4984/5d11acb3d9b8ce3d3c5a37c82c5035db to your computer and use it in GitHub Desktop.
encode/decode binary data in bitmap
package main
import (
"image"
"os"
"io/ioutil"
"math"
"golang.org/x/image/bmp"
"log"
"bytes"
"fmt"
"image/color"
)
func main(){
if os.Args[1] == "e" {
encode()
}else{
decode()
}
}
func decode(){
data,err:=ioutil.ReadFile(os.Args[2])
if err != nil {
panic(err)
}
outFile, err := os.Create("out.data")
if err != nil {
panic(err)
}
defer outFile.Close()
img, err:=bmp.Decode(bytes.NewBuffer(data))
if err != nil {
panic(err)
}
rgba:=img.(*image.RGBA)
wh:=img.Bounds().Max.X
log.Println("width,height:",wh)
bytesLen:=uint32(0)
c:=rgba.RGBAAt(0,wh-1)
bytesLen|=uint32(c.R)
bytesLen|=uint32(c.G)<<8
//log.Println(c.R,c.G)
c=rgba.RGBAAt(1,wh-1)
bytesLen|=uint32(c.R)<<16
bytesLen|=uint32(c.G)<<24
//log.Println(c.R,c.G)
log.Println(fmt.Sprintf("bytes:0x%x",bytesLen))
buf:=make([]byte, wh*wh*2)
i:=0
for y:=wh-1;y>=0;y--{
for x:=2;x<wh;x++{
c:=rgba.RGBAAt(x,y)
buf[i]=c.R
buf[i+1]=c.G
i+=2
}
}
_,err=outFile.Write(buf[:bytesLen])
if err != nil {
panic(err)
}
}
func encode(){
data,err:=ioutil.ReadFile(os.Args[2])
if err != nil {
panic(err)
}
outFile, err := os.Create("out.bmp")
if err != nil {
panic(err)
}
defer outFile.Close()
realBytesLen := len(data)
log.Println(fmt.Sprintf("bytes:0x%x",realBytesLen))
dataPoints:=(realBytesLen+ 1) / 2 + 2//+1 for align +4 for length info
sqrtF := math.Sqrt(float64(dataPoints))
wh := int(sqrtF+1)
log.Println("width,height:",wh, wh * wh * 2)
data=append(data,make([]byte, wh*wh*2-realBytesLen)...)
rgba := image.NewRGBA(image.Rect(0,0,wh,wh))
log.Println("bmp bytes:", len(rgba.Pix))
rgba.SetRGBA(0,wh-1,color.RGBA{
R:uint8(realBytesLen&0xFF),
G:uint8((realBytesLen&0xFF00)>>8),
})
rgba.SetRGBA(1,wh-1,color.RGBA{
R:uint8((realBytesLen&0xFF0000)>>16),
G:uint8((realBytesLen&0xFF000000)>>24),
})
i:=0
for y:=wh-1;y>=0;y--{
for x:=2;x<wh;x++{
rgba.SetRGBA(x,y,color.RGBA{
R:data[i],
G:data[i+1],
})
i+=2
}
}
err = bmp.Encode(outFile, rgba)
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment