【WPF学习手记】WPF控件保存成图片加强版

    WPF中将控件保存成图片,主要利用了RenderTargetBitmap方法。但是,通过测试发现这种方法有个问题,即图片是从目标UI上一级的左上角作为起点计算长宽的,也就是说,如果目标UI居中显示,那么极有可能导出的图片是不完整的,居左置顶则能导出完整图片。

    为了解决这个问题,我们可以先将包含目标UI在内的部分保存成一张大图,然后从大图中提取目标UI部分,主要利用CroppedBitmap函数。

    以下两个函数的即实现了这个功能:第一个函数是将ImageSource转换成Bitmap,第二个函数是将指定的UI保存成图片。

// ImageSource --> Bitmap
        public static Bitmap ImageSourceToBitmap(ImageSource imageSource)
        {
            BitmapSource bitmapSource = (BitmapSource)imageSource;
            Bitmap bmp = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            BitmapData data = bmp.LockBits(
                new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
                bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
                bmp.UnlockBits(data);
            return bmp;
        }

// UI --> Image
        public static void UISaveToImage(FrameworkElement ui, string fileName, int bigX, int BigY, int width, int height)
        {
            RenderTargetBitmap bmp = new RenderTargetBitmap(bigX, BigY, 96d, 96d, PixelFormats.Pbgra32);
            bmp.Render(ui);
            int offsetX = Math.Max((int)(0.5 * (bigX - width)), 0);
            int offsetY = Math.Max((int)(0.5 * (BigY - height)), 0);
            BitmapSource bmpSource = new CroppedBitmap(BitmapFrame.Create(bmp), new Int32Rect(offsetX, offsetY, width, height));
            ImageSourceToBitmap(bmpSource).Save(fileName);
        }

    补充说明:bigX和bigY为目标UI、目标UI上一级中较大宽和较大高;

    比如以下代码:

<ScrollViewer Grid.Column="2" Name="svProcess" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" BorderBrush="BlueViolet" BorderThickness="1">
    <Image Name="imgProcess" Stretch="Uniform" RenderOptions.BitmapScalingMode="HighQuality" IsHitTestVisible="False"/>
</ScrollViewer>

    调用方式:

int offsetX = Math.Max((int)(0.5 * (svProcess.ActualWidth - imgProcess.ActualWidth)), 0);
int offsetY = Math.Max((int)(0.5 * (svProcess.ActualHeight - imgProcess.ActualHeight)), 0);
int bigX = Math.Max((int)svProcess.ActualWidth, (int)imgProcess.ActualWidth);
int bigY = Math.Max((int)svProcess.ActualHeight, (int)imgProcess.ActualHeight);
CImageProcess.UISaveToImage(imgProcess, filename, bigX, bigY, (int)imgProcess.ActualWidth, (int)imgProcess.ActualHeight);

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值