如何最佳地找到WPF控件呈现的最小图像

时间:2018-03-12 07:12:25

标签: wpf bitmap

我正在使用WPF-Math中的FormulaControl为 tek 等式渲染位图。位图将作为内容通过Web服务(松弛)传递。没有桌面组件。我只使用WPF框架尝试从 tek 控件中捕获图像。渲染器组件的代码是

public static class Renderer
{
    private static readonly StaTaskScheduler _StaTaskScheduler = new StaTaskScheduler( 1 );
    public static async Task<string> GenerateImage(string formula)
    {
        string Build()
        {

            var control = new FormulaControl
                          {
                              Formula    = formula
                            , Background = Brushes.White
                          };

            control.Measure(new Size(300, 300));
            control.Arrange(new Rect(new Size(300, 300)));

            var bmp = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);

            bmp.Render(control);

            var encoder = new PngBitmapEncoder();

            encoder.Frames.Add(BitmapFrame.Create(bmp));

            var file = @"test.png";

            using (Stream stm = File.Create(file))
                encoder.Save(stm);

            return file;

        }

        return await Task.Factory.StartNew
            ( Build, CancellationToken.None, TaskCreationOptions.None, _StaTaskScheduler );
    }
}

使用上面的代码和输入

  

k_ {n + 1} = n ^ 2 + k_n ^ 2 - k_ {n-1}

生成以下图片

enter image description here

正如您所看到的,在这种情况下,300x300的任意大小太大,而对于不同的tek输入,它可能太小。

挑战在于为渲染方程生成完全正确大小的位图。怎么办呢?

1 个答案:

答案 0 :(得分:0)

一种解决方案是渲染到大位图,然后自动裁剪空白。

有自动裁剪空白的解决方案

Cropping whitespace from image in C#

使用上面的ImageCrop类,我将渲染代码修改为

public static class Renderer
{
    private static readonly StaTaskScheduler _StaTaskScheduler = new StaTaskScheduler( 1 );

    public static Bitmap Convert( RenderTargetBitmap inmap )
    {
        MemoryStream stream = new MemoryStream();
        BitmapEncoder encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(inmap));
        encoder.Save(stream);

        Bitmap bitmap = new Bitmap(stream);
        return bitmap;
    }

    public static async Task<string> GenerateImage(string formula)
    {
        string Build()
        {

            var control = new FormulaControl
                          {
                              Formula    = formula
                            , Background = Brushes.White
                          };

            control.Measure(new Size(300, 300));
            control.Arrange(new Rect(new Size(300, 300)));

            var bmp = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);

            bmp.Render(control);

            var image = ImageCrop.AutoCrop( Convert( bmp ) );
            var file = @"test.png";
            image.Save( file,ImageFormat.Png );
            return file;

        }

        return await Task.Factory.StartNew
            ( Build, CancellationToken.None, TaskCreationOptions.None, _StaTaskScheduler );
    }
}

我的slackbot中的输出现在完全裁剪。

enter image description here

显然这并不完美,因为渲染大小有一个上限。