BitmapImage in UWP

A forum dedicated to UWP version of LightningChart

Moderator: Queue Moderators

kingofthegeeks
Posts: 2
Joined: Wed Aug 18, 2021 11:30 am

BitmapImage in UWP

Post by kingofthegeeks » Wed Dec 01, 2021 3:01 pm

I am having difficulty using a bitmap as an event marker in UWP, may I request a sample showing this implemented please.

Mike
a happy Canadian user !

Arction_LasseP
Posts: 139
Joined: Wed Mar 27, 2019 1:05 pm

Re: BitmapImage in UWP

Post by Arction_LasseP » Thu Dec 02, 2021 8:50 am

Hello Mike,

Bitmaps can be quite complicated, not only in LightningChart but in UWP general.
Basically, there are two ways to get bitmaps working, depending on whether the target object is requiring a BitmapImage or a WriteableBitmap.

Event markers use BitmapImages. To load and use the image, use BitmapImage.UriSource.

Code: Select all

BitmapImage bmi = new BitmapImage();
bmi.UriSource = new Uri("ms-appx:///Resources/capture47.png");
_chart.ViewXY.PointLineSeries[0].SeriesEventMarkers[0].Symbol.BitmapImage = bmi;
Disable Symbol.UseImageSize for the marker if you don't want to use the image's size but Symbols's Width and Height properties instead.
The above requires that the image files are included somewhere in your project, for example in a separate Resources folder. Alternatively, you can use Assets folder that is automatically added to every project.

If you need a WriteableBitmap for example for chart background fill, ImageFromAppContent method under ChartTools is the best option. This has to be used in an async method:

Code: Select all

private async void LoadImages()
{
    _chart.ViewXY.GraphBackground.Style = RectFillStyle.Bitmap;
    _chart.ViewXY.GraphBackground.Bitmap.Layout = BitmapFillLayout.Stretch;
    _chart.ViewXY.GraphBackground.Bitmap.Image = await ChartTools.ImageFromAppContent("Resources/Mesh1.png");
}
There are also other methods such as StorageFile or FileOpenPicker, but the above ones are easier to use.

Note that if you try to load the image file directly from disc (C:\path), you will most like get an error, because by default UWP apps don't have permission to get files from external paths. Enabling broadFileSystemAccess may help in these cases, but you might have to use StorageFile then.

Best regards,
Lasse

kingofthegeeks
Posts: 2
Joined: Wed Aug 18, 2021 11:30 am

Re: BitmapImage in UWP

Post by kingofthegeeks » Tue Dec 07, 2021 5:23 pm

Lasse,

Thank you very much, this does work well for adding a bitmap as an Event Marker however I noticed a problem in my particular situation that requires further help.

I create a chart with all my data and add it to stack panel where I can successfully view it as configured.

Code: Select all

  
var completeChart = reportingChartService.GetPlanPlot(styledChart, analysis, size, scale, units);
stackPanel.Children.Add(completeChart );
unfortunately when I attempt to export that chart as a bitmap for reporting, the event marker bitmap disappears while the label for it is still there. This indicates to me that the marker persists and the bitmap in particular is the issue. If I use any other symbol for the marker it also persists to the exported bitmap.

Code: Select all

var storageFolder = ApplicationData.Current.LocalFolder;
var plotFile = await storageFolder.CreateFileAsync("tempPlotFile.bmp", CreationCollisionOption.ReplaceExisting);
await completeChart .SaveToFileAsync(plotFile, TargetImageFormat.Bmp);
any suggestions ?

Mike

Arction_LasseP
Posts: 139
Joined: Wed Mar 27, 2019 1:05 pm

Re: BitmapImage in UWP

Post by Arction_LasseP » Wed Dec 08, 2021 11:18 am

Hello Mike,

I tried to reproduce the issue but couldn't do so. I created a separate test project which has chart in a StackPanel and a Bitmap marker, then called SaveToFileAsync. The saved image was correct.

The only thing I can think of is the LightningChart version you are using. I was testing this with the newest version 10.1.2.2 (available as a NuGet package). If you are using an earlier version (something before 10.1.2), it could explain this as we have made some changes to image saving in some of the previous versions.

In any case, I'll put the code of my test project here. You can compare this to your code to see if you find any clear differences.

Code: Select all

    public sealed partial class MainPage : Page
    {
        private LightningChart _chart = null;

        public MainPage()
        {
            this.InitializeComponent();

            CreateChart();
        }

        private void CreateChart()
        {
            _chart = new LightningChart();

            _chart.BeginUpdate();

            AxisX ax = new AxisX(_chart.ViewXY);
            _chart.ViewXY.XAxes.Add(ax);

            AxisY ay = new AxisY(_chart.ViewXY);
            _chart.ViewXY.YAxes.Add(ay);

            PointLineSeries pls = new PointLineSeries(_chart.ViewXY, _chart.ViewXY.XAxes[0], _chart.ViewXY.YAxes[0]);
            pls.LineVisible = true;
            pls.PointsVisible = false;

            Random rnd = new Random();
            SeriesPoint[] points = new SeriesPoint[11];
            for (int i = 0; i < 11; i++)
            {
                points[i].X = i;
                points[i].Y = rnd.NextDouble() * 8 + 1;
            }
            pls.Points = points;
            _chart.ViewXY.PointLineSeries.Add(pls);

            SeriesEventMarker marker = new SeriesEventMarker(pls);
            marker.Symbol.UseImageSize = false;
            marker.Symbol.Width = 50;
            marker.Symbol.Height = 50;
            marker.Symbol.Shape = SeriesMarkerPointShape.Bitmap;
            marker.HorizontalPosition = SeriesEventMarkerHorizontalPosition.AtXValue;
            marker.XValue = 4;
            marker.VerticalPosition = SeriesEventMarkerVerticalPosition.TrackSeries;
            pls.SeriesEventMarkers.Add(marker);

            BitmapImage bmi = new BitmapImage();
            bmi.UriSource = new Uri("ms-appx:///Resources/capture47.png");
            _chart.ViewXY.PointLineSeries[0].SeriesEventMarkers[0].Symbol.BitmapImage = bmi;

            _chart.KeyDown += _chart_KeyDown;

            _chart.EndUpdate();

            _chart.MinHeight = 1000;
            _chart.Height = 1000;
            stackPanel.Children.Add(_chart);

            LoadImages();
        }

        private async void LoadImages()
        {
            _chart.ViewXY.GraphBackground.Style = RectFillStyle.Bitmap;
            _chart.ViewXY.GraphBackground.Bitmap.Layout = BitmapFillLayout.Stretch;
            _chart.ViewXY.GraphBackground.Bitmap.Image = await ChartTools.ImageFromAppContent("Resources/Mesh1.png");
        }

        private void _chart_KeyDown(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == Windows.System.VirtualKey.P)
            {
                SaveImage();
            }
        }

        private async void SaveImage()
        {
            StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

            StorageFile sampleFile = await storageFolder.CreateFileAsync("sample.bmp", CreationCollisionOption.ReplaceExisting);

            await _chart.SaveToFileAsync(sampleFile, TargetImageFormat.Bmp);
        }
    }
Best regards,
Lasse