func imageToDraw(i image.Image) (draw.Image, error) { switch i := i.(type) { case *image.Alpha: return draw.Image(i), nil case *image.Alpha16: return draw.Image(i), nil case *image.CMYK: return draw.Image(i), nil case *image.Gray: return draw.Image(i), nil case *image.Gray16: return draw.Image(i), nil case *image.NRGBA: return draw.Image(i), nil case *image.NRGBA64: return draw.Image(i), nil case *image.Paletted: return draw.Image(i), nil case *image.RGBA: return draw.Image(i), nil case *image.RGBA64: return draw.Image(i), nil default: return nil, fmt.Errorf("invalid image type %T", i) } }
// RotateImageLeft will rotate image 90 deg Counter Clockwise func RotateImageLeft(src image.Image) image.Image { width := src.Bounds().Size().X height := src.Bounds().Size().Y m := draw.Image(image.NewRGBA(image.Rect(0, 0, height, width))) for x := 0; x < width; x++ { for y := 0; y < width; y++ { m.Set(y, width-x, src.At(x, y)) } } return m }
// postHandler accepts POSTed revisit messages from a Revisit.link hub, // transforms the message, and returns the transformed message to the hub. // See: http://revisit.link/spec.html func (rs *RevisitService) postHandler(w http.ResponseWriter, r *http.Request) { // make sure message isn't too large payloadReadCloser := http.MaxBytesReader(w, r.Body, payloadLimit) payloadBytes, err := ioutil.ReadAll(payloadReadCloser) if err != nil { log.Errorf("error reading payload: %d", http.StatusRequestEntityTooLarge) http.Error(w, "ROTFL", http.StatusRequestEntityTooLarge) return } // decode the payload into a RevisitMsg var msg *RevisitMsg decoder := json.NewDecoder(bytes.NewReader(payloadBytes)) err = decoder.Decode(&msg) if err != nil { log.Errorf("error decoding json: %d", http.StatusUnsupportedMediaType) http.Error(w, "ROTFL", http.StatusUnsupportedMediaType) return } // construct a RevisitImage from the payload ri, err := NewRevisitImageFromMsg(msg) if err != nil { log.Errorf("error decoding json: %d", http.StatusUnsupportedMediaType) http.Error(w, "ROTFL", http.StatusUnsupportedMediaType) return } // for each image frame (only 1 if jpeg or png), call the glitcher for _, rgba := range ri.Rgbas { rs.glitcher(draw.Image(&rgba)) } // create a new message from the modified image newMsg, err := ri.RevisitMsg() if err != nil { log.Errorf("error decoding json: %d", http.StatusInternalServerError) http.Error(w, "ROTFL", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) enc.Encode(newMsg) }
func (g *Gui) Run(tsEvent *chan touchscreen.TouchscreenEvent) { oldEvent := touchscreen.TouchscreenEvent{touchscreen.TSEVENT_NULL, 0, 0} for { select { case e := <-*tsEvent: if e.Type == touchscreen.TSEVENT_PUSH { if oldEvent != e { if g.timeout > DISPLAY_TIMEOUT { g.dirty <- true } else { g.processButtonsOfPage(e, g.mainPage) g.processButtonsOfPage(e, g.pages[g.activePageName]) } g.timeout = 0 oldEvent = e } } else { oldEvent = touchscreen.TouchscreenEvent{touchscreen.TSEVENT_NULL, 0, 0} } case <-g.dirty: if g.timeout > DISPLAY_TIMEOUT { draw.Draw(*g.target, g.Bounds, image.NewUniform(image.Black), image.ZP, draw.Src) } else { doubleBuffer := draw.Image(image.NewRGBA(g.Bounds)) mainPage := g.mainPage if mainPage != nil { (*mainPage).Draw(&doubleBuffer) } currentPage := g.pages[g.activePageName] if currentPage != nil { (*currentPage).Draw(&doubleBuffer) } draw.Draw(*g.target, doubleBuffer.Bounds(), doubleBuffer, image.ZP, draw.Src) } } } }
func drawImage(sampleRate float64, spectraChan chan []float64) (img_ image.Image) { var spectra [][]float64 max := 0.0 os.Stdout.Sync() for spectrum := range spectraChan { //spectrum = spectrum[:MaxNumFreqs] for i, x := range spectrum { x = math.Log(x) spectrum[i] = x max = math.Max(max, x) } spectra = append(spectra, spectrum) if len(spectra)%20 == 0 { fmt.Printf("\rCalculating spectra... %d ", len(spectra)) os.Stdout.Sync() } } imageWidth := len(spectra) imageHeight := len(spectra[0]) img := draw.Image(image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))) for x := 0; x < imageWidth; x++ { if x%20 == 0 { fmt.Printf("\rDrawing image... %.1f%% ", (float64(x)/float64(imageWidth))*100) os.Stdout.Sync() } for y := 0; y < imageHeight; y++ { value := spectra[x][y] / max red := uint8((1.0 - value) * 0xff) green := uint8(value * 0xff) c := color.RGBA{red, green, 0, 0xff} img.Set(x, y, c) } } return img }
// NewWith returns a new image canvas created according to the specified // options. The currently accepted options are UseWH, // UseDPI, UseImage, and UseImageWithContext. // Each of the options specifies the size of the canvas (UseWH, UseImage), // the resolution of the canvas (UseDPI), or both (useImageWithContext). // If size or resolution are not specified, defaults are used. // It panics if size and resolution are overspecified (i.e., too many options are // passed). func NewWith(o ...option) *Canvas { c := new(Canvas) var g uint32 for _, opt := range o { f := opt(c) if g&f != 0 { panic("incompatible options") } g |= f } if c.dpi == 0 { c.dpi = DefaultDPI } if c.w == 0 { // h should also == 0. if c.img == nil { c.w = DefaultWidth c.h = DefaultHeight } else { w := float64(c.img.Bounds().Max.X - c.img.Bounds().Min.X) h := float64(c.img.Bounds().Max.Y - c.img.Bounds().Min.Y) c.w = vg.Length(w/float64(c.dpi)) * vg.Inch c.h = vg.Length(h/float64(c.dpi)) * vg.Inch } } if c.img == nil { w := c.w / vg.Inch * vg.Length(c.dpi) h := c.h / vg.Inch * vg.Length(c.dpi) c.img = draw.Image(image.NewRGBA(image.Rect(0, 0, int(w+0.5), int(h+0.5)))) } if c.gc == nil { h := float64(c.img.Bounds().Max.Y - c.img.Bounds().Min.Y) c.gc = draw2dimg.NewGraphicContext(c.img) c.gc.SetDPI(c.dpi) c.gc.Scale(1, -1) c.gc.Translate(0, -h) } draw.Draw(c.img, c.img.Bounds(), image.White, image.ZP, draw.Src) c.color = []color.Color{color.Black} vg.Initialize(c) return c }
// benchGlyph benchmarks rasterizing a TrueType glyph. // // Note that, compared to the github.com/google/font-go prototype, the height // here is the height of the bounding box, not the pixels per em used to scale // a glyph's vectors. A height of 64 corresponds to a ppem greater than 64. func benchGlyph(b *testing.B, colorModel byte, loose bool, height int, op draw.Op) { width, data := scaledBenchmarkGlyphData(height) z := NewRasterizer(width, height) bounds := z.Bounds() if loose { bounds.Max.X++ } dst, src := draw.Image(nil), image.Image(nil) switch colorModel { case 'A': dst = image.NewAlpha(bounds) src = image.Opaque case 'N': dst = image.NewNRGBA(bounds) src = image.NewUniform(color.NRGBA{0x40, 0x80, 0xc0, 0xff}) case 'R': dst = image.NewRGBA(bounds) src = image.NewUniform(color.RGBA{0x40, 0x80, 0xc0, 0xff}) default: b.Fatal("unsupported color model") } bounds = z.Bounds() b.ResetTimer() for i := 0; i < b.N; i++ { z.Reset(width, height) z.DrawOp = op for _, d := range data { switch d.n { case 0: z.MoveTo(d.px, d.py) case 1: z.LineTo(d.px, d.py) case 2: z.QuadTo(d.px, d.py, d.qx, d.qy) } } z.Draw(dst, bounds, src, image.Point{}) } }
func (ri *RevisitImage) Transform(t func(src draw.Image)) { for _, frame := range ri.Rgbas { t(draw.Image(&frame)) } }