// NewDrawableSize returns a new draw.Image with the same type as p and the given bounds. // If p is not a draw.Image, another type is used. func NewDrawableSize(p image.Image, r image.Rectangle) draw.Image { switch p := p.(type) { case *image.RGBA: return image.NewRGBA(r) case *image.RGBA64: return image.NewRGBA64(r) case *image.NRGBA: return image.NewNRGBA(r) case *image.NRGBA64: return image.NewNRGBA64(r) case *image.Alpha: return image.NewAlpha(r) case *image.Alpha16: return image.NewAlpha16(r) case *image.Gray: return image.NewGray(r) case *image.Gray16: return image.NewGray16(r) case *image.Paletted: pl := make(color.Palette, len(p.Palette)) copy(pl, p.Palette) return image.NewPaletted(r, pl) case *image.CMYK: return image.NewCMYK(r) default: return image.NewRGBA(r) } }
// Save saves the texture as a PNG image. func (a *TextureAtlas) Save(file string) (err error) { fd, err := os.Create(file) if err != nil { return } defer fd.Close() rect := image.Rect(0, 0, a.width, a.height) switch a.depth { case 1: img := image.NewAlpha(rect) copy(img.Pix, a.data) err = png.Encode(fd, img) case 3: img := image.NewRGBA(rect) copy(img.Pix, a.data) err = png.Encode(fd, img) case 4: img := image.NewRGBA(rect) copy(img.Pix, a.data) err = png.Encode(fd, img) } return }
// Smart crop given image file & write it to io.Writer func smartCrop(w io.Writer, r io.Reader, size []int) error { img, mimetype, err := image.Decode(r) if size == nil || err != nil { io.Copy(w, r) return nil } size = setMaxSize(fitToActualSize(&img, size)) crop, err := smartcrop.SmartCrop(&img, size[0], size[1]) if err != nil { io.Copy(w, r) return nil } croppedBuffer := image.NewRGBA(image.Rect(0, 0, crop.Width, crop.Height)) draw.Draw( croppedBuffer, croppedBuffer.Bounds(), img, image.Point{crop.X, crop.Y}, draw.Src, ) dst := image.NewRGBA(image.Rect(0, 0, size[0], size[1])) graphics.Scale(dst, croppedBuffer) return writeByMimetype(w, dst, mimetype) }
func main() { rand.Seed(time.Now().UTC().UnixNano()) var templatePath string if len(os.Args) == 1 { templatePath = "tux.png" } else { templatePath = os.Args[1] } template, err := readTemplate(templatePath) if err != nil { panic(err) } templateBounds := template.Bounds() sourceHeight := templateBounds.Max.Y sourceWidth := templateBounds.Max.X cypherHeight := sourceHeight * 2 cypherWidth := sourceWidth * 2 image1 := image.NewRGBA(image.Rect(0, 0, cypherWidth, cypherHeight)) image2 := image.NewRGBA(image.Rect(0, 0, cypherWidth, cypherHeight)) for x := 0; x <= sourceWidth; x++ { for y := 0; y <= sourceHeight; y++ { setPixel(x, y, template.At(x, y), image1, image2) } } writeCypers(image1, image2) }
func NewPPU(console *Console) *PPU { ppu := PPU{Memory: NewPPUMemory(console), console: console} ppu.front = image.NewRGBA(image.Rect(0, 0, 256, 240)) ppu.back = image.NewRGBA(image.Rect(0, 0, 256, 240)) ppu.Reset() return &ppu }
func makePngShield(w io.Writer, d Data) { // render text to determine how wide the image has to be // we leave 6 pixels at the start and end, and 3 for each in the middle v, vw := renderString(d.Vendor, c) s, sw := renderString(d.Status, c) imageWidth := op + vw + ip*2 + sw + op img := image.NewRGBA(image.Rect(0, 0, imageWidth, h)) draw.Draw(img, img.Bounds(), &image.Uniform{C: d.Color}, image.ZP, draw.Src) rect := image.Rect(0, 0, op+vw+ip, h) draw.Draw(img, rect, &image.Uniform{C: Grey}, image.ZP, draw.Src) dst := image.NewRGBA(image.Rect(0, 0, imageWidth, h)) mask := image.NewRGBA(image.Rect(0, 0, imageWidth, h)) buildMask(mask, imageWidth, edge, draw.Src) draw.DrawMask(dst, dst.Bounds(), img, image.ZP, mask, image.ZP, draw.Over) buildMask(dst, imageWidth, gradient, draw.Over) draw.Draw(dst, dst.Bounds(), v, image.Point{-op, 0}, draw.Over) draw.Draw(dst, dst.Bounds(), s, image.Point{-(op + vw + ip*2), 0}, draw.Over) png.Encode(w, dst) }
func (ff *FontFace) GetImage(text string) (img draw.Image, err error) { var ( src image.Image bg image.Image dst draw.Image pt fixed.Point26_6 w int h int ) src = image.NewUniform(ff.fg) bg = image.NewUniform(ff.bg) w = int(float32(len(text)) * ff.charw) h = int(ff.charh) dst = image.NewRGBA(image.Rect(0, 0, w, h)) draw.Draw(dst, dst.Bounds(), bg, image.ZP, draw.Src) ff.context.SetSrc(src) ff.context.SetDst(dst) ff.context.SetClip(dst.Bounds()) pt = freetype.Pt(0, int(ff.charh+ff.offy)) if pt, err = ff.context.DrawString(text, pt); err != nil { return } img = image.NewRGBA(image.Rect(0, 0, int(pt.X/64), int(pt.Y/64))) draw.Draw(img, img.Bounds(), dst, image.Pt(0, -int(ff.offy)), draw.Src) return }
func (ff *FontFace) GetText(text string) (t *Texture, err error) { var ( src image.Image bg image.Image dst draw.Image shortened draw.Image pt fixed.Point26_6 w int h int ) src = image.NewUniform(ff.fg) bg = image.NewUniform(ff.bg) w = int(float32(len(text)) * ff.charw) h = int(ff.charh) dst = image.NewRGBA(image.Rect(0, 0, w, h)) draw.Draw(dst, dst.Bounds(), bg, image.ZP, draw.Src) ff.context.SetSrc(src) ff.context.SetDst(dst) ff.context.SetClip(dst.Bounds()) pt = freetype.Pt(0, int(ff.charh)) if pt, err = ff.context.DrawString(text, pt); err != nil { return } // if err = WritePNG("hello.png", dst); err != nil { // return // } shortened = image.NewRGBA(image.Rect(0, 0, int(pt.X/64), h)) draw.Draw(shortened, shortened.Bounds(), dst, image.ZP, draw.Src) t, err = GetTexture(shortened, gl.NEAREST) return }
// TestNegativeWeights tests that scaling by a kernel that produces negative // weights, such as the Catmull-Rom kernel, doesn't produce an invalid color // according to Go's alpha-premultiplied model. func TestNegativeWeights(t *testing.T) { check := func(m *image.RGBA) error { b := m.Bounds() for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { if c := m.RGBAAt(x, y); c.R > c.A || c.G > c.A || c.B > c.A { return fmt.Errorf("invalid color.RGBA at (%d, %d): %v", x, y, c) } } } return nil } src := image.NewRGBA(image.Rect(0, 0, 16, 16)) for y := 0; y < 16; y++ { for x := 0; x < 16; x++ { a := y * 0x11 src.Set(x, y, color.RGBA{ R: uint8(x * 0x11 * a / 0xff), A: uint8(a), }) } } if err := check(src); err != nil { t.Fatalf("src image: %v", err) } dst := image.NewRGBA(image.Rect(0, 0, 32, 32)) CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), Over, nil) if err := check(dst); err != nil { t.Fatalf("dst image: %v", err) } }
func main() { m := image.NewRGBA(image.Rect(0, 0, 500, 500)) blue := color.RGBA{59, 148, 217, 255} white := color.RGBA{255, 255, 255, 255} black := color.RGBA{0, 0, 0, 255} draw.Draw(m, m.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src) filename := "egg_mask.png" f, err := os.Open(filename) if err != nil { panic(err) } defer f.Close() src, err := png.Decode(f) if err != nil { panic(err) } mask := image.NewRGBA(image.Rect(0, 0, 500, 500)) draw.Draw(mask, mask.Bounds(), &image.Uniform{white}, image.ZP, draw.Src) draw.DrawMask(m, m.Bounds(), src, image.ZP, mask, image.ZP, draw.Over) for i := m.Bounds().Min.X; i < m.Bounds().Max.X; i++ { m.Set(i, m.Bounds().Max.Y/2, black) // to change a single pixel } w, _ := os.Create("defaultegg.png") defer w.Close() png.Encode(w, m) }
func TestSrcMask(t *testing.T) { srcMask := image.NewRGBA(image.Rect(0, 0, 23, 1)) srcMask.SetRGBA(19, 0, color.RGBA{0x00, 0x00, 0x00, 0x7f}) srcMask.SetRGBA(20, 0, color.RGBA{0x00, 0x00, 0x00, 0xff}) srcMask.SetRGBA(21, 0, color.RGBA{0x00, 0x00, 0x00, 0x3f}) srcMask.SetRGBA(22, 0, color.RGBA{0x00, 0x00, 0x00, 0x00}) red := image.NewUniform(color.RGBA{0xff, 0x00, 0x00, 0xff}) blue := image.NewUniform(color.RGBA{0x00, 0x00, 0xff, 0xff}) dst := image.NewRGBA(image.Rect(0, 0, 6, 1)) Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil) NearestNeighbor.Scale(dst, dst.Bounds(), red, image.Rect(0, 0, 3, 1), Over, &Options{ SrcMask: srcMask, SrcMaskP: image.Point{20, 0}, }) got := [6]color.RGBA{ dst.RGBAAt(0, 0), dst.RGBAAt(1, 0), dst.RGBAAt(2, 0), dst.RGBAAt(3, 0), dst.RGBAAt(4, 0), dst.RGBAAt(5, 0), } want := [6]color.RGBA{ {0xff, 0x00, 0x00, 0xff}, {0xff, 0x00, 0x00, 0xff}, {0x3f, 0x00, 0xc0, 0xff}, {0x3f, 0x00, 0xc0, 0xff}, {0x00, 0x00, 0xff, 0xff}, {0x00, 0x00, 0xff, 0xff}, } if got != want { t.Errorf("\ngot %v\nwant %v", got, want) } }
func (jw *JsonWed) ImportOverlays(wed *Wed) error { jw.Overlays = make([]jsonWedOverlay, 0) jw.TileIndices = make([]int, len(wed.TileIndices)) for idx, overlay := range wed.Overlays { if overlay.Name.String() != "" { ov := jsonWedOverlay{} ov.Width = int(overlay.Width) ov.Height = int(overlay.Height) ov.Name = overlay.Name.String() ov.Flags = int(overlay.LayerFlags) ov.Tilemap = make([]jsonWedTilemap, len(wed.Tilemaps[idx])) for tmIdx, tilemap := range wed.Tilemaps[idx] { ov.Tilemap[tmIdx].Id = int(tilemap.TileIndexLookupIndex) ov.Tilemap[tmIdx].Count = int(tilemap.TileIndexLookupCount) ov.Tilemap[tmIdx].Alt = int(tilemap.AlternateTileIndex) ov.Tilemap[tmIdx].Flags = int(tilemap.Flags) ov.Tilemap[tmIdx].AnimSpeed = int(tilemap.AnimSpeed) ov.Tilemap[tmIdx].WFlags = int(tilemap.WFlags) } tisFile, err := os.Open(overlay.Name.String() + ".tis") if err != nil { return fmt.Errorf("unable to open overlay: %s %v", overlay.Name.String(), err) } defer tisFile.Close() cwd, err := os.Getwd() if err != nil { return fmt.Errorf("unable to get working directory: %v", err) } tis, err := OpenTis(tisFile, overlay.Name.String(), cwd) if err != nil { return fmt.Errorf("unable to open tis: %v", err) } ov.Tis = tis img := image.NewRGBA(image.Rect(0, 0, 64*ov.Width, 64*ov.Height)) closedimg := image.NewRGBA(image.Rect(0, 0, 64*ov.Width, 64*ov.Height)) for y := 0; y < int(ov.Height); y++ { for x := 0; x < int(ov.Width); x++ { tileNum := y*int(ov.Width) + x tileImg := tis.SubImage(tileNum) draw.Draw(img, image.Rect(x*64, y*64, x*64+64, y*64+64), tileImg, image.Pt(0, 0), draw.Src) if ov.Tilemap[tileNum].Alt != -1 { tileImg = tis.SubImage(ov.Tilemap[tileNum].Alt) draw.Draw(closedimg, image.Rect(x*64, y*64, x*64+64, y*64+64), tileImg, image.Pt(0, 0), draw.Src) } } } ov.BackgroundImg = img ov.ClosedImage = closedimg jw.Overlays = append(jw.Overlays, ov) } } for idx, ti := range wed.TileIndices { jw.TileIndices[idx] = int(ti) } return nil }
func maskFor(in image.Image) image.Image { b := in.Bounds() // thumb size, corresponds to first convert command thumbWidth := int(b.Dx() / 5) thumbHeight := int(b.Dy() / 5) thumb := image.NewRGBA(image.Rect(0, 0, thumbWidth, thumbHeight)) final := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) // fill black (xc:black) // draw white rectangle (1,1 : thumbWidth-1,thumbHeight-1) for y := 0; y < thumbHeight; y++ { for x := 0; x < thumbWidth; x++ { if (y > 0 && y < thumbHeight-1) && (x > 0 && x < thumbWidth-1) { thumb.Set(x, y, color.White) } else { thumb.Set(x, y, color.Black) } } } // apply Gaussian blur with radius=7, sigma=15 graphics.Blur(thumb, thumb, &graphics.BlurOptions{2, 7}) // now resize to original image size resized := resize.Resize(uint(b.Dx()), uint(b.Dy()), thumb, resize.Bilinear) // with gaussian blur radius=0, sigma=5 graphics.Blur(final, resized, &graphics.BlurOptions{5, 0}) return final }
// Adjust adjusts the two images aligning ther centers. The background // of the smaller image is filled with FillColor. The returned images // are of the same size. func (c Centerer) Adjust(img1, img2 image.Image) (image.Image, image.Image) { img1Rect := img1.Bounds() img2Rect := img2.Bounds() backgroundRect := img1Rect.Union(img2Rect) dstImg1 := image.NewRGBA(backgroundRect) dstImg2 := image.NewRGBA(backgroundRect) // Fill destination images with FillColor draw.Draw(dstImg1, dstImg1.Bounds(), &image.Uniform{c.FillColor}, image.ZP, draw.Src) draw.Draw(dstImg2, dstImg2.Bounds(), &image.Uniform{c.FillColor}, image.ZP, draw.Src) // Copy img1 to the center of dstImg1 dp := image.Point{ (backgroundRect.Max.X-backgroundRect.Min.X)/2 - (img1Rect.Max.X-img1Rect.Min.X)/2, (backgroundRect.Max.Y-backgroundRect.Min.Y)/2 - (img1Rect.Max.Y-img1Rect.Min.Y)/2, } r := image.Rectangle{dp, dp.Add(img1Rect.Size())} draw.Draw(dstImg1, r, img1, image.ZP, draw.Src) // Copy img2 to the center of dstImg2 dp = image.Point{ (backgroundRect.Max.X-backgroundRect.Min.X)/2 - (img2Rect.Max.X-img2Rect.Min.X)/2, (backgroundRect.Max.Y-backgroundRect.Min.Y)/2 - (img2Rect.Max.Y-img2Rect.Min.Y)/2, } r = image.Rectangle{dp, dp.Add(img2Rect.Size())} draw.Draw(dstImg2, r, img2, image.ZP, draw.Src) return dstImg1, dstImg2 }
func TestGMProcess(t *testing.T) { buffer := new(bytes.Buffer) png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200))) gm := NewGMProcessor() params, _ := ParseParams("r_100x100,c_50x50,g_c,q_50") img, err := gm.Process(params, "text.png", buffer) assert.NoError(t, err) assert.NotNil(t, img) assert.True(t, img.Len() > 0) buffer = new(bytes.Buffer) png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200))) params, _ = ParseParams("r_100x0,c_50x50,g_c,q_50") img, err = gm.Process(params, "text.png", buffer) assert.NoError(t, err) assert.NotNil(t, img) assert.True(t, img.Len() > 0) buffer = new(bytes.Buffer) png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200))) params, _ = ParseParams("r_0x100,c_50x50,g_c,q_50") img, err = gm.Process(params, "text.png", buffer) assert.NoError(t, err) assert.NotNil(t, img) assert.True(t, img.Len() > 0) }
func TestConvolve(t *testing.T) { kernFull, err := NewKernel([]float64{ 0, 0, 0, 1, 1, 1, 0, 0, 0, }) if err != nil { t.Fatal(err) } kernSep := &SeparableKernel{ X: []float64{1, 1, 1}, Y: []float64{0, 1, 0}, } src, err := graphicstest.LoadImage("../../testdata/gopher.png") if err != nil { t.Fatal(err) } b := src.Bounds() sep := image.NewRGBA(b) if err = Convolve(sep, src, kernSep); err != nil { t.Fatal(err) } full := image.NewRGBA(b) Convolve(full, src, kernFull) err = graphicstest.ImageWithinTolerance(sep, full, 0x101) if err != nil { t.Fatal(err) } }
func DrawLogo(qrPng []byte, logo string, logoBgColor color.Color) []byte { if logo != "" { // println(logo) resp, err := http.Get(logo) if err != nil { fmt.Printf("Logo Error=%s\n", err.Error()) // println(resp) } else { logoImg, _, _ := image.Decode(resp.Body) qrImg, _, _ := image.Decode(bytes.NewReader(qrPng)) pb := qrImg.Bounds() logoImg = resize.Resize(uint(pb.Dx()/4), uint(pb.Dy()/4), logoImg, resize.Lanczos3) logoBgImg := image.NewRGBA(image.Rect(0, 0, logoImg.Bounds().Dx()+2, logoImg.Bounds().Dy()+2)) draw.Draw(logoBgImg, logoBgImg.Bounds(), &image.Uniform{color.White}, image.Point{}, draw.Src) draw.Draw(logoBgImg, logoImg.Bounds(), logoImg, image.Point{-1, -1}, draw.Over) offsetX := (pb.Dx() - logoBgImg.Bounds().Dx()) / 2 newImg := image.NewRGBA(pb) draw.Draw(newImg, pb, qrImg, image.Point{}, draw.Src) draw.Draw(newImg, newImg.Bounds(), logoBgImg, image.Point{-offsetX, -offsetX}, draw.Over) // println(logoImg) buf := new(bytes.Buffer) err = png.Encode(buf, newImg) // send_s3 := buf.Bytes() return buf.Bytes() } } return qrPng }
// TestSrcTranslationInvariance tests that Scale and Transform are invariant // under src translations. Specifically, when some source pixels are not in the // bottom-right quadrant of src coordinate space, we consistently round down, // not round towards zero. func TestSrcTranslationInvariance(t *testing.T) { f, err := os.Open("../testdata/testpattern.png") if err != nil { t.Fatalf("Open: %v", err) } defer f.Close() src, _, err := image.Decode(f) if err != nil { t.Fatalf("Decode: %v", err) } sr := image.Rect(2, 3, 16, 12) if !sr.In(src.Bounds()) { t.Fatalf("src bounds too small: got %v", src.Bounds()) } qs := []Interpolator{ NearestNeighbor, ApproxBiLinear, CatmullRom, } deltas := []image.Point{ {+0, +0}, {+0, +5}, {+0, -5}, {+5, +0}, {-5, +0}, {+8, +8}, {+8, -8}, {-8, +8}, {-8, -8}, } m00 := transformMatrix(3.75, 0, 0) for _, transform := range []bool{false, true} { for _, q := range qs { want := image.NewRGBA(image.Rect(0, 0, 20, 20)) if transform { q.Transform(want, m00, src, sr, Over, nil) } else { q.Scale(want, want.Bounds(), src, sr, Over, nil) } for _, delta := range deltas { tsrc := &translatedImage{src, delta} got := image.NewRGBA(image.Rect(0, 0, 20, 20)) if transform { m := matMul(&m00, &f64.Aff3{ 1, 0, -float64(delta.X), 0, 1, -float64(delta.Y), }) q.Transform(got, m, tsrc, sr.Add(delta), Over, nil) } else { q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), Over, nil) } if !bytes.Equal(got.Pix, want.Pix) { t.Errorf("pix differ for delta=%v, transform=%t, q=%T", delta, transform, q) } } } } }
func BenchmarkSimpleScaleCopy(b *testing.B) { dst := image.NewRGBA(image.Rect(0, 0, 640, 480)) src := image.NewRGBA(image.Rect(0, 0, 400, 300)) b.ResetTimer() for i := 0; i < b.N; i++ { ApproxBiLinear.Scale(dst, image.Rect(10, 20, 10+400, 20+300), src, src.Bounds(), Src, nil) } }
// testInterp tests that interpolating the source image gives the exact // destination image. This is to ensure that any refactoring or optimization of // the interpolation code doesn't change the behavior. Changing the actual // algorithm or kernel used by any particular quality setting will obviously // change the resultant pixels. In such a case, use the gen_golden_files flag // to regenerate the golden files. func testInterp(t *testing.T, w int, h int, direction, srcFilename string) { f, err := os.Open("../testdata/go-turns-two-" + srcFilename) if err != nil { t.Fatalf("Open: %v", err) } defer f.Close() src, _, err := image.Decode(f) if err != nil { t.Fatalf("Decode: %v", err) } testCases := map[string]Interpolator{ "nn": NearestNeighbor, "ab": ApproxBiLinear, "bl": BiLinear, "cr": CatmullRom, } for name, q := range testCases { goldenFilename := fmt.Sprintf("../testdata/go-turns-two-%s-%s.png", direction, name) got := image.NewRGBA(image.Rect(0, 0, w, h)) if direction == "rotate" { q.Transform(got, transformMatrix(40, 10), src, src.Bounds(), nil) } else { q.Scale(got, got.Bounds(), src, src.Bounds(), nil) } if *genGoldenFiles { if err := encode(goldenFilename, got); err != nil { t.Error(err) } continue } g, err := os.Open(goldenFilename) if err != nil { t.Errorf("Open: %v", err) continue } defer g.Close() wantRaw, err := png.Decode(g) if err != nil { t.Errorf("Decode: %v", err) continue } // convert wantRaw to RGBA. want, ok := wantRaw.(*image.RGBA) if !ok { b := wantRaw.Bounds() want = image.NewRGBA(b) Draw(want, b, wantRaw, b.Min, Src) } if !reflect.DeepEqual(got, want) { t.Errorf("%s: actual image differs from golden image", goldenFilename) continue } } }
func BenchmarkCopy(b *testing.B) { src := image.NewRGBA(image.Rect(0, 0, 100, 100)) testDrawRandom(src) dst := image.NewRGBA(image.Rect(0, 0, 100, 100)) b.ResetTimer() for i := 0; i < b.N; i++ { Copy(dst, src) } }
func tileImage(lookup []imageLookup) { imgFile, openErr := os.Open(inputImage) if openErr != nil { log.Println("Source File (Open): ", openErr) } defer imgFile.Close() imgData, _, decodeErr := image.Decode(imgFile) if decodeErr != nil { log.Println("Source File (Decode Tile): ", decodeErr) } bounds := imgData.Bounds() imgWidth := bounds.Max.X imgHeight := bounds.Max.Y maxTilesX := int(math.Ceil(float64(imgWidth) / float64(tileSize))) maxTilesY := int(math.Ceil(float64(imgHeight) / float64(tileSize))) var tileChoice []tileReplacement newCanvas := image.NewRGBA(image.Rect(0, 0, imgWidth, imgHeight)) for tileY := 0; tileY < maxTilesY; tileY++ { for tileX := 0; tileX < maxTilesX; tileX++ { tileXZero := tileX * tileSize tileYZero := tileY * tileSize imgTile := image.NewRGBA(image.Rect(0, 0, tileSize, tileSize)) draw.Draw(imgTile, imgTile.Bounds(), imgData, image.Point{tileXZero, tileYZero}, draw.Src) tileColor := averageColor(imgTile) var distSlice []tileDistance for l := 0; l < len(lookup); l++ { colorDist := measureColorDist(tileColor.colorR, tileColor.colorG, tileColor.colorB, lookup[l].colorR, lookup[l].colorG, lookup[l].colorB) cdSlice := tileDistance{lookup[l].sourceName, colorDist} distSlice = append(distSlice, cdSlice) } min := distSlice[0].distance idx := 0 for m := 0; m < len(distSlice); m++ { if distSlice[m].distance < min { min = distSlice[m].distance idx = m } } closestTile := tileReplacement{tileX, tileY, distSlice[idx].sourceName} tileChoice = append(tileChoice, closestTile) fmt.Printf("Now processing tile %d:%d ...", tileX, tileY) rpcSmall := replaceTile(closestTile) draw.Draw(newCanvas, image.Rectangle{image.Point{tileXZero, tileYZero}, image.Point{imgWidth, imgHeight}}, rpcSmall, image.Point{0, 0}, draw.Src) } } writeToJPEG(newCanvas) }
func TestCopy(t *testing.T) { for _, tc := range []struct { name string srcSize image.Rectangle dstSize image.Rectangle }{ { name: "Equal", srcSize: image.Rect(0, 0, 10, 10), dstSize: image.Rect(0, 0, 10, 10), }, { name: "Larger", srcSize: image.Rect(0, 0, 5, 5), dstSize: image.Rect(0, 0, 10, 10), }, { name: "Smaller", srcSize: image.Rect(0, 0, 10, 10), dstSize: image.Rect(0, 0, 5, 5), }, { name: "NoIntersection", srcSize: image.Rect(0, 0, 5, 5), dstSize: image.Rect(5, 5, 10, 10), }, { name: "Intersection1", srcSize: image.Rect(0, 0, 10, 10), dstSize: image.Rect(5, 5, 15, 15), }, { name: "Intersection2", srcSize: image.Rect(5, 5, 15, 15), dstSize: image.Rect(0, 0, 10, 10), }, } { t.Run(tc.name, func(t *testing.T) { src := image.NewRGBA(tc.srcSize) testDrawRandom(src) dst := image.NewRGBA(tc.dstSize) Copy(dst, src) bd := src.Bounds().Intersect(dst.Bounds()) for y, yEnd := bd.Min.Y, bd.Max.Y; y < yEnd; y++ { for x, xEnd := bd.Min.X, bd.Max.X; x < xEnd; x++ { cSrc := src.At(x, y) cDst := dst.At(x, y) if cSrc != cDst { t.Fatalf("different color: %#v, pixel %dx%d: src=%#v, dst=%#v", tc, x, y, cSrc, cDst) } } } }) } }
func BenchmarkSimpleTransformScale(b *testing.B) { dst := image.NewRGBA(image.Rect(0, 0, 640, 480)) src := image.NewRGBA(image.Rect(0, 0, 400, 300)) b.ResetTimer() for i := 0; i < b.N; i++ { ApproxBiLinear.Transform(dst, f64.Aff3{ 0.5, 0.0, 10, 0.0, 0.5, 20, }, src, src.Bounds(), Src, nil) } }
func BenchmarkCopy(b *testing.B) { src := image.NewRGBA(image.Rect(0, 0, 100, 100)) testDrawRandom(src) dst := image.NewRGBA(image.Rect(0, 0, 100, 100)) b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { Copy(dst, src) } }) }
// TestIssue836 verifies http://code.google.com/p/go/issues/detail?id=836. func TestIssue836(t *testing.T) { a := image.NewRGBA(1, 1) b := image.NewRGBA(2, 2) b.Set(0, 0, image.RGBAColor{0, 0, 0, 5}) b.Set(1, 0, image.RGBAColor{0, 0, 5, 5}) b.Set(0, 1, image.RGBAColor{0, 5, 0, 5}) b.Set(1, 1, image.RGBAColor{5, 0, 0, 5}) Draw(a, image.Rect(0, 0, 1, 1), b, image.Pt(1, 1)) if !eq(image.RGBAColor{5, 0, 0, 5}, a.At(0, 0)) { t.Errorf("Issue 836: want %v got %v", image.RGBAColor{5, 0, 0, 5}, a.At(0, 0)) } }
func main() { // read parameters flag.Parse() // open input file inFile, err := os.Open(*filename) if err != nil { panic(err) } // close file on exit and check for its returned error defer func() { if err := inFile.Close(); err != nil { panic(err) } }() r := csv.NewReader(bufio.NewReader(inFile)) r.Comma = ';' r.Comment = '#' records, err := r.ReadAll() if err != nil { panic(err) } // prepare images to draw white an black rectangles black = image.NewRGBA(image.Rect(0, 0, scale, scale)) white = image.NewRGBA(image.Rect(0, 0, scale, scale)) cB := color.RGBA{0x0, 0x0, 0x0, 0xFF} cW := color.RGBA{0xFF, 0xFF, 0xFF, 0x0} draw.Draw(black, black.Bounds(), &image.Uniform{cB}, image.ZP, draw.Src) draw.Draw(white, white.Bounds(), &image.Uniform{cW}, image.ZP, draw.Src) var headers []string pool := make(chan bool, 200/scale) var wg sync.WaitGroup for i, v := range records { if i == 0 { // first row are the headings headers = v } else { wg.Add(1) pool <- true go generateQr(headers, v, pool, &wg) } } wg.Wait() }
func ImageTransformByProfile(src_image image.Image, src_prof, dst_prof *Profile) (image.Image, error) { var dst_image image.Image rect := src_image.Bounds() width := rect.Dx() height := rect.Dy() colorModel := src_image.ColorModel() // 今のところ RGBA, YCbCr のみ対応 if (colorModel != color.YCbCrModel) && (colorModel != color.RGBAModel) { return nil, fmt.Errorf("ImageTransformByProfile: Unsupported ColorModel(%d)", colorModel) } var src_rgba *image.RGBA var src_ycbcr *image.YCbCr if colorModel == color.YCbCrModel { // YCbCr の場合は RGB に変換する src_ycbcr = src_image.(*image.YCbCr) src_rgba = image.NewRGBA(rect) DrawYCbCr(src_rgba, rect, src_ycbcr, image.Pt(0, 0)) } else { src_rgba = src_image.(*image.RGBA) // type assertions } transform := CreateTransform(src_prof, DATA_RGBA_8, dst_prof, DATA_RGBA_8) defer transform.DeleteTransform() if transform == nil { return nil, fmt.Errorf("ImageTransformByProfile: CreateTransform Failedl(%d)", colorModel) } dst_rgba := image.NewRGBA(rect) src_pix := src_rgba.Pix dst_pix := dst_rgba.Pix len_pix := len(src_pix) transform.DoTransform(src_pix, dst_pix, len_pix) // YCbCr の場合は RGB から戻す if colorModel == color.YCbCrModel { dst_ycbcr := image.NewYCbCr(rect, src_ycbcr.SubsampleRatio) var x int var y int for y = 0; y < height; y++ { for x = 0; x < width; x++ { r, g, b, _ := dst_rgba.At(x, y).RGBA() yy, cb, cr := color.RGBToYCbCr(uint8(r), uint8(g), uint8(b)) yi := dst_ycbcr.YOffset(x, y) ci := dst_ycbcr.COffset(x, y) dst_ycbcr.Y[yi] = yy dst_ycbcr.Cb[ci] = cb dst_ycbcr.Cr[ci] = cr } } dst_image = image.Image(dst_ycbcr) } else { dst_image = image.Image(dst_rgba) } return dst_image, nil }
// TestNonZeroSrcPt checks drawing with a non-zero src point parameter. func TestNonZeroSrcPt(t *testing.T) { a := image.NewRGBA(image.Rect(0, 0, 1, 1)) b := image.NewRGBA(image.Rect(0, 0, 2, 2)) b.Set(0, 0, color.RGBA{0, 0, 0, 5}) b.Set(1, 0, color.RGBA{0, 0, 5, 5}) b.Set(0, 1, color.RGBA{0, 5, 0, 5}) b.Set(1, 1, color.RGBA{5, 0, 0, 5}) Draw(a, image.Rect(0, 0, 1, 1), b, image.Pt(1, 1), Over) if !eq(color.RGBA{5, 0, 0, 5}, a.At(0, 0)) { t.Errorf("non-zero src pt: want %v got %v", color.RGBA{5, 0, 0, 5}, a.At(0, 0)) } }
// TestSimpleTransforms tests Scale and Transform calls that simplify to Copy // or Scale calls. func TestSimpleTransforms(t *testing.T) { f, err := os.Open("../testdata/testpattern.png") // A 100x100 image. if err != nil { t.Fatalf("Open: %v", err) } defer f.Close() src, _, err := image.Decode(f) if err != nil { t.Fatalf("Decode: %v", err) } dst0 := image.NewRGBA(image.Rect(0, 0, 120, 150)) dst1 := image.NewRGBA(image.Rect(0, 0, 120, 150)) for _, op := range []string{"scale/copy", "tform/copy", "tform/scale"} { for _, epsilon := range []float64{0, 1e-50, 1e-1} { Copy(dst0, image.Point{}, image.Transparent, dst0.Bounds(), Src, nil) Copy(dst1, image.Point{}, image.Transparent, dst1.Bounds(), Src, nil) switch op { case "scale/copy": dr := image.Rect(10, 30, 10+100, 30+100) if epsilon > 1e-10 { dr.Max.X++ } Copy(dst0, image.Point{10, 30}, src, src.Bounds(), Src, nil) ApproxBiLinear.Scale(dst1, dr, src, src.Bounds(), Src, nil) case "tform/copy": Copy(dst0, image.Point{10, 30}, src, src.Bounds(), Src, nil) ApproxBiLinear.Transform(dst1, f64.Aff3{ 1, 0 + epsilon, 10, 0, 1, 30, }, src, src.Bounds(), Src, nil) case "tform/scale": ApproxBiLinear.Scale(dst0, image.Rect(10, 50, 10+50, 50+50), src, src.Bounds(), Src, nil) ApproxBiLinear.Transform(dst1, f64.Aff3{ 0.5, 0.0 + epsilon, 10, 0.0, 0.5, 50, }, src, src.Bounds(), Src, nil) } differ := !bytes.Equal(dst0.Pix, dst1.Pix) if epsilon > 1e-10 { if !differ { t.Errorf("%s yielded same pixels, want different pixels: epsilon=%v", op, epsilon) } } else { if differ { t.Errorf("%s yielded different pixels, want same pixels: epsilon=%v", op, epsilon) } } } } }