微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在代码背后渲染图像不起作用?

如何解决为什么在代码背后渲染图像不起作用?

我正在尝试从螺旋控件生成屏幕截图,但仅在后面的代码中-为什么这不起作用? 缺少什么了吗?

private void generate() {

    ModelImporter importer = new ModelImporter();
    Model3D model = importer.Load(@"c:\test\test.obj");

    Model3DGroup group = new Model3DGroup();
    group.Children.Add(model);

    ModelVisual3D myModelVisual3D = new ModelVisual3D();
    myModelVisual3D.Content = group;

    HelixViewport3D viewer = new HelixViewport3D();
    viewer.Children.Add(myModelVisual3D);

    dispatcher.BeginInvoke(new Action(() =>
            {
                rendertargetBitmap bmp = new rendertargetBitmap(1024,768,96,PixelFormats.Pbgra32);
                bmp.Render(viewer);

                PngBitmapEncoder png = new PngBitmapEncoder();
                BitmapFrame frame = BitmapFrame.Create(bmp);
                png.Frames.Add(frame);
                using (Stream stm = File.Create(@"c:\test\test.png"))
                {
                    png.Save(stm);
                }            }
            ),dispatcherPriority.ContextIdle,null);
}

编辑:

无例外-无-代码缝正常工作,但PNG为空。如果我将HelixViewport3D viewer与XAML中的控件交换,则可以生成PNG。使用在代码中定义的HelixViewport3D时,渲染不起作用并且PNG为空-大小可以-它是PNG但没有内容-当我显示它时是透明的。 在这个test.obj文件中没有什么特别的-当我使用XAML定义的HelixViewport3D时-一切都很好。

解决方法

我知道现在有点晚了,但我也不容易找到令人满意的解决方案。

我看到的主要原因是您没有将视口附加到窗口。 如果像我一样根本不想看到任何窗口,有两种解决方案:

  1. hacky 解决方案
  • 将视口置于窗口中
  • 将窗口样式设置为以下内容:
    <Style x:Key="EdgeToEdgeWindowStyle" TargetType="Window">
      <Setter Property="WindowStyle" Value="None" />
      <Setter Property="AllowsTransparency" Value="True" />
      <Setter Property="Left" Value="-10000" />
      <Setter Property="Top" Value="-10000" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Window">
            <AdornerDecorator>
              <ContentPresenter />
            </AdornerDecorator>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  1. 清洁解决方案 按以下方式使用 HostVisual 类
this.hostVisual = new HostVisual();
this.visualTargetPS = new VisualTargetPresentationSource(hostVisual);
this.renderTargetBitmap = new RenderTargetBitmap(width,height,96,PixelFormats.Pbgra32);
this.visualTargetPS.RootVisual = this.viewport;

不会有任何渲染循环,但您可以手动触发渲染调用 this.viewport.InvalidateRender(); 然后每次你想保存一个渲染就调用这个:

this.renderTargetBitmap.Render(this.viewport);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (var stream = new FileStream(this.currentJob.ThumbnailPath,FileMode.Create))
{
 encoder.Save(stream);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。