Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Why is the WriteableBitmap so cumbersome and inefficient? RSS

6 replies

Last post May 11, 2009 10:16 AM by planetmarshall

(0)
  • medconn

    medconn

    0 Points

    2 Posts

    Why is the WriteableBitmap so cumbersome and inefficient?

    May 09, 2009 06:50 PM | LINK

    I need to create truly dynamic bitmaps - as do many other people doing specialised imaging, ray-tracing etc. etc.

    Why then do we have to set the pixel data "byte-by-byte" using  bitmap[position] = x separateloy (and massivly inefficiently) for each pixel?

    I realise that you have the needs to keep Hollywood happy with all sorts of "security" concerns about bitmaps in general, but I can't see how a WriteableBitmap constructor which took an existing byte[] or int[] as a parameter could be any concern at all?

    Looking at the protected data (_pixels and _accessiblePixels), this should be trivial, either using Array.Copy in a constructor?

    PLEASE ??!?

    This really does make the difference as to whether my proposed Silverlight application is viable or not!

    Dave Harvey

    WriteabeBitmap dynamic bitmaps

  • SharpGIS

    SharpGIS

    Contributor

    4835 Points

    832 Posts

    Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 09, 2009 07:40 PM | LINK

    You might be interested in this:

    http://blogs.msdn.com/nikola/archive/2009/03/04/silverlight-super-fast-dymanic-image-generation-code-revisited.aspx

    or this:

    http://blogs.msdn.com/nikola/archive/2008/06/10/raytracing-in-silverlight.aspx

    --
    /Morten | Silverlight MVP | blog - twitter
    Please click on "Mark as Answer" if this answered your question.
  • ksleung

    ksleung

    Contributor

    6680 Points

    1265 Posts

    Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 09, 2009 09:45 PM | LINK

    SharpGIS,

    Are you saying that the fast PNG approach mentioned in the link is actually faster than updating the image via WriteableBitmap?

    Visit http://www.tagxedo.com, a Silverlight-based word cloud generator. If you like it, please help me spread the word!
  • SharpGIS

    SharpGIS

    Contributor

    4835 Points

    832 Posts

    Re: Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 09, 2009 10:39 PM | LINK

    No (but could very well be...). What I'm saying is that you can initialize this using a full byte array, and it has some pretty cool optimizations for setting pixels at entire rows.

    Personally I think the WritebleBitmap API is useless in 99% of the cases where I want to edit bitmaps, not to mention often overkill.

    --
    /Morten | Silverlight MVP | blog - twitter
    Please click on "Mark as Answer" if this answered your question.
  • medconn

    medconn

    0 Points

    2 Posts

    Re: Re: Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 09, 2009 11:32 PM | LINK

    Messing about with a PNG file might well be quicker than poking values into the _pixels/_accessible pixels one by one in the awful and restricted manner currently provided by WriteableBitmap, but neither method compares to the efficiency and simplicy that would be possible if only Microsoft would add a simple alternative constructor!

    The only current contructor is:

    public WriteableBitmap(int pixelWidth, int pixelHeight, PixelFormat format) : base(0x13a)
    {
        this._isPixelsAccessible = true;
        if (pixelWidth < 0)
        {
            throw new ArgumentOutOfRangeException("pixelWidth");
        }
        if (pixelHeight < 0)
        {
            throw new ArgumentOutOfRangeException("pixelHeight");
        }
        XcpImports.WriteableBitmap_Create(this, pixelWidth, pixelHeight, (int) format.Format);
        this._pixelWidth = pixelWidth;
        this._pixelHeight = pixelHeight;
        this._pixelFormat = format;
        this._pixelArrayLength = this._pixelWidth * this._pixelHeight;
        this._isPixelsAccessible = true;
    }
    ALL that would be needed would be the following (additions in bold)
    public WriteableBitmap(int pixelWidth, int pixelHeight, int[] pixels, PixelFormat format) : base(0x13a)
    {
        this._isPixelsAccessible = true;
        if (pixelWidth < 0)
        {
            throw new ArgumentOutOfRangeException("pixelWidth");
        }
        if (pixelHeight < 0)
        {
            throw new ArgumentOutOfRangeException("pixelHeight");
        }
    if(pixels.Length < pixelHeight*pixelWidth)
    {
    throw new
    ArgumentOutOfRangeException("pixels too short");
    }
    XcpImports.WriteableBitmap_Create(this, pixelWidth, pixelHeight, (int) format.Format); this._pixelWidth = pixelWidth; this._pixelHeight = pixelHeight; this._pixelFormat = format; this._pixelArrayLength = this._pixelWidth * this._pixelHeight; this._isPixelsAccessible = true;
    Array.Copy(pixels, this._accessiblePixels, this._pixelArrayLength); }
    Is this really too much to ask to save hundreds of people having to mess around 
    with bizarre and inefficient intermediate formats?
    The alternative of course would be to encapsulate the Array.Copy call into a public 
    method, thereby giving users the chance to use their own data without needing
    (horror, horror!) to trust them with access to the "accessible" pixels property!
    The WriteableBitmap is far from "overkill" for those of use who need to generate dynamic
    bitmaps....it is marginally better than previous alternatives, but only just, and a long
    way short of what it so easily could be!
    Dave

     

  • neopocott

    neopocott

    Member

    368 Points

    82 Posts

    Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 10, 2009 12:21 PM | LINK

    Hi,

    Actually, you can access either to the WriteableBitmap pixels using bytes or using ints (way faster).

    For example, for a PixelFormats.Bgr32 format, you could write:

    bitmap[width * y + x] = (red << 16) | (green << 8) | blue;

    I recon that WriteableBitmap is not as fast as we could expect but at least it is way faster than the fastest PNG encoder you could write (for example, the one I used in Quake in Silverlight).

    With the above method, I can generate 1280x1024 bitmaps in 50 FPS. With my PNG encoder, this is only 15 FPS.

    Julien Frelat
    Microsoft Client App Dev MVP
    Quake in Silverlight - Twitter - Blog (French)
  • planetmarshall

    planetmarshall

    Member

    88 Points

    22 Posts

    Re: Why is the WriteableBitmap so cumbersome and inefficient?

    May 11, 2009 10:16 AM | LINK

     Well, how cumbersome and how inefficient? There are a number of suggestions made by the other replies, but before I weigh in I would need to know exactly what are your expectations, that is, what do you consider to be "efficient" and "inefficient". You can't just determine this from the APIs, I would need to see some performance metrics.

     For example, you mention ray tracing, however in any scene of even average complexity the computational expense of ray tracing would massively outweigh the bitmap update code.

    There are some performance notes on a Reaction Diffusion simulator I wrote on my own website. It uses Joe Stegman's PNGEncoder class, which is sufficient for my needs because the actual simulation code is the bottleneck in this scenario.

    http://www.planetmarshall.co.uk/index.php/2009/04/implentation-of-the-reaction-diffusion-simulation/
    --
    Andrew Marshall
    http://www.planetmarshall.co.uk