2010-02-05 4 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); 
     } 
    } 
} 

을하는 I 몰라요, TestClass에서 이미지의 deserialization 잘 작동하지 않습니다. 바이트 배열을 잡고 다시 이미지 (Button_Click_4)로 변환하면 작동하고 이미지는 내 양식에 표시됩니다. 대신, TestClass의 Image 속성에서 직접 이미지를 가져 오는 경우 폼에 아무 것도 표시되지 않습니다. 다른 상황이 일어나지 않는 한 두 가지 상황에 관련된 코드가 동일하므로이 방법이 가능한지 모르겠습니다.

내가 뭘 잘못하고 있니? 완전한 코드를 제공 했으므로 붙여넣고 문제를보기 위해 실행할 수 있습니다.

답변

1

시각적 트리의 이미지 개체는 "스크린 샷"이라는 필드에 의해 참조됩니다. 새 이미지에 this.Screenshot을 할당해도 시각적 트리가 전혀 변경되지 않습니다. Screenshot 필드를 지정합니다. 소스를 설정하는 경우, 비주얼 트리에있는 이미지를 업데이트합니다.

이상적으로 테스트 클래스는 Image가 아닌 ImageSource 속성을 노출해야합니다. 단일 이미지 인스턴스는 시각적 트리에만 한 번 나타날 수 있습니다. 따라서 ImageSource 속성을 노출하면 Image의 여러 인스턴스 (시각적 트리의 여러 위치에서 사용될 수 있음)에서 다시 사용할 수 있습니다.

+0

감사합니다. 이제 문제는 컨트롤의 이미지 대신 Image 컨트롤을 다시 할당했기 때문입니다. – Austin