2008-10-21 28 views
9

Nền: Tôi đang làm việc trên ứng dụng Silverlight (1.0) tự động xây dựng bản đồ Hoa Kỳ với các biểu tượng và văn bản được phủ tại các vị trí cụ thể. Bản đồ hoạt động rất tốt trong trình duyệt và bây giờ tôi cần có bản sao tĩnh (có thể in và chèn vào tài liệu/powerpoints) của bản đồ được hiển thị.Chia tỷ lệ nội dung WPF trước khi hiển thị thành bitmap

Mục tiêu: Để có bản in bản đồ cũng có thể được sử dụng trong trang trình bày powerpoint, từ, v.v. Tôi đã chọn tạo ASP.NET HttpHandler để tạo lại xaml ở phía máy chủ WPF và sau đó làm cho WPF thành hình ảnh bitmap được trả về dưới dạng tệp png, được tạo ở tốc độ 300dpi để có chất lượng in tốt hơn.

Sự cố: Điều này rất hữu ích với một sự cố, tôi không thể làm cho hình ảnh được chia tỷ lệ theo kích thước được chỉ định. Tôi đã thử nhiều thứ khác nhau, một số trong đó có thể được nhìn thấy trong các dòng nhận xét. Tôi cần để có thể chỉ định chiều cao và chiều rộng của hình ảnh, bằng inch hoặc pixel, tôi không nhất thiết phải quan tâm và có thang xaml với kích thước đó cho bitmap đã tạo. Hiện tại, nếu tôi tạo kích thước lớn hơn canvas gốc, canvas sẽ được hiển thị ở kích thước ban đầu ở góc trên cùng bên trái của hình ảnh được tạo ở kích thước được chỉ định. Dưới đây là phần quan trọng của người tán thành của tôi. Canvas gốc được lưu trữ dưới dạng "MyImage" có Chiều cao 600 và Chiều rộng là 800. Tôi thiếu gì để có được nội dung mở rộng cho vừa với kích thước được chỉ định?

Tôi không hiểu đầy đủ về kích thước được truyền vào Arrange() và Measure() khi một số mã này được lấy từ ví dụ trực tuyến. Tôi cũng không hiểu đầy đủ về công cụ RenderTargetBitmap. Mọi hướng dẫn sẽ được đánh giá cao.

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 

Trả lời

13

này nên là đủ để giúp bạn bắt đầu:


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(); 
} 
+0

này đã kết thúc truyền cảm hứng cho tôi để tìm ra giải pháp phù hợp vì vậy tôi đã đánh dấu nó là câu trả lời nhưng bên dưới là mã thực sự làm việc cho tôi. –

1

Đây là những gì đã kết thúc làm việc cho tôi:

Public Sub Capture(ByVal MyImage As Canvas) 
     ' Normally we would obtain a user's configured DPI setting to account for the possibilty of a high DPI setting. 
     ' However, this code is running server side so the client's DPI is not obtainable. 
     Const SCREEN_DPI As Double = 96.0 ' Screen DPI 
     Const TARGET_DPI As Double = 300.0 ' Print Quality DPI 

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

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

     ' Create the target bitmap 
     Dim rtb As RenderTargetBitmap = New RenderTargetBitmap(CDbl(MyImage.Width * scale/SCREEN_DPI * TARGET_DPI), CDbl(MyImage.Height * scale/SCREEN_DPI * TARGET_DPI), TARGET_DPI, TARGET_DPI, 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) 
      ctx.DrawRectangle(vb, Nothing, New Rect(New System.Windows.Point(), bounds.Size)) 
     End Using 
     ' Transform the visual to scale the image to our desired size. 
     'dv.Transform = New ScaleTransform(scale, scale) 

     ' Render the visual to the bitmap. 
     rtb.Render(dv) 

     ' Encode the image in the format selected. If no valid format was selected, default to png. 
     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() 
      Case Else 
       encoder = New System.Windows.Media.Imaging.PngBitmapEncoder() 
     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 
+0

Tôi nghĩ bạn có thể thiếu dòng chèn khung vào bộ mã hóa. – bryanbcook

Các vấn đề liên quan