2010-02-05 41 views
1

我想了解圖像序列化如何在WPF中工作。我有以下類:序列化WPF圖像

[Serializable] 
public class TestClass : ISerializable 
{ 
    public TestClass() { } 


    protected TestClass(SerializationInfo info, StreamingContext context) 
    { 
     SerializedImage = (byte[])info.GetValue("SerializedImage", typeof(byte[])); 
    } 


    public byte[] SerializedImage { get; set; } 


    public Image Image { get; set; } 


    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("SerializedImage", SerializedImage); 
    } 


    [OnSerializing] 
    private void OnSerializing(StreamingContext sc) 
    { 
     BitmapImage image = Image.Source as BitmapImage; 

     MemoryStream stream = new MemoryStream(); 
     BmpBitmapEncoder encoder = new BmpBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(image)); 
     encoder.Save(stream); 

     SerializedImage = stream.ToArray(); 

     stream.Close(); ; 
    } 


    [OnDeserialized] 
    private void OnDeserialized(StreamingContext sc) 
    { 
     MemoryStream stream = new MemoryStream(SerializedImage); 
     Image = new Image 
     { 
      Source = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad) 
     }; 

     stream.Close(); 
    } 
} 

這是XAML代碼:

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="358" Width="300" ResizeMode="NoResize"> 
<StackPanel> 

    <Image x:Name="Screenshot" Height="178" /> 
    <Button Width="80" Height="30" Content="Load Image" Click="Button_Click_1" /> 
    <Button Width="92" Height="30" Content="Save to file" Click="Button_Click_2" /> 
    <Button Width="92" Height="30" Content="Load File" Click="Button_Click_3" /> 
    <Button Width="92" Height="30" Content="Load File (1)" Click="Button_Click_4" /> 

</StackPanel> 

這是後面的代碼:

public partial class Window1 : Window 
{ 
    TestClass test; 


    public Window1() 
    { 
     InitializeComponent(); 

     test = new TestClass(); 
    } 


    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog dialog = new OpenFileDialog { Filter = "Bmp Image | *.bmp" }; 
     dialog.ShowDialog(); 

     if (dialog.FileName != string.Empty) 
     { 
      Screenshot.Source = new BitmapImage(new Uri(dialog.FileName)); 
      test.Image = Screenshot; 
     } 
    } 


    private void Button_Click_2(object sender, RoutedEventArgs e) 
    { 
     SaveFileDialog dialog = new SaveFileDialog { DefaultExt = ".t", AddExtension = true }; 
     dialog.ShowDialog(); 

     if (dialog.FileName != string.Empty) 
     { 
      BinaryFormatter formatter = new BinaryFormatter(); 
      FileStream stream = new FileStream(dialog.FileName, FileMode.Create); 
      formatter.Serialize(stream, test); 
      stream.Close(); 
     } 
    } 


    private void Button_Click_3(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog dialog = new OpenFileDialog { Filter = "TEST file | *.t" }; 
     dialog.ShowDialog(); 

     if (dialog.FileName != string.Empty) 
     { 
      BinaryFormatter formatter = new BinaryFormatter(); 
      FileStream stream = new FileStream(dialog.FileName, FileMode.Open); 
      test = formatter.Deserialize(stream) as TestClass; 
      stream.Close(); 

      Screenshot = test.Image; 
     } 
    } 


    private void Button_Click_4(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog dialog = new OpenFileDialog { Filter = "TEST file | *.t" }; 
     dialog.ShowDialog(); 

     if (dialog.FileName != string.Empty) 
     { 
      BinaryFormatter formatter = new BinaryFormatter(); 
      FileStream stream = new FileStream(dialog.FileName, FileMode.Open); 
      test = formatter.Deserialize(stream) as TestClass; 
      stream.Close(); 

      Screenshot.Source = null; 

      MemoryStream stream1 = new MemoryStream(test.SerializedImage); 
      Screenshot.Source = BitmapFrame.Create(stream1, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); 
     } 
    } 
} 

現在,出於某種原因,我不知道,TestClass中圖像的反序列化操作不太好。如果我抓取字節數組並將其自動轉換爲圖像(Button_Click_4),它將起作用,並且圖像會顯示在我的表單上。如果我直接從TestClass中的Image屬性中獲取圖像,則表單中不會顯示任何圖像。我不知道這是怎麼可能的,因爲在這兩種情況下所涉及的代碼是相同的,除非在幕後發生其他事情。

我在做什麼錯?我提供了完整的代碼,您可以將其粘貼並運行以查看問題。

回答

1

視覺樹中的圖像對象被稱爲「屏幕截圖」的字段引用。將此.Screenshot分配給新的圖像根本不會改變您的可視化樹。它只是分配字段屏幕截圖。在設置Source的情況下,您正在更新視覺樹中的Image。

理想情況下,您的測試類應公開ImageSource屬性,而不是Image。一個Image實例只能在可視化樹中出現一次。所以通過公開一個ImageSource屬性,你可以在Image的幾個實例中重用它(可以在你的可視化樹中的不同位置使用)。

+0

謝謝,我現在意識到問題是我重新分配圖像控件,而不是控件的圖像。 – Austin