package pixclient import ( "bufio" "errors" "net" "strconv" "strings" "image" ) type Client struct { connection net.Conn width int height int } func NewClient(addr net.IP, port int) *Client { var client Client connection, err := net.Dial("tcp", addr.String()+":"+strconv.Itoa(port)) check(err) client.connection = connection client.height, client.width = client.Size() return &client } func (Client *Client) WritePixel(x, y int, r, g, b, a byte) error { var bytes []byte if x <= 0 || y <= 0 || x >= Client.width || y >= Client.height { return errors.New("Pixel out of range.") } bytes = append(appendTwoDigitHex(appendTwoDigitHex(appendTwoDigitHex(appendTwoDigitHex(append(append(append(append(append( bytes, []byte("PX ")...), []byte(strconv.FormatInt(int64(x), 10))...), []byte(" ")...), []byte(strconv.FormatInt(int64(y), 10))...), []byte(" ")...), r), g), b), a), []byte("\n")...) Client.connection.Write(bytes) //Client.connection.Write([]byte( // fmt.Sprintf("PX %d %d %X\n", x, y, []byte{r, g, b, a}))) return nil } func (Client *Client) WriteImage(image image.Image) { bounds := image.Bounds() for x := bounds.Min.X; x < bounds.Max.X; x++ { for y := bounds.Min.Y; y < bounds.Max.Y; y++ { r, g, b, a := image.At(x, y).RGBA() Client.WritePixel(x, y, byte(r), byte(g), byte(b), byte(a)) } } } func (Client *Client) Size() (int, int) { Client.connection.Write([]byte("SIZE\n")) reader := bufio.NewReader(Client.connection) size, err := reader.ReadBytes('\n') check(err) sizeString := string(size) sizeArray := strings.Split(sizeString, " ") Client.width, err = strconv.Atoi(strings.TrimSpace(sizeArray[1])) check(err) Client.height, err = strconv.Atoi(strings.TrimSpace(sizeArray[2])) check(err) return Client.width, Client.height } func appendTwoDigitHex(bytes []byte, val byte) []byte { if val < 0x10 { bytes = append(bytes, []byte("0")...) } return strconv.AppendInt(bytes, int64(val), 16) } func check(e error) { if e != nil { panic(e) } }