Rendering images through WPF using Pivot as an example
Pivot needs no introduction. If you drive this word into a search for a habr, the result will be 37 articles, among which there are both reviews and tutorials. Therefore, I decided to focus my efforts on only one aspect of working with Pivot - in the pictures.
The convenience of working with Pivot depends heavily on the pictures selected for it. Pictures of low resolution or of different sizes and styles can ruin the whole impression. There are such situations that there are no pictures at all and cannot be, since all the data is in the database in the form of numbers, strings and dates.
There are many ways to programmatically generate pictures from a template. One of them is even built into the PautorLib library , which helps to prepare data in a format that PivotViewer understands. HTML is used there as a template.
In this article I will discuss the solution to the problem using WPF. The template in our case will be UserControl, in which there can be various TextBlock and Image, the properties of which can be set in the code. In order not to be unfounded, let us consider everything with an example.
For an example, information was taken about the first thousand users from the top of the Habr. For this, a bot was written that slowly collected all the data and put it in MongoDB.
A class that takes user information and converts it into a picture looks something like this (pastebin) .
The following pictures were obtained at the output:
In order to achieve such quality of fonts, the following properties must be set in the template:
To render control to a picture, the RenderTargetBitmap class is used . It has its own peculiarity - the output pictures have the inhuman Pbgra32 format. Other formats are not supported. Therefore, you have to additionally run the resulting bitmap through the FormatConvertedBitmap class to get Rgb24 at the output. After that, the result is encoded in PNG via PngBitmapEncoder and saved to a file.
All this happens on a timer ( DispatcherTimer ) and it looks like this - a timer is triggered, a template is filled with new data, a timer is triggered again, a redrawed window with new data is converted into a picture.
All this economy with a timer, a template and a window is launched in a separate STA stream, as required by WPF. The thread, in turn, is triggered by a function call.
As for the speed of such a solution, the main limitation here is the speed of writing to the hard disk.
An example program for generating pictures can be downloaded at the following links: bin , src . There are two keys in the program config. TilesPath contains the path to the folder where the finished pictures will be saved. DemoRender - a binary value that switches the program modes (demo and working). In the demo mode, the pictures are not saved to disk, but are displayed in the window as a slideshow. In the operating mode, the pictures are saved, and the window is hidden.
Well, finally hereYou can find the resulting Pivot. I remind you that this is the first thousand people from the top of the Habr. Through a search, you can search for UserName and DisplayName. The rest of the properties can be filtered, sorted and grouped. Here are some screenshots for those who for one reason or another can not see it: img1 , img2 , img3 , img4 , img5 , img6 .
The convenience of working with Pivot depends heavily on the pictures selected for it. Pictures of low resolution or of different sizes and styles can ruin the whole impression. There are such situations that there are no pictures at all and cannot be, since all the data is in the database in the form of numbers, strings and dates.
There are many ways to programmatically generate pictures from a template. One of them is even built into the PautorLib library , which helps to prepare data in a format that PivotViewer understands. HTML is used there as a template.
In this article I will discuss the solution to the problem using WPF. The template in our case will be UserControl, in which there can be various TextBlock and Image, the properties of which can be set in the code. In order not to be unfounded, let us consider everything with an example.
For an example, information was taken about the first thousand users from the top of the Habr. For this, a bot was written that slowly collected all the data and put it in MongoDB.
A class that takes user information and converts it into a picture looks something like this (pastebin) .
The following pictures were obtained at the output:
In order to achieve such quality of fonts, the following properties must be set in the template:
TextOptions.TextFormattingMode="Display"
RenderOptions.ClearTypeHint="Enabled"
To render control to a picture, the RenderTargetBitmap class is used . It has its own peculiarity - the output pictures have the inhuman Pbgra32 format. Other formats are not supported. Therefore, you have to additionally run the resulting bitmap through the FormatConvertedBitmap class to get Rgb24 at the output. After that, the result is encoded in PNG via PngBitmapEncoder and saved to a file.
All this happens on a timer ( DispatcherTimer ) and it looks like this - a timer is triggered, a template is filled with new data, a timer is triggered again, a redrawed window with new data is converted into a picture.
All this economy with a timer, a template and a window is launched in a separate STA stream, as required by WPF. The thread, in turn, is triggered by a function call.
As for the speed of such a solution, the main limitation here is the speed of writing to the hard disk.
An example program for generating pictures can be downloaded at the following links: bin , src . There are two keys in the program config. TilesPath contains the path to the folder where the finished pictures will be saved. DemoRender - a binary value that switches the program modes (demo and working). In the demo mode, the pictures are not saved to disk, but are displayed in the window as a slideshow. In the operating mode, the pictures are saved, and the window is hidden.
Well, finally hereYou can find the resulting Pivot. I remind you that this is the first thousand people from the top of the Habr. Through a search, you can search for UserName and DisplayName. The rest of the properties can be filtered, sorted and grouped. Here are some screenshots for those who for one reason or another can not see it: img1 , img2 , img3 , img4 , img5 , img6 .