package meowlib import ( "bytes" "compress/gzip" "fmt" "image" "image/color" "image/png" "io" "log" "math" "os" "github.com/makiuchi-d/gozxing" "github.com/makiuchi-d/gozxing/qrcode" "google.golang.org/protobuf/proto" ) func ServerFromUrl(url string) *ServerCard { var s ServerCard s.Url = url return &s } func (Contact *ContactCard) AddUrls(urls []string) { for _, url := range urls { Contact.PullServers = append(Contact.PullServers, ServerFromUrl(url)) } } func (contact *ContactCard) Serialize() ([]byte, error) { out, err := proto.Marshal(contact) if err != nil { return nil, err } return out, nil } func (contact *ContactCard) Compress() ([]byte, error) { out, err := contact.Serialize() if err != nil { return nil, err } var b bytes.Buffer gz, err := gzip.NewWriterLevel(&b, gzip.BestCompression) if err != nil { return nil, err } if _, err := gz.Write(out); err != nil { return nil, err } if err := gz.Close(); err != nil { return nil, err } return b.Bytes(), nil } func (contact *ContactCard) Split(parts uint8) (packets [][]byte, err error) { data, err := contact.Compress() if err != nil { return nil, err } return BufferSplit(data, parts) } func NewContactCardFromCompressed(compressed []byte) (*ContactCard, error) { cc := &ContactCard{} reader := bytes.NewReader([]byte(compressed)) gzreader, err := gzip.NewReader(reader) if err != nil { return nil, err } output, err := io.ReadAll(gzreader) if err != nil { return nil, err } if err := proto.Unmarshal(output, cc); err != nil { return nil, err } return cc, nil } func NewContactCardFromSplit(packets [][]byte) (*ContactCard, error) { data, err := BufferMerge(packets) if err != nil { return nil, err } return NewContactCardFromCompressed(data) } func (contact *ContactCard) WriteCompressed(filename string) error { out, err := contact.Compress() if err != nil { return err } err = os.WriteFile(filename, out, 0600) if err != nil { return err } return nil } func (contact *ContactCard) WritePng(filename string) { out, err := proto.Marshal(contact) if err != nil { println(err) } size := int(math.Sqrt(float64(len(out))/3)) + 1 println(size) // Create a colored i mage of the given width and height. img := image.NewNRGBA(image.Rect(0, 0, size, size)) for y := 0; y < size; y++ { for x := 0; x < size*3; x = x + 3 { p1 := uint8(out[x+y]) p2 := uint8(out[x+y+1]) p3 := uint8(out[x+y+2]) img.Set(x/3, y, color.NRGBA{ R: p1, G: p2, B: p3, A: 255, }) } } f, err := os.Create(filename) if err != nil { log.Fatal(err) } if err := png.Encode(f, img); err != nil { f.Close() log.Fatal(err) } if err := f.Close(); err != nil { log.Fatal(err) } } func (Contact *ContactCard) WriteQr(filename string) error { //jsonContact, _ := json.Marshal(Contact) jsonContact, _ := Contact.Compress() qwriter := qrcode.NewQRCodeWriter() code, err := qwriter.Encode(string(jsonContact), gozxing.BarcodeFormat_QR_CODE, 512, 512, nil) if err != nil { return err } file, _ := os.Create(filename) defer file.Close() // *BitMatrix implements the image.Image interface, // so it is able to be passed to png.Encode directly. _ = png.Encode(file, code) return nil } func ReadQr(filename string) *ContactCard { var contact ContactCard // open and decode image file file, _ := os.Open(filename) img, _, _ := image.Decode(file) // prepare BinaryBitmap bmp, _ := gozxing.NewBinaryBitmapFromImage(img) // decode image qrReader := qrcode.NewQRCodeReader() result, _ := qrReader.Decode(bmp, nil) fmt.Println(result) return &contact }