Inserting a bitmap into axes

Oystein Bjorke 10 years ago 0
This discussion was imported from CodePlex

willmoore88 wrote at 2013-07-24 14:37:

I need to be able to use oxyplot axes, but insert a bitmap that I have already drawn into the graph rather than any other series. This is because the oxyplot axes work perfectly but without drawing the bitmap myself, I would be trying to plot over 20 million points and its too much for this library to handle satisfactorily for me.

Is there anyway I can achieve this? The bitmap would be drawn to the correct scale etc, so would just need to be placed at 0,0 on the graph and sized to the size of the plot and all should be correct.

raphay wrote at 2013-07-24 15:02:

Have you tried with the image annotation ? It sounds to fit with your problem.

willmoore88 wrote at 2013-07-24 15:59:

I haven't. Any pointers? Is there an example?

raphay wrote at 2013-07-24 16:55:

There is an official example here : http://www.oxyplot.org/examplebrowser (in the annotation category).


Here is the source code (from oxyplot) :
[Example("ImageAnnotations")]
        public static PlotModel ImageAnnotations()
        {
            var model = new PlotModel("ImageAnnotations") { PlotMargins = new OxyThickness(60, 4, 4, 60) };
            model.Axes.Add(new LinearAxis(AxisPosition.Bottom));
            model.Axes.Add(new LinearAxis(AxisPosition.Left));

            OxyImage image;
            var assembly = Assembly.GetExecutingAssembly();
            using (var stream = assembly.GetManifestResourceStream("ExampleLibrary.Resources.OxyPlot.png"))
            {
                image = new OxyImage(stream);
            }

            // Centered in plot area, filling width
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                Opacity = 0.2,
                Interpolate = false,
                X = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
                Y = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
                Width = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Middle
            });

            // Relative to plot area, inside top/right corner, 120pt wide
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                X = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
                Y = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
                Width = new PlotLength(120, PlotLengthUnit.ScreenUnits),
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top
            });

            // Relative to plot area, above top/left corner, 20pt high
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                X = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
                Y = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
                OffsetY = new PlotLength(-5, PlotLengthUnit.ScreenUnits),
                Height = new PlotLength(20, PlotLengthUnit.ScreenUnits),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Bottom
            });

            // At the point (50,50), 200pt wide
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                X = new PlotLength(50, PlotLengthUnit.Data),
                Y = new PlotLength(50, PlotLengthUnit.Data),
                Width = new PlotLength(200, PlotLengthUnit.ScreenUnits),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top
            });

            // At the point (50,20), 50 x units wide
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                X = new PlotLength(50, PlotLengthUnit.Data),
                Y = new PlotLength(20, PlotLengthUnit.Data),
                Width = new PlotLength(50, PlotLengthUnit.Data),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top
            });

            // Relative to the viewport, centered at the bottom, with offset (could also use bottom vertical alignment)
            model.Annotations.Add(new ImageAnnotation
            {
                ImageSource = image,
                X = new PlotLength(0.5, PlotLengthUnit.RelativeToViewport),
                Y = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
                OffsetY = new PlotLength(-35, PlotLengthUnit.ScreenUnits),
                Height = new PlotLength(30, PlotLengthUnit.ScreenUnits),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top
            });

            // Changing opacity
            for (int y = 0; y < 10; y++)
            {
                model.Annotations.Add(
                    new ImageAnnotation
                        {
                            ImageSource = image,
                            Opacity = (y + 1) / 10.0,
                            X = new PlotLength(10, PlotLengthUnit.Data),
                            Y = new PlotLength(y * 2, PlotLengthUnit.Data),
                            Width = new PlotLength(100, PlotLengthUnit.ScreenUnits),
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment = VerticalAlignment.Bottom
                        });
            }

            return model;
        }
I think in your case, it's the image annotation bind to a point that will be usefull.

willmoore88 wrote at 2013-07-24 17:33:

Thanks very much, this is definitely what I was looking for.

How do I get load a locally saved image (bitmap) into the OxyImage then?

raphay wrote at 2013-07-25 09:14:

Use this code :
OxyImage image;
using (FileStream stream = new FileStream(PathOfYourImage, FileMode.Open))
{
          image = new OxyImage(stream);
 }

willmoore88 wrote at 2013-07-25 09:53:

Is It possible to use a System.Drawing.Bitmap?

Basically I draw my bitmap, and can save it as a file, but would be quicker if I just used the one stored in memory.
Bitmap b = makeBitmap(scatter);

BlindMonk wrote at 2013-07-25 12:32:

Well, i added a bitmapimage, but I cant make it zoom. which property am i missing?

thanks a lot

raphay wrote at 2013-07-25 13:20:

willmoore88 wrote:
Is It possible to use a System.Drawing.Bitmap?

Basically I draw my bitmap, and can save it as a file, but would be quicker if I just used the one stored in memory.
Bitmap b = makeBitmap(scatter);
Save your bitmap in a stream and then use this stream to create your OxyImage
b.Save(Stream, ImageFormat);
image = new OxyImage(Stream);