From 5eb6bf0ea28ffc1a7f0c33838eaf5f68c37f408d Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Fri, 19 Aug 2022 16:33:21 +0200 Subject: [PATCH] plotter: add special handling for image.Uniform Fixes #752. Signed-off-by: Sebastien Binet --- plotter/image.go | 16 +++++++++++++ plotter/image_example_test.go | 21 ++++++++++++++++++ plotter/image_test.go | 4 ++++ .../testdata/image_plot_uniform_golden.png | Bin 0 -> 6519 bytes 4 files changed, 41 insertions(+) create mode 100644 plotter/testdata/image_plot_uniform_golden.png diff --git a/plotter/image.go b/plotter/image.go index 7d9540211..66f82679c 100644 --- a/plotter/image.go +++ b/plotter/image.go @@ -27,6 +27,12 @@ type Image struct { // (xmin, ymin) and (xmax, ymax) points given in the data space. // The img will be scaled to fit inside the rectangle. func NewImage(img image.Image, xmin, ymin, xmax, ymax float64) *Image { + if src, ok := img.(*image.Uniform); ok { + img = uniform{ + src, + image.Rect(0, 0, int(xmax-xmin+0.5), int(ymax-ymin+0.5)), + } + } bounds := img.Bounds() cols := bounds.Dx() rows := bounds.Dy() @@ -126,3 +132,13 @@ func (img *Image) y(r int) float64 { } return img.ymin + float64(r)*img.dy } + +// uniform is a cropped uniform image. +type uniform struct { + *image.Uniform + rect image.Rectangle +} + +func (img uniform) Bounds() image.Rectangle { + return img.rect +} diff --git a/plotter/image_example_test.go b/plotter/image_example_test.go index 9fa51688f..f6381e75b 100644 --- a/plotter/image_example_test.go +++ b/plotter/image_example_test.go @@ -5,6 +5,8 @@ package plotter_test import ( + "image" + "image/color" "image/png" "log" "os" @@ -79,3 +81,22 @@ func ExampleImage_log() { log.Fatalf("error saving image plot: %v\n", err) } } + +// An example of embedding a uniform image in a plot. +func ExampleImage_uniform() { + p := plot.New() + p.Title.Text = "Uniform image" + + img := image.NewUniform(color.RGBA{R: 90, G: 155, B: 212, A: 255}) + p.Add(plotter.NewImage(img, 100, 100, 10000, 10000)) + + const ( + w = 5 * vg.Centimeter + h = 5 * vg.Centimeter + ) + + err := p.Save(w, h, "testdata/image_plot_uniform.png") + if err != nil { + log.Fatalf("error saving image plot: %v\n", err) + } +} diff --git a/plotter/image_test.go b/plotter/image_test.go index 7e6558cc9..0b31f7a07 100644 --- a/plotter/image_test.go +++ b/plotter/image_test.go @@ -17,3 +17,7 @@ func TestImagePlot(t *testing.T) { func TestImagePlot_log(t *testing.T) { cmpimg.CheckPlot(ExampleImage_log, t, "image_plot_log.png") } + +func TestImagePlot_uniform(t *testing.T) { + cmpimg.CheckPlot(ExampleImage_uniform, t, "image_plot_uniform.png") +} diff --git a/plotter/testdata/image_plot_uniform_golden.png b/plotter/testdata/image_plot_uniform_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..e74eeb3700d1e55db0ea38d04a81450cd334e1a3 GIT binary patch literal 6519 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