Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Configuration;
- using System.IO;
- using System.Threading;
- using System.Windows;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Threading;
- namespace WPFRenderDemo
- {
- public class TileRenderer
- {
- private string outputPath;
- private bool isDemoMode;
- private Window win;
- private DispatcherTimer timer;
- private TileTemplate tileTemplate;
- private int counter;
- public void Start()
- {
- // Папка, в которую будут сохранены отрисованные картинки
- this.outputPath = ConfigurationManager.AppSettings["TilesPath"];
- // В режиме демонстрации картинки отображаются в окне с интервалом в 1с
- // В рабочем режиме окно прячется и картинки сохраняются на диск
- this.isDemoMode = bool.Parse(ConfigurationManager.AppSettings["DemoRender"]);
- if (!this.isDemoMode)
- // Создает папку, если она не сужествует и удаляет из нее все файлы *.png
- ClearOutputDirectory();
- // Для запуска WPF нужен поток с SingleThreadApartment
- // Создаем такой потов, в котором будет выполняться вся отрисовка
- var thread = new Thread(Run);
- thread.SetApartmentState(ApartmentState.STA);
- thread.Start();
- }
- private void Run()
- {
- // Начало STAThread
- this.win = new Window();
- this.win.SizeToContent = SizeToContent.WidthAndHeight;
- this.win.Loaded += Loaded;
- // В рабочем режиме окно нужно прятать,
- // чтобы ускорить процесс отрисовки
- if (!this.isDemoMode)
- this.win.Visibility = Visibility.Hidden;
- // Добавляем UserControl с шаблоном для картинок
- // В нашем случае - это Grid с единственным TextBlock
- this.tileTemplate = new TileTemplate();
- this.win.Content = tileTemplate;
- // Запускаем приложение, после этого должно появиться наше окно
- var app = new Application();
- app.Run(win);
- }
- private void Loaded(object sender, RoutedEventArgs e)
- {
- // Окно загружено, теперь создаем таймер,
- // по которому будет срабатывать отрисовка
- // В рабочем режиме таймаут должен быть минимальным,
- // чтобы ускорить процесс отрисовки
- TimeSpan timeout = new TimeSpan(1);
- // В демонстрационном режиме таймаут выбран так,
- // чтобы можно было успеть разглядеть каждую картинку
- if (this.isDemoMode)
- timeout = TimeSpan.FromSeconds(1);
- this.timer = new DispatcherTimer(
- timeout,
- DispatcherPriority.Background,
- Tick,
- win.Dispatcher);
- this.timer.Start();
- }
- private void Tick(object sender, EventArgs args)
- {
- // После срабатывания таймера окно перерисовывается
- // и можно сохранять его содержимое в виде картинки
- // Сохранение происходит только в рабочем режиме
- if (!this.isDemoMode)
- {
- string fileName = string.Format(@"{0}\{1}.png", this.outputPath, this.counter++);
- Save(fileName);
- }
- // После сотой картинки приложение будет завершено
- if (this.counter >= 100)
- {
- this.timer.Stop();
- this.win.Close();
- }
- // Подготавливаем окно, передавая нашему UserControl
- // новые данные. В данном случае это случайные значения
- // цветовых каналов.
- var random = new Random();
- var rgb = new byte[3];
- random.NextBytes(rgb);
- this.tileTemplate.Fill(rgb[0], rgb[1], rgb[2]);
- }
- private void Save(string fileName)
- {
- // RenderTargetBitmap позволяет перевести любой
- // контрол WPF в bitmap.
- // В конструктор передаются размеры итогового bitmap,
- // его разрешение и формат
- var bitmap = new RenderTargetBitmap(320, 240, 96, 96,
- PixelFormats.Default);
- bitmap.Render(tileTemplate);
- // Так как из всех форматов поддерживается только
- // Pbgra32, его нужно перевести в человеческий Rgb24
- // Для этого воспользуемся специальным конвертером
- var formatConv = new FormatConvertedBitmap();
- formatConv.BeginInit();
- formatConv.Source = bitmap;
- formatConv.DestinationFormat = PixelFormats.Rgb24;
- formatConv.EndInit();
- // После всего этого bitmap можно сохранять в PNG
- var encoder = new PngBitmapEncoder();
- encoder.Frames.Add(BitmapFrame.Create(formatConv));
- using (var stream = File.Create(fileName))
- {
- encoder.Save(stream);
- }
- }
- private void ClearOutputDirectory()
- {
- var outputDir = new DirectoryInfo(this.outputPath);
- if (!outputDir.Exists)
- outputDir.Create();
- var oldTiles = outputDir.GetFiles("*.png");
- foreach (var tile in oldTiles)
- tile.Delete();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement