Harry
Harry

Reputation: 4946

What's wrong with my bitmap? How to get pixel data of what I drew?

Here's my buffer for an animation:

Bitmap PixBuffer;

Here's how I create it:

PixBuffer = new Bitmap(ClientRectangle.Width, ClientRectangle.Height, PixelFormat.Format32bppArgb);

Here's how I draw on it:

Graphics Renderer { get { return Graphics.FromImage(PixBuffer); } }

To make long story short. It works. I draw. I see changes. I use the bitmap as BackgroundImage for a window. Since the window has DoubleBuffered = true, it's silky smooth and fast.

OK, and the WTF part. I try to clone a slice of my bitmap, or even whole thing:

PixBuffer = (Bitmap)PixBuffer.Clone();

It doesn't make much sense, it should do nothing with what's displayed. But guess what - the clone is EMPTY! Exactly the same result if I try to draw PixBuffer on a new bitmap. The contents of PixBuffer is displayed. It can be even stretched as windows background. But I see no way to copy it. RotateFlip has no effect too.

What am I doing wrong? How to get pixel data of what I drew?

                Freeze = (Bitmap)PixBuffer.Clone();
                using (var g = Graphics.FromImage(Freeze)) {
                    g.FillRectangle(BrushF, 0, 0, 100, 100);
                    g.CompositingMode = CompositingMode.SourceOver;
                    g.Dispose();
                }
                var test = (Bitmap)Freeze.Clone();
                BackgroundImage = test;

When I set PixBuffer as BackgroundImage - I get my drawn image. When I set Freeze as BackgroundImage - I get a square.

Then, if I clone Freeze to let's say Freeze1 - I still get my square, so cloning actually works on some bitmaps. But on PixBuffer NO JOY!

PixBuffer is not drawn in one frame. It is drawn as progressing animation during ca 30s. After animation completes - I have still screen - this screen I want to have as a normal bitmap to manipulate (like scaling and such). It seems like PixBuffer is write-only. I can still draw on it, but I can't copy anything from it.

I even tried to convert it to Icon and then back to Bitmap - but it's exactly the same like I was doing operations on empty Bitmap object.

But it IS NOT EMPTY! I tested it. I removed the BackgroundImage. I set another image in its place. And then I set PixBuffer as BacgroundImage again - and it is not empty, there is all I drew.

I'm missing something.

Upvotes: 1

Views: 218

Answers (1)

Harry
Harry

Reputation: 4946

It's one of those very nasty bugs in code.

    void RenderFrame(object sender, EventArgs e) {
        using (var r = Graphics.FromImage(PixBuffer)) r.Clear(Color.Transparent);
        var end = false;
        for (var i = 0; i < Speed; i++) if (end = !UnmaskOne()) break;
        RenderText();
        RenderPattern();
        if (end) FreezeContent = true;
        Refresh();
    }

I tried to copy my bitmap in UnmaskOne() method, which is called directly after clearing the frame, since this method can detect, if there's nothing more to unmask. However I had to wait with copying the bitmap - it should be drawn first with RenderText() and RenderPattern() methods. No magic here. Just plain human error.

Upvotes: 1

Related Questions