Exemplo n.º 1
0
// Generate a text string to a QR code, which you can write to a terminal or file.
func (c *Config) Generate(text string) (string, error) {
	code, err := qr.Encode(text, qr.Level(c.Level))
	if err != nil {
		return "", err
	}

	// calculate size in blocks
	// two bits per block
	// add one block for remaining singlebit (if existing)
	// add two blocks for border left and right
	size := code.Size/2 + (code.Size % 2) + 2

	// rune slice
	//++ TODO: precalculate size
	qrRunes := make([]rune, 0)

	// upper border
	c.addWhiteRow(&qrRunes, size)

	// content
	for y := 0; y < code.Size; y += 2 {
		if c.UseSGR {
			qrRunes = append(qrRunes, []rune(sgr.FgWhite+sgr.BgBlack)...)
		}
		qrRunes = append(qrRunes, '█')
		for x := 0; x < code.Size; x += 2 {
			var num int8
			if !code.Black(x, y) {
				num += 1
			}
			if !code.Black(x+1, y) {
				num += 2
			}
			if !code.Black(x, y+1) {
				num += 4
			}
			if !code.Black(x+1, y+1) {
				num += 8
			}
			qrRunes = append(qrRunes, blocks[num])
		}
		qrRunes = append(qrRunes, '█')
		if c.UseSGR {
			qrRunes = append(qrRunes, []rune(sgr.Reset)...)
		}
		qrRunes = append(qrRunes, '\n')
	}

	// add lower border when required (only required when QR size is odd)
	if code.Size%2 == 0 {
		c.addWhiteRow(&qrRunes, size)
	}

	return string(qrRunes), nil
}
Exemplo n.º 2
0
// GenerateQR generates a for the receiver *Request.
func (r *Request) GenerateQR() (*qr.Code, error) {
	// get config for this request
	c := r.Config
	if c == nil {
		c = DefaultConfig
	}

	var err error

	// uriBuf will contain the bytes that are to be encoded into the QR code
	uriBuf := &bytes.Buffer{}

	// write uri scheme
	_, err = uriBuf.WriteString(c.scheme())
	if err != nil {
		return nil, err
	}

	// write uri seperator colon
	err = uriBuf.WriteByte(':')
	if err != nil {
		return nil, err
	}

	// write receiving address
	_, err = uriBuf.WriteString(r.Address)
	if err != nil {
		return nil, err
	}

	// params contains optional parameters used in the URI
	var params = make(map[string]string)

	// add amount when not zero
	if r.Amount < 0 {
		return nil, ErrNegativeAmount
	}
	if r.Amount != 0 {
		params["amount"] = strconv.FormatFloat(r.Amount, 'f', -1, 64)
		if err != nil {
			return nil, err
		}
	}

	// add label when it is not empty
	if len(r.Label) != 0 {
		params["label"] = url.QueryEscape(r.Label)
	}

	// add message when it is not empty
	if len(r.Message) != 0 {
		params["message"] = url.QueryEscape(r.Message)
	}

	// add query escaped params (if any)
	if r.Params != nil {
		for key, value := range r.Params {
			params[url.QueryEscape(key)] = url.QueryEscape(value)
		}
	}

	// write all parameters to the uriBuf
	q := true
	for key, value := range params {
		// write '?' or '&' to uriBuf
		if q {
			q = false
			err = uriBuf.WriteByte('?')
			if err != nil {
				return nil, err
			}
		} else {
			err = uriBuf.WriteByte('&')
			if err != nil {
				return nil, err
			}
		}

		// write <key>=<value> to uriBuf
		_, err = uriBuf.WriteString(key)
		if err != nil {
			return nil, err
		}
		err = uriBuf.WriteByte('=')
		if err != nil {
			return nil, err
		}
		_, err = uriBuf.WriteString(value)
		if err != nil {
			return nil, err
		}
	}

	// create qr image
	code, err := qr.Encode(uriBuf.String(), qr.Level(c.Level))
	if err != nil {
		return nil, err
	}

	// all done
	return code, nil
}