//水印 func waterMark(picBytes []byte) []byte { // 打开水印图并解码 img, fileType, _ := image.Decode(bytes.NewBuffer(picBytes)) //读取水印图片 watermark, _ := png.Decode(bytes.NewBuffer(wm)) //原始图界限 origin_size := img.Bounds() //创建新图层 canvas := image.NewNRGBA(origin_size) //贴原始图 draw.Draw(canvas, origin_size, img, image.ZP, draw.Src) //贴水印图 draw.Draw(canvas, watermark.Bounds().Add(image.Pt(origin_size.Dx()-watermark.Bounds().Dx(), origin_size.Dy()-watermark.Bounds().Dy()-4)), watermark, image.ZP, draw.Over) //生成新图片 buff := bytes.NewBuffer([]byte{}) switch fileType { case "jpeg": jpeg.Encode(buff, canvas, &jpeg.Options{95}) default: png.Encode(buff, canvas) } return buff.Bytes() }
// Sets skin.Processed to an isometric render of the head from a top-left angle (showing 3 sides). func (skin *mcSkin) GetCube(width int) error { // Crop out the top of the head topFlat := imaging.Crop(skin.Image, image.Rect(8, 0, 16, 8)) // Resize appropriately, so that it fills the `width` when rotated 45 def. topFlat = imaging.Resize(topFlat, int(float64(width)*math.Sqrt(2)/3+1), 0, imaging.NearestNeighbor) // Create the Gift filter filter := gift.New( gift.Rotate(45, color.Transparent, gift.LinearInterpolation), ) bounds := filter.Bounds(topFlat.Bounds()) top := image.NewNRGBA(bounds) // Draw it on the filter, then smush it! filter.Draw(top, topFlat) top = imaging.Resize(top, width+2, width/3, imaging.NearestNeighbor) // Skew the front and sides at 15 degree angles to match up with the // head that has been smushed front := skin.cropHead(skin.Image).(*image.NRGBA) side := imaging.Crop(skin.Image, image.Rect(0, 8, 8, 16)) front = imaging.Resize(front, width/2, int(float64(width)/1.75), imaging.NearestNeighbor) side = imaging.Resize(side, width/2, int(float64(width)/1.75), imaging.NearestNeighbor) front = skewVertical(front, math.Pi/12) side = skewVertical(imaging.FlipH(side), math.Pi/-12) // Create a new image to assemble upon skin.Processed = image.NewNRGBA(image.Rect(0, 0, width, width)) // Draw each side draw.Draw(skin.Processed.(draw.Image), image.Rect(0, width/6, width/2, width), side, image.Pt(0, 0), draw.Src) draw.Draw(skin.Processed.(draw.Image), image.Rect(width/2, width/6, width, width), front, image.Pt(0, 0), draw.Src) // Draw the top we created draw.Draw(skin.Processed.(draw.Image), image.Rect(-1, 0, width+1, width/3), top, image.Pt(0, 0), draw.Over) return nil }
func rotate(im image.Image, angle int) image.Image { var rotated *image.NRGBA // trigonometric (i.e counter clock-wise) switch angle { case 90: newH, newW := im.Bounds().Dx(), im.Bounds().Dy() rotated = image.NewNRGBA(image.Rect(0, 0, newW, newH)) for y := 0; y < newH; y++ { for x := 0; x < newW; x++ { rotated.Set(x, y, im.At(newH-1-y, x)) } } case -90: newH, newW := im.Bounds().Dx(), im.Bounds().Dy() rotated = image.NewNRGBA(image.Rect(0, 0, newW, newH)) for y := 0; y < newH; y++ { for x := 0; x < newW; x++ { rotated.Set(x, y, im.At(y, newW-1-x)) } } case 180, -180: newW, newH := im.Bounds().Dx(), im.Bounds().Dy() rotated = image.NewNRGBA(image.Rect(0, 0, newW, newH)) for y := 0; y < newH; y++ { for x := 0; x < newW; x++ { rotated.Set(x, y, im.At(newW-1-x, newH-1-y)) } } default: return im } return rotated }
func (this *Signer) GetMoreLineImage(text string, text_color image.Image, l int, fix_top, fix_bottom int) (image.Image, error) { r := image.Rect(0, 0, 414, 96) img := image.NewNRGBA(r) c := freetype.NewContext() c.SetDPI(this.Dpi) c.SetFont(this.font) c.SetFontSize(this.FontSize) c.SetClip(img.Bounds()) c.SetDst(img) c.SetSrc(text_color) //pt := freetype.Pt(0, 0) pt := freetype.Pt(0, 0+int(c.PointToFix32(this.FontSize)>>8)) var err error limit := c.PixToFix32(l) str := strings.Split(text, "\r\n") for i, s := range str { pt, err = c.DrawString(s, pt, limit) if err != nil { fmt.Println("c.DrawString(%s) error(%v)", s, err) return nil, err } if i < len(str)-1 { pt.Y += c.PointToFix32(this.FontSize * 1.5) } } x, y := l, c.Fix32ToPix(pt.Y) sub_r := image.Rect(0, 0, x+20, y+(fix_bottom-fix_top)) sub_img := image.NewNRGBA(sub_r) draw.Draw(sub_img, sub_r, img, image.Point{0, fix_top}, draw.Src) return sub_img, nil }
// imgの片方の辺をずらして変形する // (option=trueで縦/falseで横に伸ばす/option2=trueで左上固定/falseで右下固定) // _ _ // | | → / / //  ̄  ̄ // func Slide(img *image.Image, length int, option bool, option2 bool) image.Image { size := (*img).Bounds().Size() //横を伸ばす場合は横の長さがx+x/lenになる img2 := image.NewNRGBA(image.Rect(0, 0, size.X+int(float64(size.X)/float64(length)), size.Y)) if option { //縦を伸ばす場合は縦の長さがx+x/lenになる img2 = image.NewNRGBA(image.Rect(0, 0, size.X, size.Y+int(float64(size.Y)/float64(length)))) } size2 := (*img2).Bounds().Size() //統一で扱うために長い方を取得 sizeB := size2.Y if size2.X > size2.Y { sizeB = size2.X } offset := 0 for x, x2 := 0, 0; x < sizeB; x++ { //逆スタートの場合は反転 x2 = x if option2 { if option { x2 = size2.X - x } else { x2 = size2.Y - x } } for y, y2 := 0, 0; y < sizeB; y++ { //逆スタートの場合は反転 y2 = y if option2 { if option { y2 = size2.Y - y } else { y2 = size2.X - y } } c := (*img).At(x2, y2) r, g, b, _ := c.RGBA() if !(r == 0 && g == 0 && b == 0) { //縦横の入れ替えの場合 if option { img2.Set(x2, y2+offset, c) } else { img2.Set(y2+offset, x2, c) } } } //ずらす分 if x2%length == 0 { offset++ } } return img2 }
func BenchmarkPCompare(b *testing.B) { m1 := image.NewNRGBA(image.Rect(0, 0, 100, 100)) m2 := image.NewNRGBA(image.Rect(0, 0, 100, 100)) d := NewDefaultPerceptual() b.RunParallel(func(pb *testing.PB) { for pb.Next() { d.Compare(m1, m2) } }) }
func TestEncodeDecode(t *testing.T) { imgWithAlpha := image.NewNRGBA(image.Rect(0, 0, 3, 3)) imgWithAlpha.Pix = []uint8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 244, 245, 246, 247, 248, 249, 250, 252, 252, 253, 254, 255, } imgWithoutAlpha := image.NewNRGBA(image.Rect(0, 0, 3, 3)) imgWithoutAlpha.Pix = []uint8{ 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 10, 255, 127, 128, 129, 255, 131, 132, 133, 255, 135, 136, 137, 255, 244, 245, 246, 255, 248, 249, 250, 255, 252, 253, 254, 255, } for _, format := range []Format{JPEG, PNG, GIF, BMP, TIFF} { img := imgWithoutAlpha if format == PNG { img = imgWithAlpha } buf := &bytes.Buffer{} err := Encode(buf, img, format) if err != nil { t.Errorf("fail encoding format %s", format) continue } img2, err := Decode(buf) if err != nil { t.Errorf("fail decoding format %s", format) continue } img2cloned := Clone(img2) delta := 0 if format == JPEG { delta = 3 } else if format == GIF { delta = 16 } if !compareNRGBA(img, img2cloned, delta) { t.Errorf("test [DecodeEncode %s] failed: %#v %#v", format, img, img2cloned) continue } } buf := &bytes.Buffer{} err := Encode(buf, imgWithAlpha, Format(100)) if err != ErrUnsupportedFormat { t.Errorf("expected ErrUnsupportedFormat") } }
func TestNrgbaPlanes(t *testing.T) { w, h := 256, 256 src := readImage(t, "testdata/nrgba.png") ref := image.NewNRGBA(src.Bounds()) err := Convert(ref, src, nil) expect(t, err, nil) raw := image.NewNRGBA(image.Rect(0, 0, w*2, h*2)) dst := raw.SubImage(image.Rect(7, 7, 7+w, 7+h)) err = Convert(dst, src, NewBicubicFilter()) expect(t, err, nil) err = Convert(src, dst, NewBicubicFilter()) expect(t, err, nil) checkPsnrs(t, ref, src, image.Rectangle{}, []float64{39}) }
func NewImageOfTypeRect(src image.Image, bounds image.Rectangle) image.Image { switch i := src.(type) { case *image.Alpha: return image.NewAlpha(bounds) case *image.Alpha16: return image.NewAlpha16(bounds) case *image.Gray: return image.NewGray(bounds) case *image.Gray16: return image.NewGray16(bounds) case *image.NRGBA: return image.NewNRGBA(bounds) case *image.NRGBA64: return image.NewNRGBA64(bounds) case *image.Paletted: return image.NewPaletted(bounds, i.Palette) case *image.RGBA: return image.NewRGBA(bounds) case *image.RGBA64: return image.NewRGBA64(bounds) case *image.YCbCr: return image.NewYCbCr(bounds, i.SubsampleRatio) } panic("Unknown image type") }
func (t testTransport) RoundTrip(req *http.Request) (*http.Response, error) { var raw string switch req.URL.Path { case "/ok": raw = "HTTP/1.1 200 OK\n\n" case "/error": return nil, errors.New("http protocol error") case "/nocontent": raw = "HTTP/1.1 204 No Content\n\n" case "/etag": raw = "HTTP/1.1 200 OK\nEtag: \"tag\"\n\n" case "/png": m := image.NewNRGBA(image.Rect(0, 0, 1, 1)) img := new(bytes.Buffer) png.Encode(img, m) raw = fmt.Sprintf("HTTP/1.1 200 OK\nContent-Length: %d\n\n%s", len(img.Bytes()), img.Bytes()) default: raw = "HTTP/1.1 404 Not Found\n\n" } buf := bufio.NewReader(bytes.NewBufferString(raw)) return http.ReadResponse(buf, req) }
func createSwatch(col color.Color, size int) image.Image { log.Printf("Creating swatch for %v\n", col) bounds := image.Rect(0, 0, size, size) img := image.NewNRGBA(bounds) draw.Draw(img, img.Bounds(), image.NewUniform(col), img.Bounds().Min, draw.Src) return img }
// cut out the image and return individual channels with image.Image // no encoding of JPEG func cut(original image.Image, db *map[string][3]float64, tileSize, x1, y1, x2, y2 int) <-chan image.Image { c := make(chan image.Image) sp := image.Point{0, 0} go func() { newimage := image.NewNRGBA(image.Rect(x1, y1, x2, y2)) for y := y1; y < y2; y = y + tileSize { for x := x1; x < x2; x = x + tileSize { r, g, b, _ := original.At(x, y).RGBA() color := [3]float64{float64(r), float64(g), float64(b)} nearest := nearest(color, db) file, err := os.Open(nearest) if err == nil { img, _, err := image.Decode(file) if err == nil { t := resize(img, tileSize) tile := t.SubImage(t.Bounds()) tileBounds := image.Rect(x, y, x+tileSize, y+tileSize) draw.Draw(newimage, tileBounds, tile, sp, draw.Src) } else { fmt.Println("error in decoding nearest", err, nearest) } } else { fmt.Println("error opening file when creating mosaic:", nearest) } file.Close() } } c <- newimage.SubImage(newimage.Rect) }() return c }
func draw_image(filename string, plot_map map[Key]Point, width int, height int, gradient string) { build_gradient(gradient) fill_palette() bounds := image.Rect(0, 0, width, height) b := image.NewNRGBA(bounds) draw.Draw(b, bounds, image.NewUniform(color.Black), image.ZP, draw.Src) for x := 0; x < width; x += 1 { for y := 0; y < height; y += 1 { var p = plot_map[Key{x, y}] b.Set(p.X, p.Y, get_colour(p.Escape)) } } file, err := os.Create(filename) if err != nil { fmt.Println(err) } if err = jpeg.Encode(file, b, &jpeg.Options{jpeg.DefaultQuality}); err != nil { fmt.Println(err) } if err = file.Close(); err != nil { fmt.Println(err) } }
// AdjustFunc applies the fn function to each pixel of the img image and returns the adjusted image. // // Example: // // dstImage = imaging.AdjustFunc( // srcImage, // func(c color.NRGBA) color.NRGBA { // // shift the red channel by 16 // r := int(c.R) + 16 // if r > 255 { // r = 255 // } // return color.NRGBA{uint8(r), c.G, c.B, c.A} // } // ) // func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA { src := toNRGBA(img) width := src.Bounds().Max.X height := src.Bounds().Max.Y dst := image.NewNRGBA(image.Rect(0, 0, width, height)) parallel(height, func(partStart, partEnd int) { for y := partStart; y < partEnd; y++ { for x := 0; x < width; x++ { i := y*src.Stride + x*4 j := y*dst.Stride + x*4 r := src.Pix[i+0] g := src.Pix[i+1] b := src.Pix[i+2] a := src.Pix[i+3] c := fn(color.NRGBA{r, g, b, a}) dst.Pix[j+0] = c.R dst.Pix[j+1] = c.G dst.Pix[j+2] = c.B dst.Pix[j+3] = c.A } } }) return dst }
func (ir *ImageRenderer) RenderToFile(filename string) { img := image.NewNRGBA(image.Rect(0, 0, ir.Width, ir.Height)) for y := 0; y < ir.Height; y++ { for x := 0; x < ir.Width; x++ { i := y*ir.Width*4 + x*4 r := uint8(ir.Pixels[i] * 255.0) g := uint8(ir.Pixels[i+1] * 255.0) b := uint8(ir.Pixels[i+2] * 255.0) a := uint8(ir.Pixels[i+3] * 255.0) c := color.NRGBA{r, g, b, a} img.Set(x, y, c) } } imgWriter, _ := os.Create(filename) defer imgWriter.Close() var err error switch filepath.Ext(filename) { case ".png": err = png.Encode(imgWriter, img) case ".jpg", ".jpeg": err = jpeg.Encode(imgWriter, img, &jpeg.Options{Quality: jpeg.DefaultQuality}) } if err != nil { fmt.Printf("Error writing out %v: %v", filename, err) } }
func (f *Font) Render(text string) *Texture { width, height, yBearing := f.TextDimensions(text) font := f.ttf size := f.Size // Colors fg := image.NewUniform(color.NRGBA{f.FG.R, f.FG.G, f.FG.B, f.FG.A}) bg := image.NewUniform(color.NRGBA{f.BG.R, f.BG.G, f.BG.B, f.BG.A}) // Create the font context c := freetype.NewContext() nrgba := image.NewNRGBA(image.Rect(0, 0, width, height)) draw.Draw(nrgba, nrgba.Bounds(), bg, image.ZP, draw.Src) c.SetDPI(dpi) c.SetFont(font) c.SetFontSize(size) c.SetClip(nrgba.Bounds()) c.SetDst(nrgba) c.SetSrc(fg) // Draw the text. pt := freetype.Pt(0, int(yBearing)) _, err := c.DrawString(text, pt) if err != nil { log.Println(err) return nil } // Create texture imObj := &ImageObject{nrgba} return NewTexture(imObj) }
func writeImagePng(filename string, pixels []float32, xres, yres int) { outImage := image.NewNRGBA(image.Rect(0, 0, xres, yres)) to_byte := func(v float32) uint8 { // apply gamma and convert to 0..255 return uint8(Clamp(255.0*math.Pow(float64(v), 1.0/2.2), 0.0, 255.0)) } for y := 0; y < yres; y++ { for x := 0; x < xres; x++ { var fcolor color.NRGBA fcolor.R = to_byte(pixels[3*(y*xres+x)+0]) fcolor.G = to_byte(pixels[3*(y*xres+x)+1]) fcolor.B = to_byte(pixels[3*(y*xres+x)+2]) fcolor.A = 0xff outImage.Set(x, y, fcolor) } } f, err := os.Create(filename) defer f.Close() if err != nil { Error("Error writing PNG \"%s\"", filename) } else { png.Encode(f, outImage) } }
// fast nearest-neighbor resize, no filtering func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA { dstW, dstH := width, height srcBounds := src.Bounds() srcW := srcBounds.Max.X srcH := srcBounds.Max.Y dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) dx := float64(srcW) / float64(dstW) dy := float64(srcH) / float64(dstH) Parallel(dstH, func(partStart, partEnd int) { for dstY := partStart; dstY < partEnd; dstY++ { fy := (float64(dstY)+0.5)*dy - 0.5 for dstX := 0; dstX < dstW; dstX++ { fx := (float64(dstX)+0.5)*dx - 0.5 srcX := int(math.Min(math.Max(math.Floor(fx+0.5), 0.0), float64(srcW))) srcY := int(math.Min(math.Max(math.Floor(fy+0.5), 0.0), float64(srcH))) srcOff := srcY*src.Stride + srcX*4 dstOff := dstY*dst.Stride + dstX*4 copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) } } }) return dst }
func convolve(img *plugin.MMapImage, matrix Matrix) { bounds := img.Bounds() height := bounds.Dy() width := bounds.Dx() out := image.NewNRGBA(img.Bounds()) log.Info("Convolving with %d x %d image", width, height) mwOn2 := matrix.width / 2 mhOn2 := matrix.height / 2 for py := 0; py < height; py++ { for px := 0; px < width; px++ { var r, g, b int for y := 0; y < matrix.height; y++ { dy := y - mhOn2 for x := 0; x < matrix.width; x++ { dx := x - mwOn2 coef := matrix.At(x, y) p := img.NRGBAAt(px+dx, py+dy) r += (coef * int(p.R)) g += (coef * int(p.G)) b += (coef * int(p.B)) } } out.SetNRGBA(px, py, nrgba(r, g, b, 255)) } } // memcpy the result back over the input buffer copy(img.Pix(), out.Pix) }
func GenerateQRCode(w io.Writer, code string, version Version) error { size := version.MappedSize() img := image.NewNRGBA(image.Rect(0, 0, size, size)) //buf := new(bytes.Buffer) return png.Encode(w, img) //return buf.Bytes() }
// Sharpen produces a sharpened version of the image. // Sigma parameter must be positive and indicates how much the image will be sharpened. // // Usage example: // // dstImage := imaging.Sharpen(srcImage, 3.5) // func Sharpen(img image.Image, sigma float64) *image.NRGBA { if sigma <= 0 { // sigma parameter must be positive! return Clone(img) } src := toNRGBA(img) blurred := Blur(img, sigma) width := src.Bounds().Max.X height := src.Bounds().Max.Y dst := image.NewNRGBA(image.Rect(0, 0, width, height)) parallel(height, func(partStart, partEnd int) { for y := partStart; y < partEnd; y++ { for x := 0; x < width; x++ { i := y*src.Stride + x*4 for j := 0; j < 4; j++ { k := i + j val := int(src.Pix[k]) + (int(src.Pix[k]) - int(blurred.Pix[k])) if val < 0 { val = 0 } else if val > 255 { val = 255 } dst.Pix[k] = uint8(val) } } } }) return dst }
func resizeHorizontal(src *image.NRGBA, width int, filter ResampleFilter) *image.NRGBA { srcBounds := src.Bounds() srcW := srcBounds.Max.X srcH := srcBounds.Max.Y dstW := width dstH := srcH dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) weights := precomputeWeights(dstW, srcW, filter) parallel(dstH, func(partStart, partEnd int) { for dstY := partStart; dstY < partEnd; dstY++ { for dstX := 0; dstX < dstW; dstX++ { var c [4]int32 for _, iw := range weights[dstX].iwpairs { i := dstY*src.Stride + iw.i*4 c[0] += int32(src.Pix[i+0]) * iw.w c[1] += int32(src.Pix[i+1]) * iw.w c[2] += int32(src.Pix[i+2]) * iw.w c[3] += int32(src.Pix[i+3]) * iw.w } j := dstY*dst.Stride + dstX*4 sum := weights[dstX].wsum dst.Pix[j+0] = clampint32(int32(float32(c[0])/float32(sum) + 0.5)) dst.Pix[j+1] = clampint32(int32(float32(c[1])/float32(sum) + 0.5)) dst.Pix[j+2] = clampint32(int32(float32(c[2])/float32(sum) + 0.5)) dst.Pix[j+3] = clampint32(int32(float32(c[3])/float32(sum) + 0.5)) } } }) return dst }
// Interpolate 4 interleaved uint8 per pixel images. func interpolate4x8(src *image.NRGBA, dstW, dstH int) image.Image { srcRect := src.Bounds() srcW := srcRect.Dx() srcH := srcRect.Dy() ww, hh := uint64(dstW), uint64(dstH) dx, dy := uint64(srcW), uint64(srcH) n, sum := dx*dy, make([]uint64, 4*dstW*dstH) for y := 0; y < srcH; y++ { pixOffset := src.PixOffset(0, y) for x := 0; x < srcW; x++ { // Get the source pixel. r64 := uint64(src.Pix[pixOffset+0]) g64 := uint64(src.Pix[pixOffset+1]) b64 := uint64(src.Pix[pixOffset+2]) a64 := uint64(src.Pix[pixOffset+3]) pixOffset += 4 // Spread the source pixel over 1 or more destination rows. py := uint64(y) * hh for remy := hh; remy > 0; { qy := dy - (py % dy) if qy > remy { qy = remy } // Spread the source pixel over 1 or more destination columns. px := uint64(x) * ww index := 4 * ((py/dy)*ww + (px / dx)) for remx := ww; remx > 0; { qx := dx - (px % dx) if qx > remx { qx = remx } qxy := qx * qy sum[index+0] += r64 * qxy sum[index+1] += g64 * qxy sum[index+2] += b64 * qxy sum[index+3] += a64 * qxy index += 4 px += qx remx -= qx } py += qy remy -= qy } } } dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) for y := 0; y < dstH; y++ { pixOffset := dst.PixOffset(0, y) for x := 0; x < dstW; x++ { dst.Pix[pixOffset+0] = uint8(sum[pixOffset+0] / n) dst.Pix[pixOffset+1] = uint8(sum[pixOffset+1] / n) dst.Pix[pixOffset+2] = uint8(sum[pixOffset+2] / n) dst.Pix[pixOffset+3] = uint8(sum[pixOffset+3] / n) pixOffset += 4 } } return dst }
// New creates a new image with the specified width and height, and fills it with the specified color. func New(width, height int, fillColor color.Color) *image.NRGBA { if width <= 0 || height <= 0 { return &image.NRGBA{} } dst := image.NewNRGBA(image.Rect(0, 0, width, height)) c := color.NRGBAModel.Convert(fillColor).(color.NRGBA) if c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0 { return dst } cs := []uint8{c.R, c.G, c.B, c.A} // fill the first row for x := 0; x < width; x++ { copy(dst.Pix[x*4:(x+1)*4], cs) } // copy the first row to other rows for y := 1; y < height; y++ { copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4]) } return dst }
func NewImage(digits []byte, width, height int) *Image { img := new(Image) r := image.Rect(img.width, img.height, stdWidth, stdHeight) img.NRGBA = image.NewNRGBA(r) img.color = &color.NRGBA{ uint8(rand.Intn(129)), uint8(rand.Intn(129)), uint8(rand.Intn(129)), 0xFF, } // Draw background (10 random circles of random brightness) img.calculateSizes(width, height, len(digits)) img.fillWithCircles(10, img.dotsize) maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize maxy := height - img.height - img.dotsize*2 x := rnd(img.dotsize*2, maxx) y := rnd(img.dotsize*2, maxy) // Draw digits. for _, n := range digits { img.drawDigit(font[n], x, y) x += img.width + img.dotsize } // Draw strike-through line. img.strikeThrough() return img }
func LoadImage(data interface{}) Image { var m image.Image switch data := data.(type) { default: log.Fatal("NewTexture needs a string or io.Reader") case string: file, err := os.Open(data) if err != nil { log.Fatal(err) } defer file.Close() img, _, err := image.Decode(file) if err != nil { log.Fatal(err) } m = img case io.Reader: img, _, err := image.Decode(data) if err != nil { log.Fatal(err) } m = img case image.Image: m = data } b := m.Bounds() newm := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(newm, newm.Bounds(), m, b.Min, draw.Src) return &ImageObject{newm} }
func BenchmarkCopyImageNRGBA(b *testing.B) { img := image.NewNRGBA(image.Rect(0, 0, 4096, 4096)) b.ResetTimer() for i := 0; i < b.N; i++ { CopyImage(img) } }
// Join the matrix of images into a single image. func (h Himawari) joinGrid(grid [][]image.Image) image.Image { dst := image.NewNRGBA(image.Rect(0, 0, gridSize*h.Depth, gridSize*h.Depth)) var wg sync.WaitGroup for i := range grid { for j := range grid[i] { if grid[i][j] == nil { break } wg.Add(1) go func(i, j int) { defer wg.Done() // Modification is performed pixel-by-pixel, so async // should be fine, theoretically. src := grid[i][j] sdx, sdy := src.Bounds().Dx(), src.Bounds().Dy() rect := image.Rect( i*sdx, j*sdy, i*sdx+sdx, j*sdy+sdy, ) draw.Draw(dst, rect, src, image.ZP, draw.Src) }(i, j) } } wg.Wait() return dst }
// generateBackground creates a background of green tiles - might not be the most efficient way to do this func generateBackground() *ecs.Entity { rect := image.Rect(0, 0, int(worldWidth), int(worldHeight)) img := image.NewNRGBA(rect) c1 := color.RGBA{102, 153, 0, 255} c2 := color.RGBA{102, 173, 0, 255} for i := rect.Min.X; i < rect.Max.X; i++ { for j := rect.Min.Y; j < rect.Max.Y; j++ { if i%40 > 20 { if j%40 > 20 { img.Set(i, j, c1) } else { img.Set(i, j, c2) } } else { if j%40 > 20 { img.Set(i, j, c2) } else { img.Set(i, j, c1) } } } } bgTexture := engi.NewImageObject(img) field := ecs.NewEntity([]string{"RenderSystem"}) fieldRender := engi.NewRenderComponent(engi.NewTexture(bgTexture), engi.Point{1, 1}, "Background1") fieldRender.SetPriority(engi.Background) fieldSpace := &engi.SpaceComponent{engi.Point{0, 0}, worldWidth, worldHeight} field.AddComponent(fieldRender) field.AddComponent(fieldSpace) return field }
//IMAGE DUMP FUNCTIONS - SLOPPY CODE!!!! func SpritesToImage(sprites [40][8][8]types.RGB, w, h int) (*image.NRGBA, error) { out := image.NewNRGBA(image.Rect(0, 0, w, h)) font, err := GetFont("../resources/FreeUniversal-Regular.ttf") if err != nil { return out, err } draw.Draw(out, out.Bounds(), &image.Uniform{color.RGBA{200, 200, 200, 255}}, image.ZP, draw.Src) DrawTextOnImage("Sprites", font, out, 8, (out.Bounds().Dx()/2)-10, 2) plotX, plotY, imgX, imgY := 4, 26, 0, 0 var spacing int = 8 for i, spr := range sprites { for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { cr := color.RGBA{spr[y][x].Red, spr[y][x].Green, spr[y][x].Blue, 0xFF} out.Set(imgX+plotX, imgY+plotY, cr) imgX++ } imgX = 0 imgY++ } imgY = 0 DrawTextOnImage(fmt.Sprint(i), font, out, 4, plotX, plotY+12) plotX += 8 + spacing if plotX >= 490 { plotY += 24 + spacing plotX = 4 } } return out, nil }