2012-05-06 33 views
11

Tôi có một điều khiển Hình ảnh bên trong ứng dụng wpf của tôi, trong đó có một hình ảnh lớn bên trong nó, nhưng bản thân điều khiển chỉ 60x150, điều này có nghĩa là nó chỉ hiển thị một phần nhất định hình ảnh. Cách dễ nhất để lưu phần hiển thị vào một tệp là gì?Cách dễ nhất để lưu wpf Điều khiển hình ảnh vào một tệp

Cảm ơn sự giúp đỡ của bạn.

[EDIT] tôi đã kết thúc sử dụng mã tìm thấy here (mà tôi đã không thể xác định vị trí trước khi gửi bài ở đây) ...

Grid r = new Grid(); 
     r.Background = new ImageBrush(image2.Source); 


    System.Windows.Size sz = new System.Windows.Size(image2.Source.Width, image2.Source.Height); 
    r.Measure(sz); 
    r.Arrange(new Rect(sz)); 

    RenderTargetBitmap rtb = new RenderTargetBitmap((int)image2.Source.Width, (int)image2.Source.Height, 96d, 96d, PixelFormats.Default); 
    rtb.Render(r); 

    BmpBitmapEncoder encoder = new BmpBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(rtb)); 

    FileStream fs = File.Open(@"C:\lol.png", FileMode.Create); 
    encoder.Save(fs); 
    fs.Close(); 
+0

image2.Source.Width là gì? Thay vào đó là image2.ActualWidth, chỉ cần sử dụng mã của tôi. – gliderkite

Trả lời

16

Bạn có thể sử dụng RenderTargetBitmap lớp và BitmapEncoder.

Xác định các phương pháp:

void SaveToBmp(FrameworkElement visual, string fileName) 
{ 
    var encoder = new BmpBitmapEncoder(); 
    SaveUsingEncoder(visual, fileName, encoder); 
} 

void SaveToPng(FrameworkElement visual, string fileName) 
{ 
    var encoder = new PngBitmapEncoder(); 
    SaveUsingEncoder(visual, fileName, encoder); 
} 

// and so on for other encoders (if you want) 


void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder) 
{ 
    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32); 
    bitmap.Render(visual); 
    BitmapFrame frame = BitmapFrame.Create(bitmap); 
    encoder.Frames.Add(frame); 

    using (var stream = File.Create(fileName)) 
    { 
     encoder.Save(stream); 
    } 
} 

Nếu bạn có quyền kiểm soát Image của bạn bên trong một container như thế này:

<Grid x:Name="MyGrid"> 
    <Image Name="MyImage" Stretch="None"></Image> 
</Grid> 

Bạn chỉ cần làm như vậy:

SaveToPng(MyGrid, "image.png"); 

Nếu không, bạn có thể chỉ cần truyền các tham số bạn muốn khi bạn sử dụng RenderTargetBitmap:

SaveToPng(MyImage, "image.png"); 

... 

RenderTargetBitmap bitmap = new RenderTargetBitmap(YourWidth, YourHeight, 96, 96, PixelFormats.Pbgra32); 
+4

Cảm ơn vì điều này, nó sẽ là tuyệt vời nếu không cho một vấn đề nhỏ .. Các hình ảnh được lưu là sân đen ... Bất kỳ ý tưởng như thế nào đã xảy ra hoặc làm thế nào để sửa chữa nó? – Meh

+0

Khi tôi chạy mã của tôi nó hoạt động, bạn đã thử những gì? với "MyGrid" hoặc "MyImage"? – gliderkite

+0

Tôi đã thực hiện một dự án thử nghiệm trong VB.NET: [đây là một mẫu] (http://ideone.com/wZH72) nếu nó có thể giúp; và [ở đây] (http://ideone.com/CJrJA) XAML. – gliderkite

2

Tôi gặp phải vấn đề hình ảnh 'đen' tương tự mà vấn đề khác đã làm khi sử dụng giải pháp của gliderkite. Hình ảnh 'đen' có vẻ là do lề của FrameworkElement khiến cho nó được hiển thị bên ngoài hình ảnh đã chụp. Tôi tìm thấy giải pháp thay thế trong một số comment on Rick Stahl's blog

Cụ thể, đo và sắp xếp trước khi hiển thị cho phép cơ hội điều chỉnh chính nó thành thực tế không có lề trong hình. Sau đây là lớp tĩnh tôi hiện đang sử dụng lại để chụp màn hình. Điều này dựa trên câu trả lời của gliderkite và thông tin trên blog của Rick Stahl.

public static class ScreenCapture 
{ 
    public static void SaveToBmp(FrameworkElement visual, string fileName) 
    { 
     var encoder = new BmpBitmapEncoder(); 
     SaveUsingEncoder(visual, fileName, encoder); 
    } 

    public static void SaveToPng(FrameworkElement visual, string fileName) 
    { 
     var encoder = new PngBitmapEncoder(); 
     SaveUsingEncoder(visual, fileName, encoder); 
    } 

    public static void SaveToJpeg(FrameworkElement visual, string fileName) 
    { 
     var encoder = new JpegBitmapEncoder(); 
     SaveUsingEncoder(visual, fileName, encoder); 
    } 

    private static void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder) 
    { 
     RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32); 
     Size visualSize = new Size(visual.ActualWidth, visual.ActualHeight); 
     visual.Measure(visualSize); 
     visual.Arrange(new Rect(visualSize)); 
     bitmap.Render(visual); 
     BitmapFrame frame = BitmapFrame.Create(bitmap); 
     encoder.Frames.Add(frame); 

     using (var stream = File.Create(fileName)) 
     { 
      encoder.Save(stream); 
     } 
    } 
} 
Các vấn đề liên quan