关于RenderTargetBitmap,DrawingVisual画BMP的问题

dceacho 2016-01-11 08:50:21
            DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawLine(pen, new Point(0,0), new Point(1023, 200));
drawingContext.DrawLine(pen, new Point(1023,0), new Point(1023, 1023));
drawingContext.Close();
RenderTargetBitmap bmp;
bmp = new RenderTargetBitmap(1024, 1024, 120, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);


我查看bmp图像时发现图片少了一截,右边那部分没显示,第二条竖线看不到, 当把图片改大时就出现了
bmp = new RenderTargetBitmap(2048 1024, 120, 96, PixelFormats.Pbgra32);
...全文
680 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
dceacho 2016-01-12
  • 打赏
  • 举报
回复
这板块人气快赶上硬件板块的了 原文出自MSDN,地址忘记复制了, 原理暂时还没看明白,猜测RenderTargetBitmap只是从显示器上拷图像而不是直接从内存里赋值,由于DPI的关系它的一个点不是原图的一个点

using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace WDataViewer
{
    //RenderTargetBitmap把视觉树中的一部分光栅化以位图的形式保存,你可以利用下面的这个类以位图的形式呈现视觉元素,当然得考虑系统DPI设置及视觉元素的转换。(感谢Adam Smith在反转换这方面的建议)
    public class VisualUtility
    {
        public static BitmapSource CreateBitmapFromVisual(Double width,
                Double height,
                Visual visualToRender,
                Boolean undoTransformation)
        {
            if (visualToRender == null)
            {
                return null;
            }
            // The PixelsPerInch()方法用于读取屏幕上DPI的设置
            //如果你想以特定的分辨率创建一个位图,你可以直接把某一dpiX或dpiY传参给RenderTargetBitmap构造器。
            RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width),
                                                            (Int32)Math.Ceiling(height),
                                                           (Double)DeviceHelper.PixelsPerInch(Orientation.Horizontal),
                                                           (Double)DeviceHelper.PixelsPerInch(Orientation.Vertical),
                                                            PixelFormats.Pbgra32);
            //如果我们想反转换,我们可以使用VisualBrush
            if (undoTransformation)
            {
                DrawingVisual dv = new DrawingVisual();
                using (DrawingContext dc = dv.RenderOpen())
                {
                    VisualBrush vb = new VisualBrush(visualToRender);
                    dc.DrawRectangle(vb, null, new Rect(new Point(), new Size(width, height)));
                }
                bmp.Render(dv);
            }
            else
            {
                bmp.Render(visualToRender);
            }
            return bmp;
        }
    }

    internal class DeviceHelper
    {
        public static Int32 PixelsPerInch(Orientation orientation)
        {
            Int32 capIndex = (orientation == Orientation.Horizontal) ? 0x58 : 90;
            using (DCSafeHandle handle = UnsafeNativeMethods.CreateDC("DISPLAY"))
            {
                return (handle.IsInvalid ? 0x60 : UnsafeNativeMethods.GetDeviceCaps(handle, capIndex));
            }
        }
    }

    internal sealed class DCSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private DCSafeHandle() : base(true) { }
        protected override Boolean ReleaseHandle()
        {
            return UnsafeNativeMethods.DeleteDC(base.handle);
        }
    }

    [SuppressUnmanagedCodeSecurity]
    internal static class UnsafeNativeMethods
    {
        [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern Boolean DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern Int32 GetDeviceCaps(DCSafeHandle hDC, Int32 nIndex);
        [DllImport("gdi32.dll", EntryPoint = "CreateDC", CharSet = CharSet.Auto)]
        public static extern DCSafeHandle IntCreateDC(String lpszDriver,
            String lpszDeviceName, String lpszOutput, IntPtr devMode);
        public static DCSafeHandle CreateDC(String lpszDriver)
        {
            return UnsafeNativeMethods.IntCreateDC(lpszDriver, null, null, IntPtr.Zero);
        }
    }
}

8,734

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧