渲染为位图前缩放WPF内容 [英] Scaling WPF content before rendering to bitmap

查看:169
本文介绍了渲染为位图前缩放WPF内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:
我工作的一个Silverlight(1.0)的应用程序,动态生成的地图,美国与图标和文本在特定位置叠加一个。地图作品在浏览器中伟大而现在我需要得到一个静态的(可打印并插入到文档/ PPT模板)所显示的地图的副本。

目标:
为了得到这也可以在PowerPoint幻灯片中使用的地图,文字等的打印副本我选择创建一个ASP.NET的HttpHandler重新在WPF服务器端的XAML,然后呈现给WPF这是返回一个PNG文件的位图图像,在300dpi的生成更好的打印质量。

问题:
这个伟大的工程有一个问题,我不能让图像缩放到指定的大小。我试过几个不同的东西,其中一些可以在注释掉线可以看出。我需要能够以指定的图像的高度和宽度,或者以英寸或像素,我不一定关心哪个,并具有XAML规模到大小为生成位图。目前,如果我的尺寸比的根画布越大,画布得到在原来的大小在规定的大小的生成的图像的左上角渲染。下面是我的HttpHandler的重要组成部分。存储为MYIMAGE根画布有600的高度和800宽度缺少什么我获取内容扩展到符合规定的尺寸是多少?

我不完全了解什么被传递到安排(),测量(尺寸)做一些这code的从网上的例子服用。我还没有完全理解RenderTargetBitmap的东西。任何指导,将AP preciated。

 公用Sub捕捉(BYVAL MYIMAGE帆布)
    确定约束规模保持纵横比和图像尺寸的边界
    昏暗的规模为双= Math.Min(宽/ MyImage.Width,身高/ MyImage.Height)    暗淡VBOX作为新Viewbox控件()
    vbox.Stretch = Stretch.Uniform
    vbox.StretchDirection = StretchDirection.Both
    vbox.Height =身高*规模* 300 / 96.0
    vbox.Width = *宽*规模300 / 96.0
    vbox.Child = MYIMAGE    暗淡的范围作为矩形=新的Rect(0,0,MyImage.Width *刻度,MyImage.Height *刻度)
    MyImage.Measure(新尺寸(宽*秤,身高*等级))
    MyImage.Arrange(边界)
    MyImage.UpdateLayout()    创建目标位图
    昏暗的RTB作为RenderTargetBitmap =新RenderTargetBitmap(CINT(宽*规模* 300 / 96.0),CINT(高*规模* 300 / 96.0),300,300,PixelFormats.Pbgra32)    渲染图像到目标位图
    昏暗DV由于DrawingVisual =新DrawingVisual()
    使用CTX作为的DrawingContext = dv.RenderOpen()
        昏暗的VB作为新的VisualBrush(MYIMAGE)
        暗淡VB作为新的VisualBrush(VBOX)
        ctx.DrawRectangle(VB,没什么,新矩形(新System.Windows.Point(),bounds.Size))
    使用完
    rtb.Render(DV)    恩code选择了格式的图像
    昏暗带codeR作为System.Windows.Media.Imaging.BitmapEn codeR
    选择案例Encoding.ToLower
        案JPG
            EN codeR =新System.Windows.Media.Imaging.JpegBitmapEn codeR()
        案PNG
            EN codeR =新System.Windows.Media.Imaging.PngBitmapEn codeR()
        案GIF
            EN codeR =新System.Windows.Media.Imaging.GifBitmapEn codeR()
        案BMP
            EN codeR =新System.Windows.Media.Imaging.BmpBitmapEn codeR()
        案TI​​F
            EN codeR =新System.Windows.Media.Imaging.TiffBitmapEn codeR()
        案WMP
            EN codeR =新System.Windows.Media.Imaging.WmpBitmapEn codeR()
    结束选择
    EN coder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(RTB))    创建内存流保存EN codeD映像。
    retImageStream =新System.IO.MemoryStream()
    EN coder.Save(retImageStream)
    retImageStream.Flush()
    retImageStream.Seek(0,System.IO.SeekOrigin.Begin)
    MYIMAGE =什么
结束小组


解决方案

这应该足以让你开始:

 
私人无效ExportCanvas(INT宽度,高度INT)
{
    字符串路径= @C:\\ TEMP \\ Test.tif
    的FileStream FS =新的FileStream(路径,FileMode.Create);
    RenderTargetBitmap renderBitmap =新RenderTargetBitmap(宽度,
                                                             身高,1/300,1/300,PixelFormats.Pbgra32);    DrawingVisual视觉=新DrawingVisual();
    使用(背景下的DrawingContext = visual.RenderOpen())
    {
    刷的VisualBrush =新的VisualBrush(MyCanvas);
    context.DrawRectangle(刷,
    \t 空值,
    新的矩形(新点(),新的尺寸(MyCanvas.Width,MyCanvas.Height)));
    }    visual.Transform =新ScaleTransform(宽/ MyCanvas.ActualWidth,高度/ MyCanvas.ActualHeight);    renderBitmap.Render(视觉);    BitmapEn codeR EN codeR =新TiffBitmapEn codeR();
    EN coder.Frames.Add(BitmapFrame.Create(renderBitmap));
    EN coder.Save(FS);
    fs.Close();
}

Background: I'm working on a silverlight (1.0) application that dynamically builds a map of the United States with icons and text overlayed at specific locations. The map works great in the browser and now I need to get a static (printable and insertable into documents/powerpoints) copy of a displayed map.

Objective: In order to get a printable copy of the map that can also be used in powerpoint slides, word, etc. I've chosen to create an ASP.NET HttpHandler to recreate the xaml on the server side in WPF and then render the WPF to a bitmap image which is returned as a png file, generated at 300dpi for better print quality.

Problem: This works great with one problem, I can't get the image to scale to a specified size. I've tried several different things, some of which can be seen in the commented out lines. I need to be able to specify a height and width of the image, either in inches or pixels, I don't necessarily care which, and have the xaml scale to that size for the generated bitmap. Currently, if I make the size bigger than the root canvas, the canvas gets rendered at its original size in the top left corner of the generated image at the size specified. Below is the important part of my httphandler. The root canvas stored as "MyImage" has a Height of 600 and a Width of 800. What am I missing to get the content to scale to fit the size specified?

I don't fully understand what the dimensions being passed into Arrange() and Measure() do as some of this code was taken from online examples. I also don't fully understand the RenderTargetBitmap stuff. Any guidance would be appreciated.

Public Sub Capture(ByVal MyImage As Canvas)
    ' Determine the constraining scale to maintain the aspect ratio and the bounds of the image size
    Dim scale As Double = Math.Min(Width / MyImage.Width, Height / MyImage.Height)

    'Dim vbox As New Viewbox()
    'vbox.Stretch = Stretch.Uniform
    'vbox.StretchDirection = StretchDirection.Both
    'vbox.Height = Height * scale * 300 / 96.0
    'vbox.Width = Width * scale * 300 / 96.0
    'vbox.Child = MyImage

    Dim bounds As Rect = New Rect(0, 0, MyImage.Width * scale, MyImage.Height * scale)
    MyImage.Measure(New Size(Width * scale, Height * scale))
    MyImage.Arrange(bounds)
    'MyImage.UpdateLayout()

    ' Create the target bitmap
    Dim rtb As RenderTargetBitmap = New RenderTargetBitmap(CInt(Width * scale * 300 / 96.0), CInt(Height * scale * 300 / 96.0), 300, 300, PixelFormats.Pbgra32)

    ' Render the image to the target bitmap
    Dim dv As DrawingVisual = New DrawingVisual()
    Using ctx As DrawingContext = dv.RenderOpen()
        Dim vb As New VisualBrush(MyImage)
        'Dim vb As New VisualBrush(vbox)
        ctx.DrawRectangle(vb, Nothing, New Rect(New System.Windows.Point(), bounds.Size))
    End Using
    rtb.Render(dv)

    ' Encode the image in the format selected
    Dim encoder As System.Windows.Media.Imaging.BitmapEncoder
    Select Case Encoding.ToLower
        Case "jpg"
            encoder = New System.Windows.Media.Imaging.JpegBitmapEncoder()
        Case "png"
            encoder = New System.Windows.Media.Imaging.PngBitmapEncoder()
        Case "gif"
            encoder = New System.Windows.Media.Imaging.GifBitmapEncoder()
        Case "bmp"
            encoder = New System.Windows.Media.Imaging.BmpBitmapEncoder()
        Case "tif"
            encoder = New System.Windows.Media.Imaging.TiffBitmapEncoder()
        Case "wmp"
            encoder = New System.Windows.Media.Imaging.WmpBitmapEncoder()
    End Select
    encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(rtb))

    ' Create the memory stream to save the encoded image.
    retImageStream = New System.IO.MemoryStream()
    encoder.Save(retImageStream)
    retImageStream.Flush()
    retImageStream.Seek(0, System.IO.SeekOrigin.Begin)
    MyImage = Nothing
End Sub

解决方案

This should be enough to get you started:


private void ExportCanvas(int width, int height)
{
    string path = @"c:\temp\Test.tif";
    FileStream fs = new FileStream(path, FileMode.Create);


    RenderTargetBitmap renderBitmap = new RenderTargetBitmap(width,
                                                             height, 1/300, 1/300, PixelFormats.Pbgra32);

    DrawingVisual visual = new DrawingVisual();
    using (DrawingContext context = visual.RenderOpen())
    {
    	VisualBrush brush = new VisualBrush(MyCanvas);
    	context.DrawRectangle(brush,
    	                      null,
    	                      new Rect(new Point(), new Size(MyCanvas.Width, MyCanvas.Height)));
    }

    visual.Transform = new ScaleTransform(width / MyCanvas.ActualWidth, height / MyCanvas.ActualHeight);

    renderBitmap.Render(visual);

    BitmapEncoder encoder = new TiffBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
    encoder.Save(fs);
    fs.Close();
}

这篇关于渲染为位图前缩放WPF内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆