English 中文(简体)
更新“变形地图”的源头内容,没有更新所展示的图像
原标题:Updating the content of the TransformedBitmap s source doesn t update the rendered picture
  • 时间:2011-11-21 16:52:17
  •  标签:
  • c#
  • wpf

我需要从网上摄像机上提供实况录像。 我试图在新框架到达时改变我的形象。 我绘制了可悲的Bit地图,每次更新时都有新的框架,而变形图则将直线变换成其来源。 如果为每个框架制定新的变型Bit地图,则制作成视频材料,尽管记忆的迅速增长,使GC能够非常频繁地收集记忆。 如果一米试图重新使用单一变型Bit地图,我看不出有关提供情况的最新情况,就总是显示第一个框架。

How can I reuse the same TransformedBitmap object without growth of the memory footprint?

这里使用两种不同档案的样本代码,以复制网上广告。

public partial class Window1 : Window
{
    Thread m_thread;
    BitmapImage source1;
    BitmapImage source2;
    byte[] data;
    int stride;
    WriteableBitmap bitmap;
    TransformedBitmap tb;
    public Window1()
    {
        InitializeComponent();
        FileStream stream = new FileStream("1.png", FileMode.Open, FileAccess.Read);

        source1 = new BitmapImage();
        source1.BeginInit();
        source1.StreamSource = stream;
        source1.EndInit();

        FileStream stream2 = new FileStream("2.png", FileMode.Open, FileAccess.Read);
        source2 = new BitmapImage();
        source2.BeginInit();
        source2.StreamSource = stream2;
        source2.EndInit();

        stride = source1.PixelWidth * (source1.Format.BitsPerPixel / 8);
        data = new byte[stride * source1.PixelHeight];

        bitmap = new WriteableBitmap(source1.PixelWidth, source1.PixelHeight, source1.DpiX, source1.DpiY, source1.Format, source1.Palette);
        WritePixels(source1, bitmap, data);

        tb = new TransformedBitmap(bitmap, new ScaleTransform(-1, 1));

        m_thread = new Thread(ThreadFunc);
        m_thread.Start();
    }

    public void ThreadFunc()
    {
        int i = 0;
        while (true)
        {
            Dispatcher.Invoke(new Action(() => {
                BitmapSource source = (i % 2 == 0) ? source2 : source1;
                WritePixels(source, bitmap, data);
                image1.Source = tb;
            }));
            ++i;
            Thread.Sleep(100);
        }
    }

    public void WritePixels(BitmapSource source, WriteableBitmap target, byte[] data)
    {
        int stride = source.PixelWidth * (source.Format.BitsPerPixel / 8);

        source.CopyPixels(data, stride, 0);
        target.WritePixels(new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), data, stride, 0);
    }
}
最佳回答

我要说的是,之所以出现这一问题,是因为转变的Bitmap是同样的,很可能是图象的标语承认这一变化,如果我使用两个不同的变形图标,这些物体具有相同来源,然后在撰写新内容之后,我转而改换的Bit地图。

因此,该法典是:

public partial class MainWindow : Window
{
    Thread m_thread;
    BitmapImage source1;
    BitmapImage source2;
    byte[] data;
    int stride;
    WriteableBitmap bitmap1;

    TransformedBitmap tb1;
    TransformedBitmap tb2;

    public MainWindow()
    {
        InitializeComponent();
        FileStream stream = new FileStream("1.jpg", FileMode.Open, FileAccess.Read);

        source1 = new BitmapImage();
        source1.BeginInit();
        source1.StreamSource = stream;
        source1.EndInit();

        FileStream stream2 = new FileStream("2.jpg", FileMode.Open, FileAccess.Read);
        source2 = new BitmapImage();
        source2.BeginInit();
        source2.StreamSource = stream2;
        source2.EndInit();

        stride = source1.PixelWidth * (source1.Format.BitsPerPixel / 8);
        data = new byte[stride * source1.PixelHeight];

        bitmap1 = new WriteableBitmap(source1.PixelWidth, source1.PixelHeight, source1.DpiX, source1.DpiY, source1.Format, source1.Palette);
        WritePixels(source1, bitmap1, data);

        tb1 = new TransformedBitmap(bitmap1, new ScaleTransform(-1, -1));
        tb2 = new TransformedBitmap(bitmap1, new ScaleTransform(-1, -1));

        m_thread = new Thread(ThreadFunc);
        m_thread.Start();
    }

    public void ThreadFunc()
    {
        int i = 0;
        while (true)
        {
            Dispatcher.Invoke(new Action(() => {
                BitmapSource source = (i % 2 == 0) ? source2 : source1;
                WritePixels(source, bitmap1, data);
                // this is the trick we have to set different TransformedBitmap as
                // Image.Source
                // so since we don t want to create new one each time we just
                // switch between two
                image1.Source = (i % 2 == 0) ? tb1 : tb2;
            }));
            ++i;
            Thread.Sleep(100);
        }
    }

    public void WritePixels(BitmapSource source, WriteableBitmap target, byte[] data)
    {
        int stride = source.PixelWidth * (source.Format.BitsPerPixel / 8);

        source.CopyPixels(data, stride, 0);
        target.WritePixels(new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), data, stride, 0);
    }
}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签