예제 #1
0
        /// <summary>
        /// Updates the image.
        /// </summary>
        private void UpdateImage()
        {
            // determine if the provided data should be reversed in x-direction
            var reverseX = this.XAxis.Transform(this.X0) > this.XAxis.Transform(this.X1);

            // determine if the provided data should be reversed in y-direction
            var reverseY = this.YAxis.Transform(this.Y0) > this.YAxis.Transform(this.Y1);

            // determine if the data should be transposed
            var swapXY = this.IsTransposed();

            int m      = this.Data.GetLength(0);
            int n      = this.Data.GetLength(1);
            var buffer = swapXY ? new OxyColor[n, m] : new OxyColor[m, n];

            for (int i = 0; i < m; i++)
            {
                var ii = reverseX ? m - 1 - i : i;
                for (int j = 0; j < n; j++)
                {
                    var jj = reverseY ? n - 1 - j : j;
                    if (swapXY)
                    {
                        buffer[j, i] = this.ColorAxis.GetColor(this.Data[ii, jj]);
                    }
                    else
                    {
                        buffer[i, j] = this.ColorAxis.GetColor(this.Data[ii, jj]);
                    }
                }
            }

            this.image = OxyImage.Create(buffer, ImageFormat.Png);
        }
예제 #2
0
        /// <summary>
        /// Renders the icon on the specified render context.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="size">The size.</param>
        public override void Render(IRenderContext rc, double size)
        {
            var n       = (int)size * 2;
            var data    = ArrayHelper.Evaluate(Functions.Peaks, ArrayHelper.CreateVector(-3.1, 2.6, n), ArrayHelper.CreateVector(3.0, -3.4, n));
            var c       = OxyColor.FromArgb(255, 90, 165, 200);
            var palette = OxyPalette.Interpolate(5, OxyColors.White, c, OxyColors.White);
            var min     = data.Min2D();
            var max     = data.Max2D();
            var pixels  = new OxyColor[n, n];

            for (int x = 0; x < n; x++)
            {
                for (int y = 0; y < n; y++)
                {
                    var i = (int)((data[x, y] - min) / (max - min) * palette.Colors.Count);
                    i = Math.Min(Math.Max(i, 0), palette.Colors.Count - 1);
                    pixels[y, n - 1 - x] = palette.Colors[i];
                }
            }

            var image = OxyImage.Create(pixels, OxyPlot.ImageFormat.Png);

            // fix image interpolation artifacts on the edge
            rc.DrawImage(image, 0, 0, n, n, 0, 0, size, size, 1, true);
            rc.DrawRectangle(new OxyRect(0, 0, size, 2), c, OxyColors.Undefined, 0);
            rc.DrawRectangle(new OxyRect(0, size - 1, size, 1), c, OxyColors.Undefined, 0);
            rc.DrawRectangle(new OxyRect(0, 0, 2, size), c, OxyColors.Undefined, 0);
            rc.DrawRectangle(new OxyRect(size - 1, 0, 1, size), c, OxyColors.Undefined, 0);
        }
예제 #3
0
        /// <summary>
        /// Renders the icon on the specified render context.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="size">The size.</param>
        public override void Render(IRenderContext rc, double size)
        {
            var n       = (int)size * 2;
            var data    = ArrayHelper.Evaluate(Functions.Peaks, ArrayHelper.CreateVector(-3.1, 2.6, n), ArrayHelper.CreateVector(3.0, -3.4, n));
            var palette = OxyPalettes.BlueWhiteRed(5);
            var min     = data.Min2D();
            var max     = data.Max2D();
            var pixels  = new OxyColor[n, n];

            for (int x = 0; x < n; x++)
            {
                for (int y = 0; y < n; y++)
                {
                    var i = (int)((data[x, y] - min) / (max - min) * palette.Colors.Count);
                    i = Math.Min(Math.Max(i, 0), palette.Colors.Count - 1);
                    pixels[y, n - 1 - x] = palette.Colors[i];
                }
            }

            var image = OxyImage.Create(pixels, OxyPlot.ImageFormat.Png);

            rc.DrawImage(image, 0, 0, n, n, 0, 0, size, size, 1, true);

            var frameWidth = (int)Math.Max(Math.Round(size / 32), 1);

            rc.DrawRectangle(new OxyRect(0, 0, size, frameWidth), OxyColors.Black, OxyColors.Black, 0);
            rc.DrawRectangle(new OxyRect(0, size - frameWidth, size, frameWidth), OxyColors.Black, OxyColors.Undefined, 0);
            rc.DrawRectangle(new OxyRect(0, 0, frameWidth, size), OxyColors.Black, OxyColors.Undefined, 0);
            rc.DrawRectangle(new OxyRect(size - frameWidth, 0, frameWidth, size), OxyColors.Black, OxyColors.Undefined, 0);
        }
예제 #4
0
        public override void Render(IRenderContext rc)
        {
            var origin = XAxis.InverseTransform(XAxis.ScreenMin.X, YAxis.ScreenMin.Y, YAxis);
            var end    = XAxis.InverseTransform(XAxis.ScreenMax.X, YAxis.ScreenMax.Y, YAxis);

            var state = new BufferState
            {
                MinX   = origin.X,
                MaxX   = end.X,
                MinY   = origin.Y,
                MaxY   = end.Y,
                Width  = XAxis.ScreenMax.X - XAxis.ScreenMin.X,
                Height = YAxis.ScreenMax.Y - YAxis.ScreenMin.Y
            };

            if (!state.Equals(_buffer))
            {
                var g      = Math.Max(1, (Int32)Math.Sqrt(state.Width * state.Height / 50000.0));
                var width  = (Int32)state.Width / g;
                var height = (Int32)state.Height / g;
                var scaleX = (XAxis.ScreenMax.X - XAxis.ScreenMin.X) / width;
                var scaleY = (YAxis.ScreenMax.Y - YAxis.ScreenMin.Y) / height;
                var pixels = new OxyColor[width, height];
                _buffer.ReplaceWith(state);

                var dx = (end.X - origin.X) / width;
                var dy = (end.Y - origin.Y) / height;
                var sx = XAxis.ScreenMin.X;
                var z  = new ScalarValue(origin.X, 0.0);

                for (var i = 0; i < width; i++)
                {
                    var sy = YAxis.ScreenMin.Y;
                    z.ImaginaryValue = origin.Y;

                    for (var j = 0; j < height; j++)
                    {
                        var value = _f(z);
                        pixels[i, j]      = value.GetColor();
                        sy               += scaleY;
                        z.ImaginaryValue += dy;
                    }

                    z.Value += dx;
                    sx      += scaleX;
                }

                _points = OxyImage.Create(pixels, ImageFormat.Png);
            }

            rc.DrawImage(_points, XAxis.ScreenMin.X, YAxis.ScreenMin.Y, state.Width, state.Height, 1.0, true);
        }
예제 #5
0
        private static OxyImage CreateImage()
        {
            var data = new OxyColor[4, 2];

            data[0, 0] = OxyColors.Blue;
            data[1, 0] = OxyColors.Green;
            data[2, 0] = OxyColors.Red;
            data[3, 0] = OxyColors.White;
            data[0, 1] = OxyColors.Transparent;
            data[3, 1] = OxyColor.FromAColor(127, OxyColors.Yellow);
            data[1, 1] = OxyColor.FromAColor(127, OxyColors.Orange);
            data[2, 1] = OxyColor.FromAColor(127, OxyColors.Pink);
            return(OxyImage.Create(data, ImageFormat.Png));
        }
예제 #6
0
        public void Create_SmallImageToPng()
        {
            var data = new OxyColor[2, 4];

            data[1, 0] = OxyColors.Blue;
            data[1, 1] = OxyColors.Green;
            data[1, 2] = OxyColors.Red;
            data[1, 3] = OxyColors.White;
            data[0, 0] = OxyColor.FromAColor(127, OxyColors.Yellow);
            data[0, 1] = OxyColor.FromAColor(127, OxyColors.Orange);
            data[0, 2] = OxyColor.FromAColor(127, OxyColors.Pink);
            data[0, 3] = OxyColors.Transparent;
            var img   = OxyImage.Create(data, ImageFormat.Png);
            var bytes = img.GetData();

            File.WriteAllBytes(@"Imaging\SmallImage.png", bytes);
        }
예제 #7
0
        public void Discussion453825_100()
        {
            var data = new byte[100, 100];
            int k    = 0;

            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    data[i, j] = (byte)(k++ % 256);
                }
            }

            var palette = OxyPalettes.Gray(256).Colors.ToArray();
            var im      = OxyImage.Create(data, palette, ImageFormat.Bmp);

            File.WriteAllBytes(@"Imaging\Discussion453825.bmp", im.GetData());
        }
예제 #8
0
        public void LargeImageTest(bool interpolate)
        {
            // this is a test of the DrawImage function; don't add pointless backgrounds to your plots

            var plotModel = CreateTestModel1();

            var pixelData = new OxyColor[5, 5];

            for (int i = 0; i < pixelData.GetLength(0); i++)
            {
                for (int j = 0; j < pixelData.GetLength(1); j++)
                {
                    pixelData[i, j] = OxyColor.FromArgb(255, 128, (byte)((i * 255) / pixelData.GetLength(0)), (byte)((j * 255) / pixelData.GetLength(1)));
                }
            }

            var oxyImage        = OxyImage.Create(pixelData, ImageFormat.Png);
            var imageAnnotation = new ImageAnnotation()
            {
                ImageSource         = oxyImage,
                X                   = new PlotLength(-1, PlotLengthUnit.RelativeToViewport),
                Y                   = new PlotLength(-1, PlotLengthUnit.RelativeToViewport),
                Width               = new PlotLength(3, PlotLengthUnit.RelativeToViewport),
                Height              = new PlotLength(3, PlotLengthUnit.RelativeToViewport),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment   = VerticalAlignment.Top,
                Interpolate         = interpolate
            };

            plotModel.Annotations.Add(imageAnnotation);

            var fileName = Path.Combine(this.outputDirectory, $"LargeImage{(interpolate ? "Interpolated" : "Pixelated")}.png");
            var exporter = new PngExporter {
                Width = 400, Height = 300
            };

            using (var stream = File.OpenWrite(fileName))
            {
                exporter.Export(plotModel, stream);
            }

            Assert.IsTrue(File.Exists(fileName));
        }
예제 #9
0
        public void Create_LargeImageToPng()
        {
            int w    = 266;
            int h    = 40;
            var data = new OxyColor[w, h];

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    data[x, y] = OxyColor.FromHsv((double)x / w, 1, 1);
                }
            }

            var img   = OxyImage.Create(data, ImageFormat.Png);
            var bytes = img.GetData();

            File.WriteAllBytes(@"Imaging\LargeImage.png", bytes);
        }
예제 #10
0
        /// <summary>
        /// Generates the image used to render the color axis.
        /// </summary>
        /// <param name="reverse">Reverse the colors if set to <c>true</c>.</param>
        /// <returns>An <see cref="OxyImage" /> used to render the color axis.</returns>
        private OxyImage GenerateColorAxisImage(bool reverse)
        {
            int n      = this.Palette.Colors.Count;
            var buffer = this.IsHorizontal() ? new OxyColor[n, 1] : new OxyColor[1, n];

            for (var i = 0; i < n; i++)
            {
                var color = this.Palette.Colors[i];
                var i2    = reverse ? n - 1 - i : i;
                if (this.IsHorizontal())
                {
                    buffer[i2, 0] = color;
                }
                else
                {
                    buffer[0, i2] = color;
                }
            }

            return(OxyImage.Create(buffer, ImageFormat.Png));
        }
예제 #11
0
        public void Create_Indexed8bitToBmp()
        {
            var data = new byte[, ] {
                { 0, 1, 2, 3 }, { 4, 5, 6, 7 }
            };

            var palette = new OxyColor[8];

            palette[4] = OxyColors.Blue;
            palette[5] = OxyColors.Green;
            palette[6] = OxyColors.Red;
            palette[7] = OxyColors.White;
            palette[0] = OxyColor.FromAColor(127, OxyColors.Yellow);
            palette[1] = OxyColor.FromAColor(127, OxyColors.Orange);
            palette[2] = OxyColor.FromAColor(127, OxyColors.Pink);
            palette[3] = OxyColors.Transparent;
            var img   = OxyImage.Create(data, palette, ImageFormat.Bmp);
            var bytes = img.GetData();

            File.WriteAllBytes(@"Imaging\FromIndexed8.bmp", bytes);
        }
예제 #12
0
        public void Discussion453825_199()
        {
            int w     = 199;
            int h     = 256;
            var data  = new byte[h, w];
            var data2 = new byte[h * w];

            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    data[i, j]         = (byte)(i % 256);
                    data2[(i * w) + j] = (byte)(i % 256);
                }
            }

            var palette1 = OxyPalettes.Gray(256).Colors.ToArray();
            var im1      = OxyImage.Create(data, palette1, ImageFormat.Bmp);
            var bytes1   = im1.GetData();

            // The images should show a gradient image 199x256 - black at the bottom, white at the top
            File.WriteAllBytes(@"Imaging\Discussion453825_199a.bmp", bytes1);
        }
        public static PlotModel ImageAnnotation_ReverseVerticalAxis()
        {
            var model = new PlotModel {
                Title = "ImageAnnotation - reverse vertical axis"
            };

            model.Axes.Add(new LinearAxis {
                Position = AxisPosition.Bottom
            });
            model.Axes.Add(new LinearAxis {
                Position = AxisPosition.Left, StartPosition = 1, EndPosition = 0
            });

            // create an image
            var pixels = new OxyColor[2, 2];

            pixels[0, 0] = OxyColors.Blue;
            pixels[1, 0] = OxyColors.Yellow;
            pixels[0, 1] = OxyColors.Green;
            pixels[1, 1] = OxyColors.Red;

            var image = OxyImage.Create(pixels, ImageFormat.Png);

            model.Annotations.Add(
                new ImageAnnotation
            {
                ImageSource         = image,
                Interpolate         = false,
                X                   = new PlotLength(0, PlotLengthUnit.Data),
                Y                   = new PlotLength(100, PlotLengthUnit.Data),
                Width               = new PlotLength(80, PlotLengthUnit.Data),
                Height              = new PlotLength(50, PlotLengthUnit.Data),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment   = VerticalAlignment.Bottom
            });
            return(model);
        }
        public static PlotModel ImageAnnotationAsBackgroundGradient()
        {
            // http://en.wikipedia.org/wiki/Chartjunk
            var model = new PlotModel {
                Title = "Using ImageAnnotations to draw a gradient backgrounds", Subtitle = "But do you really want this? This is called 'chartjunk'!", PlotMargins = new OxyThickness(60, 4, 4, 60)
            };

            model.Axes.Add(new LinearAxis {
                Position = AxisPosition.Bottom
            });
            model.Axes.Add(new LinearAxis {
                Position = AxisPosition.Left
            });

            // create a gradient image of height n
            int n          = 256;
            var imageData1 = new OxyColor[1, n];

            for (int i = 0; i < n; i++)
            {
                imageData1[0, i] = OxyColor.Interpolate(OxyColors.Blue, OxyColors.Red, i / (n - 1.0));
            }

            var image1 = OxyImage.Create(imageData1, ImageFormat.Png); // png is required for silverlight

            // or create a gradient image of height 2 (requires bitmap interpolation to be supported)
            var imageData2 = new OxyColor[1, 2];

            imageData2[0, 0] = OxyColors.Yellow;                       // top color
            imageData2[0, 1] = OxyColors.Gray;                         // bottom color

            var image2 = OxyImage.Create(imageData2, ImageFormat.Png); // png is required for silverlight

            // gradient filling the viewport
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource         = image2,
                Interpolate         = true,
                Layer               = AnnotationLayer.BelowAxes,
                X                   = new PlotLength(0, PlotLengthUnit.RelativeToViewport),
                Y                   = new PlotLength(0, PlotLengthUnit.RelativeToViewport),
                Width               = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
                Height              = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment   = VerticalAlignment.Top
            });

            // gradient filling the plot area
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource         = image1,
                Interpolate         = true,
                Layer               = AnnotationLayer.BelowAxes,
                X                   = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
                Y                   = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
                Width               = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
                Height              = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment   = VerticalAlignment.Top
            });

            // verify that a series is rendered above the gradients
            model.Series.Add(new FunctionSeries(Math.Sin, 0, 7, 0.01));

            return(model);
        }
예제 #15
0
        /// <summary>
        /// Renders the series on the specified render context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        /// <param name="model">The model.</param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            if (this.Matrix == null)
            {
                return;
            }

            int m  = this.Matrix.GetLength(0);
            int n  = this.Matrix.GetLength(1);
            var p0 = this.Transform(0, 0);
            var p1 = this.Transform(n, m);

            // note matrix index [i,j] maps to image index [j,i]
            if (this.image == null)
            {
                var pixels = new OxyColor[n, m];
                for (int i = 0; i < m; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        pixels[j, i] = Math.Abs(this.Matrix[i, j]) <= this.ZeroTolerance ? OxyColors.Transparent : this.NotZeroColor;
                    }
                }

                this.image = OxyImage.Create(pixels, ImageFormat.Png);
            }

            var clip = this.GetClippingRect();
            var x0   = Math.Min(p0.X, p1.X);
            var y0   = Math.Min(p0.Y, p1.Y);
            var w    = Math.Abs(p0.X - p1.X);
            var h    = Math.Abs(p0.Y - p1.Y);

            rc.DrawClippedImage(clip, this.image, x0, y0, w, h, 1, false);

            var points = new List <ScreenPoint>();

            if (this.GridInterval > 0)
            {
                var p2 = this.Transform(this.GridInterval, this.GridInterval);
                if (Math.Abs(p2.Y - p0.Y) > this.MinimumGridLineDistance)
                {
                    for (int i = 1; i < n; i += this.GridInterval)
                    {
                        points.Add(this.Transform(0, i));
                        points.Add(this.Transform(n, i));
                    }
                }

                if (Math.Abs(p2.X - p0.X) > this.MinimumGridLineDistance)
                {
                    for (int j = 1; j < m; j += this.GridInterval)
                    {
                        points.Add(this.Transform(j, 0));
                        points.Add(this.Transform(j, m));
                    }
                }
            }

            if (this.ShowDiagonal)
            {
                points.Add(this.Transform(0, 0));
                points.Add(this.Transform(n, m));
            }

            rc.DrawClippedLineSegments(clip, points, this.GridColor, 1, null, OxyPenLineJoin.Miter, true);

            if (this.BorderColor.IsVisible())
            {
                var borderPoints = new[]
                {
                    this.Transform(0, 0),
                    this.Transform(m, 0),
                    this.Transform(0, n),
                    this.Transform(m, n),
                    this.Transform(0, 0),
                    this.Transform(0, n),
                    this.Transform(m, 0),
                    this.Transform(m, n)
                };

                rc.DrawClippedLineSegments(clip, borderPoints, this.BorderColor, 1, null, OxyPenLineJoin.Miter, true);
            }
        }
예제 #16
0
        /// <summary>
        /// Renders by scaling a fixed image.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="model">The model.</param>
        public void RenderFixed(IRenderContext rc, PlotModel model)
        {
            if (image == null)
            {
                int m = this.Data.GetLength(0);
                int n = this.Data.GetLength(1);

                int width  = this.ImageSize;
                int height = this.ImageSize;
                if (this.pixels == null || this.pixels.GetLength(0) != height || this.pixels.GetLength(1) != width)
                {
                    this.pixels = new OxyColor[width, height];
                }

                var p = this.pixels;
                for (int yi = 0; yi < height; yi++)
                {
                    for (int xi = 0; xi < width; xi++)
                    {
                        double x = (xi - width * 0.5) / (width * 0.5) * this.Magnitude1;
                        double y = -(yi - height * 0.5) / (height * 0.5) * this.Magnitude1;

                        double angle     = Math.Atan2(y, x) / Math.PI * 180;
                        double magnitude = Math.Sqrt(x * x + y * y);

                        while (angle < 0)
                        {
                            angle += 360;
                        }
                        while (angle > 360)
                        {
                            angle -= 360;
                        }

                        // transform to indices in the Data array
                        var ii = (angle - this.Angle0) / (this.Angle1 - this.Angle0) * m;
                        var jj = (magnitude - this.Magnitude0) / (this.Magnitude1 - this.Magnitude0) * n;
                        if (ii >= 0 && ii < m && jj >= 0 && jj < n)
                        {
                            // get the (interpolated) value
                            var value = this.GetValue(ii, jj);

                            // use the color axis to get the color
                            p[xi, yi] = OxyColor.FromAColor(160, this.ColorAxis.GetColor(value));
                        }
                        else
                        {
                            // outside the range of the Data array
                            p[xi, yi] = OxyColors.Transparent;
                        }
                    }
                }

                // Create the PNG image
                this.image = OxyImage.Create(p, ImageFormat.Png);
            }

            OxyRect dest;

            if (this.PlotModel.PlotType != PlotType.Polar)
            {
                var topleft     = this.Transform(-this.Magnitude1, this.Magnitude1);
                var bottomright = this.Transform(this.Magnitude1, -this.Magnitude1);
                dest = new OxyRect(topleft.X, topleft.Y, bottomright.X - topleft.X, bottomright.Y - topleft.Y);
            }
            else
            {
                var top    = this.Transform(this.Magnitude1, 90);
                var bottom = this.Transform(this.Magnitude1, 270);
                var left   = this.Transform(this.Magnitude1, 180);
                var right  = this.Transform(this.Magnitude1, 0);
                dest = new OxyRect(left.X, top.Y, right.X - left.X, bottom.Y - top.Y);
            }

            // Render the image
            var clip = this.GetClippingRect();

            rc.DrawClippedImage(clip, this.image, dest.Left, dest.Top, dest.Width, dest.Height, 1, false);
        }
예제 #17
0
        /// <summary>
        /// Renders by an image sized from the available plot area.
        /// </summary>
        /// <param name="rc">The rc.</param>
        /// <param name="model">The model.</param>
        public void RenderDynamic(IRenderContext rc, PlotModel model)
        {
            int m = this.Data.GetLength(0);
            int n = this.Data.GetLength(1);

            // get the available plot area
            var dest   = model.PlotArea;
            int width  = (int)dest.Width;
            int height = (int)dest.Height;

            if (width == 0 || height == 0)
            {
                return;
            }

            if (this.pixels == null || this.pixels.GetLength(0) != height || this.pixels.GetLength(1) != width)
            {
                this.pixels = new OxyColor[width, height];
            }

            var p = this.pixels;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // transform from screen to magnitude/angle
                    var    sp = new ScreenPoint(dest.Left + x, dest.Top + y);
                    var    xy = this.InverseTransform(sp);
                    double angle;
                    double magnitude;
                    if (this.PlotModel.PlotType != PlotType.Polar)
                    {
                        angle     = Math.Atan2(xy.Y, xy.X) / Math.PI * 180;
                        magnitude = Math.Sqrt((xy.X * xy.X) + (xy.Y * xy.Y));
                    }
                    else
                    {
                        angle     = xy.Y / Math.PI * 180;
                        magnitude = xy.X;
                        while (angle < 0)
                        {
                            angle += 360;
                        }
                        while (angle > 360)
                        {
                            angle -= 360;
                        }
                    }

                    // transform to indices in the Data array
                    var ii = (angle - this.Angle0) / (this.Angle1 - this.Angle0) * m;
                    var jj = (magnitude - this.Magnitude0) / (this.Magnitude1 - this.Magnitude0) * n;
                    if (ii >= 0 && ii < m && jj >= 0 && jj < n)
                    {
                        // get the (interpolated) value
                        var value = this.GetValue(ii, jj);

                        // use the color axis to get the color
                        p[x, y] = OxyColor.FromAColor(160, this.ColorAxis.GetColor(value));
                    }
                    else
                    {
                        // outside the range of the Data array
                        p[x, y] = OxyColors.Transparent;
                    }
                }
            }

            // Create the PNG image
            this.image = OxyImage.Create(p, ImageFormat.Png);

            // Render the image
            var clip = this.GetClippingRect();

            rc.DrawClippedImage(clip, this.image, dest.Left, dest.Top, dest.Width, dest.Height, 1, false);
        }