WPF加载图片​​连载 [英] WPF loading serialized image

查看:101
本文介绍了WPF加载图片​​连载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个应用程序,我需要通过一个的BinaryWriter序列化的图像,并把它在其他应用程序中显示它。

In an app I need to serialize an image through a binarywriter, and to get it in an other app to display it.

下面是我的系列化code的一部分:

Here is a part of my "serialization" code :

FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write);
BinaryWriter bin = new BinaryWriter(fs);                         

bin.Write((short)this.Animations.Count);

for (int i = 0; i < this.Animations.Count; i++)
{
    MemoryStream stream = new MemoryStream();
    BitmapEncoder encoder = new PngBitmapEncoder();

    encoder.Frames.Add(BitmapFrame.Create(Animations[i].Image));
    encoder.Save(stream);

    stream.Seek(0, SeekOrigin.Begin);

    bin.Write((int)stream.GetBuffer().Length);
    bin.Write(stream.GetBuffer());

    stream.Close();
}

bin.Close();

这是加载图像我反序列化的一部分:

And here is the part of my deserialization that load the image :

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader bin = new BinaryReader(fs);

int animCount = bin.ReadInt16();
int imageBytesLenght;
byte[] imageBytes;
BitmapSource img;

for (int i = 0; i < animCount; i++)
{    
    imageBytesLenght = bin.ReadInt32();
    imageBytes = bin.ReadBytes(imageBytesLenght);
    img = new BitmapImage();
    MemoryStream stream = new MemoryStream(imageBytes);
    BitmapDecoder dec = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    img = dec.Frames[0];
    stream.Close();
}

bin.Close();

当我用这个方法,我加载图像(它似乎是存储在IMG的对象),但它不能被显示。

When I use this method, I load the image (it seems to be stored in the "img" object) but it can't be displayed.

somedy有一个想法?

Has somedy an idea?

感谢

风筝

UPD

我已经做到这一点:更新我的约束力,甚至试图直接通过窗口code behing影响它。这些方法都不能工作:■

I already do this : updating my binding, or even trying to affect it directly through the window code behing. None of these approaches work :s

然而,当我补充一点:

private void CreateFile(byte[] bytes)
{
    FileStream fs = new FileStream(Environment.CurrentDirectory + "/" + "testeuh.png", FileMode.Create, FileAccess.Write);
    fs.Write(bytes, 0, bytes.Length);     
    fs.Close();
}

在你函数结尾,它完美地创建文件,它可以毫无问题地读...所以我不知道问题出在哪里都可以。

at the end of you function, it perfectly create the file, which can be read without any problems ... So I don't know where the problem can be.

2 UPD

一个奇怪的事情发生了。

A weird things happens.

下面是结合使用:

<Image x:Name="imgSelectedAnim" Width="150" Height="150" Source="{Binding ElementName=lstAnims, Path=SelectedItem.Image}" Stretch="Uniform" />

(列表本身上绑定一个ObservableCollection)。

(the list is itself binded on an observableCollection).

当我通过应用程序手动创建动画,它的工作原理(显示图像)。

When I create manually the animation through the app, it works (the image is displayed).

但是,当我打开它,它不显示(我看我的code,没有任何新,这可能打破我的约束力,因为还有其他的属性绑定以同样的方式,他们不失败)。

But when I load it, it is not displayed (I look at my code, there are not any "new" which could break up my binding, since there are others properties binded the same way and they does not fail).

此外,我已经把一个断点在我的动画图像性能的getter / setter方法​​。

Moreover, I've put a breakpoint on the getter/setter of the properties Image of my animation.

在创建它,没有任何问题,它具有良好的信息。

When it is created, no problems, it has the good informations.

但是,当它是通过吸气retreived,它返回一个良好的形象第一次,然后和形象与pixelWidth,pixelHeight,宽度仅为1的高度,但没有通过setter去了!

But when it is retreived through the getter, it return a good image the first time, and then and image with pixelWidth, pixelHeight, width, height of only 1 but without going through the setter anymore !

任何想法?

UPD3

你试过这样说的:

增加了一个性能测试在我的视图模型:

Added a property TEST in my viewModel :

  private BitmapSource test;
        public BitmapSource TEST { get { return test; } set { test = value; RaisePropertyChanged("TEST"); } }

然后做到了:

img = getBmpSrcFromBytes(bin.ReadBytes(imageBytesLenght));
TEST = img;

(在code显示和修改前)

(in the code showed and modified before)

和我的结合:

 <Image x:Name="imgSelectedAnim" Width="150" Height="150" Source="{Binding Path=TEST}" Stretch="Uniform" />

(DataContext设置为我的视图模型)

(datacontext is set to my ViewModel)

和它仍然无法正常工作,确实怪异的图像修改(pixW,pixH,W和H设置为1)

And it still doesn't work and does the weird image modification (pixW, pixH, W and H set to 1)

FINAL UPD:

看来我终于解决了这个问题。这里简直就是我所做的:

It seems I finally solved the problem. Here is simply what I did :

byte[] bytes = bin.ReadBytes(imageBytesLenght);
MemoryStream mem = new MemoryStream(bytes);

img = new BitmapImage();
img.BeginInit();
img.StreamSource = mem;
img.EndInit();

奇怪的是,它不工作的第一次,也许是因为我的spriteanimation类中的建筑修饰,但我不认为它是。

the strange thing is that it didn't work the first time, maybe it is due to an architectural modification within my spriteanimation class, but I don't think it is.

嗯,谢谢你很多尤金Cheverda他的帮助

Well, thank you a lot to Eugene Cheverda for his help

推荐答案

在第一个,我想你应该保存你的图像的BitmapSource 的列表,并提供反向编码使用 BitmapImage.StreamSource 图片:

At the first, I think you should store your images in a list of BitmapSource and provide reverse encoding of image for using stream as BitmapImage.StreamSource:

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
        BinaryReader bin = new BinaryReader(fs);

        int animCount = bin.ReadInt16();
        int imageBytesLenght;
        byte[] imageBytes;
        List<BitmapSource> bitmaps = new List<BitmapSource>();

        for (int i = 0; i < animCount; i++)
        {
            imageBytesLenght = bin.ReadInt32();
            imageBytes = bin.ReadBytes(imageBytesLenght);
            bitmaps.Add(getBmpSrcFromBytes(imageBytes));
        }

        bin.Close();

UPD
在code以上使用FUNC下面写:

UPD In code above use func written below:

private BitmapSource getBmpSrcFromBytes(byte[] bytes)
        {
            using (var srcStream = new MemoryStream(bytes))
            {
                var dec = new PngBitmapDecoder(srcStream, BitmapCreateOptions.PreservePixelFormat,
                                                             BitmapCacheOption.Default);

                var encoder = new PngBitmapEncoder();
                encoder.Frames.Add(dec.Frames[0]);
                BitmapImage bitmapImage = null;
                bool isCreated;
                try
                {
                    using (var ms = new MemoryStream())
                    {
                        encoder.Save(ms);
                        bitmapImage = new BitmapImage();
                        bitmapImage.BeginInit();
                        bitmapImage.StreamSource = ms;
                        bitmapImage.EndInit();
                        isCreated = true;
                    }
                }
                catch
                {
                    isCreated = false;
                }
                return isCreated ? bitmapImage : null;
            }
        }

希望这有助于。

UPD#2

您绑定不正确。你可能应该绑定选择项,例如 CurrentImageSource 。然后将此 CurrentImageSource 绑定到图片控制。

Your binding is incorrect. You may be should bind selected item to for example CurrentImageSource. And then this CurrentImageSource bind to Image control.

code:

public class MyViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<BitmapSource> ImagesCollection { get; set; }
        private BitmapSource _currentImage;

        public BitmapSource CurrentImage
        {
            get { return _currentImage; }
            set
            {
                _currentImage = value;
                raiseOnPropertyChanged("CurrentImage");
            }
        }

        private void raiseOnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }        

        public event PropertyChangedEventHandler PropertyChanged;
    }

然后:

<ListBox ItemsSource="{Binding ImagesCollection}" SelectedItem="{Binding CurrentImage}"/>
<Image Source="{Binding CurrentImage}"/>

ADDED

这里是指当我上述实施技术示例项目。
它创建动画的收集和再present他们列表框中,选择动画显示在使用它的图像属性Image控件。

Here is the sample project in which implemented technique as I described above. It creates animations collection and represent them in listbox, selected animation is displayed in Image control using its Image property.

我想说的是,如果你不能获得的图像,因为它应该是,你需要搜索序列化/反序列化的问题。

What I want to say is that if you cannot obtain image as it should be, you need to search problems in serialization/deserialization.

这篇关于WPF加载图片​​连载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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