tags:

views:

59

answers:

3

Here's the problem :

I need to scroll a huge image of a wave form that has been rendered previously, WPF didn't let me assign that huge (80000*256) picture to an Image, it works for smaller (30000*256) images but it's so slow animating it that it's unpractical.

So what I decided was to use a WriteableBitmap that I assign to my Image.Source, and then I only have to update say 1920*256 (or only the width of the screen). It works much better now but after some profiling, it seems that the actual copying process takes quite some time and it's not 60 fps everytime.

I am already writing to the bitmap by locking it and using pointers.

My question is :

Do you know any (faster) way to update a bitmap ?

These pixels are already in memory in the huge bitmap, reading straight from here seems a wise idea; well, get rid of the WriteableBitmap between my Image.Source and my BitmapData.

Thanks for your help :)

+1  A: 

You can try using BitmapSource.CopyPixels to extract the bytes with color information from the image (not sure if you need that) and BitmapSource.Create that creates a bitmap from a byte array (or its overload which can grab color information directly from unmanaged memory).

CommanderZ
I have tried it but it's not as fast as I thought I'd be.
+1  A: 

You can try using InteropBitmap to update the pixels as WriteableBitmap is kind of slow with its CPU bound internal operations. I have some code here that uses it: http://silverlightviewport.codeplex.com/SourceControl/changeset/view/57274#1534506

It's hardcoded for Bgra32, which is the only color space supported by InteropBitmap in 3.5 SP1. In 4.0 it should support 24 bit color spaces.

Jeremiah Morrill
I am currently trying Imaging.CreateBitmapFromMemorySection which according from someone at Microsoft, does copy straight to GPU only when needed. That sounds nice but in fact it takes a little more CPU than my previous method : updating a WriteableBitmap. So I'm back to the starting point, going to try WriteableBitmapEx from CodePlex to see what it does. In fact what I'd want (what I think should fit this issue) is a WriteableBitmap where I can change its BackBuffer.
After some tests, WriteableBitmap wins the match ! The method with Imaging.CreateBitmapFromMemorySection and CopyMemory is when it works, very smooth but CPU goes up 40% ... The application doesn't eat more CPU but the "System" process does ! I am back to starting point at my first solution with the feeling of something more could be done ... I heard Forms performance is much better but I am on WPF ...
I forgot to answer you, your method with InteropBitmap is exactly what I did with CreateFileMapping etc ... it's the best until I go say from 800*256 which is very nice to 1920*256 where CPU goes up 40%. Moreover, I don't know if this is blocking even more but; as I am copying from a bigger bitmap I need multiple CopyMemory because of the different stride; so there are as much CopyMemory as there are lines; but when profiling, there's no more clue on what's causing this ... I need to investigate furthermore !
A: 

Hello everyone,

I have fixed it, using GC.Collect; still can't believe it fixed the problem. Don't know if it's a good practice but it works ...

That gave me headaches and nightmares the last few days but now most is sorted. The funny conclusion I'll have about this, is that GCCollectionMode.Optimized, thinks it's never the time to collect memory, it went up to use 2Gb, destabilizing the whole system (Windows) up to the point it freezes the mouse, lol ...

Thanks for your help :-)