How to write to a (Bitmap?) image buffer for faster GDI+ displays?

前端 未结 5 788
眼角桃花
眼角桃花 2021-01-07 11:14

Using C++ and .net I have a stream of data I want to display as a scrolling image. Each time I get some new data I want to add it as a new row (128x1 pixels) and scroll the

5条回答
  •  忘掉有多难
    2021-01-07 11:58

    Try the following:

    • Start a new VC++ WinForms application.
    • Add a user control named 'Spectrogram' to the project
    • Add a timer control to the 'Spectrogram' user control and set the 'Enabled' property to true
    • Add the following private variables to the 'Spectrogram' user control
    private:
    Graphics ^m_gfxBuffer;
    Graphics ^m_gfxOriginal;
    Bitmap ^m_bmpBuffer;
    Bitmap ^m_bmpOriginal;
    
    • Add the following code to the 'Spectrogram' constructor:
    
    m_bmpBuffer = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
    m_gfxBuffer = Graphics::FromImage(m_bmpBuffer);
    m_bmpOriginal = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
    m_gfxOriginal = Graphics::FromImage(m_bmpOriginal);
    this->SetStyle(::ControlStyles::AllPaintingInWmPaint | ::ControlStyles::DoubleBuffer | ::ControlStyles::UserPaint | ::ControlStyles::OptimizedDoubleBuffer, true);
    this->UpdateStyles();
    
    • Add the following code to the 'Spectrogram' paint event:
    
    array ^bytes = gcnew array(m_bmpBuffer->Height * 3);
    Random ^r = gcnew Random();
    r->NextBytes(bytes);
    
    m_gfxOriginal->DrawImage(m_bmpBuffer, -1, 0);
    
    int y = 0;
    for (int i = 0; i < m_bmpOriginal->Height * 3; i += 3)
    {
      m_bmpOriginal->SetPixel(m_bmpOriginal->Width - 1, y++, ::Drawing::Color::FromArgb(255, bytes[i], bytes[i + 1], bytes[i + 2]));
    }
    
    m_gfxBuffer->DrawImage(m_bmpOriginal, 0, 0);
    e->Graphics->DrawImage(m_bmpOriginal, 0, 0);    
    
    • Add the following code the 'Spectrogram' timers tick event
    
    this->Invalidate(false);
    
    • Save your project
    • Clean and Rebuild
    • Run the project
    • Close the running Form
    • The Spectrogram user control should now be in the 'Toolbox'
    • Drag it from the 'Toolbox' to the form and you should see a scrolling random colored Spectrogram of sorts.

    This should give you a general idea of a bitmap buffered control. The key here is the "SetStyle" call in the constructor and the offset of the bitmap by -1 in the paint event.

    You will have to properly dispose of the graphics and bitmap objects as well as handle destroying and rebuilding them in the resize event.

    Hope this helps. Let me know how it goes.

提交回复
热议问题