Stuff about the Divoom Timebox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
2.4KB

  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "image"
  6. _ "image/png"
  7. "io/ioutil"
  8. "log"
  9. "math"
  10. "os"
  11. "github.com/bakerolls/nibble"
  12. )
  13. func main() {
  14. // c := &serial.Config{Name: "/dev/cu.TimeBox-audio-SerialPor", Baud: 9600}
  15. // p, err := serial.OpenPort(c)
  16. // if err != nil {
  17. // log.Fatal(err)
  18. // }
  19. // defer p.Close()
  20. r, err := os.Open(os.Args[1])
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. defer r.Close()
  25. img, _, err := image.Decode(r)
  26. if err != nil {
  27. log.Fatal(err)
  28. }
  29. bs, err := draw(img)
  30. if err != nil {
  31. log.Fatal(err)
  32. }
  33. for _, b := range bs {
  34. fmt.Printf("%02x ", b)
  35. }
  36. fmt.Println()
  37. // if _, err := p.Write(fill(255, 0, 0)); err != nil {
  38. // log.Fatal(err)
  39. // }
  40. // time.Sleep(5 * time.Second)
  41. }
  42. func draw(img image.Image) ([]byte, error) {
  43. prefix := []byte{0xbd, 0x00, 0x44, 0x00, 0x0a, 0x0a, 0x04}
  44. var buff bytes.Buffer
  45. nw := nibble.New(&buff)
  46. b := img.Bounds()
  47. for y := b.Min.Y; y < b.Max.Y; y++ {
  48. for x := b.Min.X; x < b.Max.X; x++ {
  49. r, g, b, _ := img.At(x, y).RGBA()
  50. data := []byte{
  51. uint8(r / (math.MaxUint8 + 1)),
  52. uint8(g / (math.MaxUint8 + 1)),
  53. uint8(b / (math.MaxUint8 + 1)),
  54. }
  55. if _, err := nw.Write(data); err != nil {
  56. return nil, err
  57. }
  58. }
  59. }
  60. if _, err := nw.Flush(); err != nil {
  61. return nil, err
  62. }
  63. data, err := ioutil.ReadAll(&buff)
  64. if err != nil {
  65. return nil, err
  66. }
  67. var sum int16
  68. for _, b := range prefix {
  69. sum += int16(b)
  70. }
  71. for _, b := range data {
  72. sum += int16(b)
  73. }
  74. postfix := []byte{byte(sum & 0x00ff), byte(sum >> 8)}
  75. var res []byte
  76. res = append(res, 0x01)
  77. res = append(res, prefix...)
  78. res = append(res, data...)
  79. res = append(res, postfix...)
  80. res = append(res, 0x02)
  81. return res, nil
  82. }
  83. func fill(r, g, b uint8) []byte {
  84. prefix := []byte{0xbd, 0x00, 0x44, 0x00, 0x0a, 0x0a, 0x04}
  85. rows, cols := 11, 11
  86. data := make([]byte, int(math.Ceil(float64(rows*cols)+float64(rows*cols)/2)))
  87. for i := 0; i < len(data)/3; i++ {
  88. r2, g2, b2 := uint8(r/16), uint8(g/16), uint8(b/16)
  89. data[i*3+0] = byte(r2&0x0f + g2<<4)
  90. data[i*3+1] = byte(b2&0x0f + r2<<4)
  91. data[i*3+2] = byte(g2&0x0f + b2<<4)
  92. }
  93. var sum int16
  94. for _, b := range prefix {
  95. sum += int16(b)
  96. }
  97. for _, b := range data {
  98. sum += int16(b)
  99. }
  100. postfix := []byte{byte(sum & 0x00ff), byte(sum >> 8)}
  101. var res []byte
  102. res = append(res, 0x01)
  103. res = append(res, prefix...)
  104. res = append(res, data...)
  105. res = append(res, postfix...)
  106. res = append(res, 0x02)
  107. return res
  108. }