<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【W(wǎng)PF】使用RenderTargetBitmap截圖的時候位置出現(xiàn)偏移的一些解決辦法

      簡介

      在WPF中,如果你需要把控件的渲染畫面保存到圖片,那么唯一的選擇就是RenderTargetBitmap。
      不過,RenderTargetBitmap是個比較難伺候的主,有時候你以為能工作,但實際上不能;你以為能夠正常截圖,但實際上截出來的圖片是歪的。
      所以,我總結(jié)一下自己項目中遇到的坑和解決辦法吧!

      保存的圖片是黑色的

      這種情況下,通常是WPF的RenderTargetBitmap無法正確獲取視覺對象的渲染結(jié)果,我比較建議在需要截圖的控件之上包裝一層Border。

      例如:

      <ux:RarityRibbon Background="{Binding Background, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   Foreground="{Binding Foreground, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   RarityStarColor="{Binding Stroke, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   Title="{Binding Name, Mode=OneWay}"
                                   Value="{Binding Value, Mode=OneWay}"
                                   Level="{Binding Level, Mode=OneWay}"
                                   Margin="0">
                      <ux:RarityRibbon.MaskedBrush>
                          <ImageBrush ImageSource="{Binding Image, Mode=OneWay, Converter={x:Static wf:Converters.Icon}}"
                                      Stretch="Uniform"
                                      Viewbox="0.1 0.1 0.5 0.5"
                                      Opacity="0.15" />
                      </ux:RarityRibbon.MaskedBrush>
                  </ux:RarityRibbon>
      
      

      要截圖的是ux:RarityRibbon控件,但保存的圖片是純黑的。
      這時候,要做的就是在ux:RarityRibbon控件之上,包裝一層Border,然后把截圖對象改成Border即可。

      
        <Border x:Name="Container">
                  <ux:RarityRibbon Background="{Binding Background, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   Foreground="{Binding Foreground, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   RarityStarColor="{Binding Stroke, Mode=OneWay, Converter={x:Static wf:Converters.StringToBrush}}"
                                   Title="{Binding Name, Mode=OneWay}"
                                   Value="{Binding Value, Mode=OneWay}"
                                   Level="{Binding Level, Mode=OneWay}"
                                   Margin="0">
                      <ux:RarityRibbon.MaskedBrush>
                          <ImageBrush ImageSource="{Binding Image, Mode=OneWay, Converter={x:Static wf:Converters.Icon}}"
                                      Stretch="Uniform"
                                      Viewbox="0.1 0.1 0.5 0.5"
                                      Opacity="0.15" />
                      </ux:RarityRibbon.MaskedBrush>
                  </ux:RarityRibbon>
              </Border>
      
      

      控件位置發(fā)生了偏移

      1. 要截圖的控件必須保證Margin屬性沒有賦值
      2. 要截圖的控件必須保證父級元素沒有使用Grid.ColumnDefnitions或者Grid.RowDefnitions屬性,這個強(qiáng)制布局的屬性會影響RenderTargetBitmap工作。
      3. 要截圖的控件必須不適用HorizontalAlignment以及VerticalAlignment,這兩個屬性會影響RenderTargetBitmap工作。

      控件大小無法對應(yīng)

      可以試試Snoop里面截圖的幫助類,還挺有用的。

      
      // (c) Copyright Cory Plotts.
      // This source is subject to the Microsoft Public License (Ms-PL).
      // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
      // All other rights reserved.
      
      namespace Snoop.Infrastructure;
      
      using System;
      using System.IO;
      using System.Reflection;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Interop;
      using System.Windows.Media;
      using System.Windows.Media.Imaging;
      
      public static class VisualCaptureUtil
      {
          private const double BaseDpi = 96;
      
          public static void SaveVisual(Visual visual, int dpi, string filename)
          {
              // sometimes RenderTargetBitmap doesn't render the Visual or doesn't render the Visual properly
              // below i am using the trick that jamie rodriguez posted on his blog
              // where he wraps the Visual inside of a VisualBrush and then renders it.
              // http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx
      
              var visualBrush = CreateVisualBrushSafe(visual);
      
              if (visual is null
                  || visualBrush is null)
              {
                  return;
              }
      
              var renderTargetBitmap = RenderVisualWithHighQuality(visual, dpi, dpi);
      
              SaveAsPng(renderTargetBitmap, filename);
          }
          
          public static RenderTargetBitmap SaveVisual(Visual visual, int dpi)
          {
              // sometimes RenderTargetBitmap doesn't render the Visual or doesn't render the Visual properly
              // below i am using the trick that jamie rodriguez posted on his blog
              // where he wraps the Visual inside of a VisualBrush and then renders it.
              // http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx
      
              var visualBrush = CreateVisualBrushSafe(visual);
      
              if (visual is null || visualBrush is null)
              {
                  return null;
              }
      
              return RenderVisualWithHighQuality(visual, dpi, dpi);
          }
      
          public static VisualBrush CreateVisualBrushSafe(Visual visual)
          {
              return IsSafeToVisualize(visual)
                  ? new VisualBrush(visual)
                  : null;
          }
      
          public static bool IsSafeToVisualize(Visual visual)
          {
              if (visual is null)
              {
                  return false;
              }
      
              if (visual is Window)
              {
                  var source = PresentationSource.FromVisual(visual) as HwndSource;
                  return source?.CompositionTarget is not null;
              }
      
              return true;
          }
      
          private static void SaveAsPng(RenderTargetBitmap bitmap, string filename)
          {
              var pngBitmapEncoder = new PngBitmapEncoder();
              pngBitmapEncoder.Frames.Add(BitmapFrame.Create(bitmap));
      
              using (var fileStream = File.Create(filename))
              {
                  pngBitmapEncoder.Save(fileStream);
              }
          }
      
          /// <summary>
          /// Draws <paramref name="visual"/> in smaller tiles using multiple <see cref="VisualBrush"/>.
          /// </summary>
          /// <remarks>
          /// This way we workaround a limitation in <see cref="VisualBrush"/> which causes poor quality for larger visuals.
          /// </remarks>
          public static RenderTargetBitmap RenderVisualWithHighQuality(Visual visual, int dpiX, int dpiY, PixelFormat? pixelFormat = null, Viewport3D viewport3D = null)
          {
              var size = GetSize(visual);
      
              var drawingVisual = new DrawingVisual();
              using (var drawingContext = drawingVisual.RenderOpen())
              {
                  DrawVisualInTiles(visual, drawingContext, size);
              }
      
              return RenderVisual(drawingVisual, size, dpiX, dpiY, pixelFormat, viewport3D);
          }
      
          public static RenderTargetBitmap RenderVisual(Visual visual, Size bounds, int dpiX, int dpiY, PixelFormat? pixelFormat = null, Viewport3D viewport3D = null)
          {
              var scaleX = dpiX / BaseDpi;
              var scaleY = dpiY / BaseDpi;
      
              pixelFormat ??= PixelFormats.Pbgra32;
      
              var renderTargetBitmap = new RenderTargetBitmap((int)Math.Ceiling(scaleX * bounds.Width), (int)Math.Ceiling(scaleY * bounds.Height), dpiX, dpiY, pixelFormat.Value);
      
              if (viewport3D is not null)
              {
                  typeof(RenderTargetBitmap)
                      .GetMethod("RenderForBitmapEffect", BindingFlags.Instance | BindingFlags.NonPublic)
                      ?.Invoke(renderTargetBitmap, new object[] { visual, Matrix.Identity, Rect.Empty });
              }
              else
              {
                  renderTargetBitmap.Render(visual);
              }
      
              return renderTargetBitmap;
          }
      
          private static Size GetSize(Visual visual)
          {
              if (visual is UIElement uiElement)
              {
                  return uiElement.RenderSize;
              }
      
              var descendantBounds = VisualTreeHelper.GetDescendantBounds(visual);
              return new Size(descendantBounds.Width, descendantBounds.Height);
          }
      
          /// <summary>
          /// Draws <paramref name="visual"/> in smaller tiles using multiple <see cref="VisualBrush"/> to <paramref name="drawingContext"/>.
          /// This way we workaround a limitation in <see cref="VisualBrush"/> which causes poor quality for larger visuals.
          /// </summary>
          /// <param name="visual">The visual to be drawn.</param>
          /// <param name="drawingContext">The <see cref="DrawingContext"/> to use.</param>
          /// <param name="visualSize">The size of <paramref name="visual"/>.</param>
          /// <param name="tileWidth">The width of one tile.</param>
          /// <param name="tileHeight">The height of one tile.</param>
          /// <remarks>
          /// Original version of this method was copied from https://srndolha.wordpress.com/2012/10/16/exported-drawingvisual-quality-when-using-visualbrush/
          ///
          /// A tile size of 32x32 turned out deliver the best quality while not increasing computation time too much.
          /// </remarks>
          private static void DrawVisualInTiles(Visual visual, DrawingContext drawingContext, Size visualSize, double tileWidth = 32, double tileHeight = 32)
          {
              var visualWidth = visualSize.Width;
              var visualHeight = visualSize.Height;
      
              var verticalTileCount = visualHeight / tileHeight;
              var horizontalTileCount = visualWidth / tileWidth;
      
              for (var i = 0; i <= verticalTileCount; i++)
              {
                  for (var j = 0; j <= horizontalTileCount; j++)
                  {
                      var width = tileWidth;
                      var height = tileHeight;
      
                      // Check if we would exceed the width of the visual and limit it by the remaining
                      if ((j + 1) * tileWidth > visualWidth)
                      {
                          width = visualWidth - (j * tileWidth);
                      }
      
                      // Check if we would exceed the height of the visual and limit it by the remaining
                      if ((i + 1) * tileHeight > visualHeight)
                      {
                          height = visualHeight - (i * tileHeight);
                      }
      
                      var x = j * tileWidth;
                      var y = i * tileHeight;
      
                      var rectangle = new Rect(x, y, width, height);
      
                      var contentBrush = new VisualBrush(visual)
                      {
                          Stretch = Stretch.None,
                          AlignmentX = AlignmentX.Left,
                          AlignmentY = AlignmentY.Top,
                          Viewbox = rectangle,
                          ViewboxUnits = BrushMappingMode.Absolute
                      };
      
                      drawingContext.DrawRectangle(contentBrush, null, rectangle);
                  }
              }
          }
      }
      
      posted @ 2025-01-15 12:28  Acoris  閱讀(149)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产一区二区三区小说| 亚洲乱码日产精品一二三| 国产午夜福利片在线观看| 在线欧美中文字幕农村电影| 97久久综合亚洲色hezyo| 亚洲av成人午夜福利| 国产成人午夜福利在线播放 | 亚洲精品三区四区成人少| 巧家县| 亚洲精中文字幕二区三区| 日本午夜精品一区二区三区电影| 无码AV无码免费一区二区| 久久99精品久久久久久 | 99riav国产精品视频| 亚洲色大成网站www在线| 婷婷色香五月综合缴缴情香蕉| 午夜福利精品国产二区| 国产精品一区二区三区性色| 伊人欧美在线| 国产日韩精品一区在线不卡| 国产精品视频一品二区三| 国产成人无码性教育视频| 欧美成人va免费大片视频| 玩弄丰满少妇人妻视频| 亚洲欧美偷国产日韩| 老少配老妇老熟女中文普通话 | 国产自拍一区二区三区在线| 91中文字幕一区二区| 昌吉市| 亚洲成人午夜排名成人午夜| 国产欧美日韩亚洲一区二区三区| 国产a在视频线精品视频下载| 暖暖视频日本在线观看| 国产综合视频一区二区三区| 中文字幕国产精品资源| 欧美亚洲日本国产综合在线美利坚| 年日韩激情国产自偷亚洲| 丁香婷婷在线观看| 高清不卡一区二区三区| 长治县| 日韩乱码人妻无码中文字幕视频|