0

同様の問い合わせのページをいくつか見て、ほとんどの提案を実装しましたが、これまでに機能したものは何も見つからないようです. うまくいけば、私は明白な何かを見落としていません。

そうですね、AForge.net を使用して画像をキャプチャしています。受信した新しいフレームごとにトリガーされるイベントを提供します。これは、私のコードでは次のようになります。

private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
    {
        framesRecieved++;
        try
        {
            if (!stopCapturing)
            {
                if (pictureBox1.Image != null)
                {
                    pictureBox1.Image.Dispose();
                }
                pictureBox1.Image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), image.PixelFormat);
            }

        }
        catch { }
        finally { GC.Collect(); }
    }

ウィンドウが静止している限り、メモリ使用量は非常に安定していますが、ウィンドウ フォームをつかんで動かし始めるとすぐに、メモリ使用量は増え続けます。ピクチャボックスに関連している可能性があると信じるようになった理由は、「stopCapturing」ブールをtrueにするとすぐに、ウィンドウを画面上で動かしてもメモリの増加が止まるためです。「stopCapturing」は他には使用されず、イベントは通常どおりトリガーされ続けます。唯一の違いは、画像ボックスに表示される画像です。原因が分からないので、どなたか教えていただければ幸いです。

PS: 関連しているかどうかはわかりませんが、私のワークステーションには 2 つの画面があります。

4

2 に答える 2

0

Bitmap.Clone()は浅いコピーを行いますが、実際のバイトは依然として呼び出し元が所有しているため、あらゆる種類の問題が発生する可能性があります。ディープコピーを行う必要があります。

たとえば、AForge の方法:

Bitmap bmp = AForge.Imaging.Image.Clone(image);

または GDI+ の方法 (パフォーマンスを向上させるためにロックビットなどを使用することもできます):

Bitmap bmp = new Bitmap(image.Width, image.Height, image.PixelFormat);
Graphics g = Graphics.FromImage(bmp);
g.DrawImageUnscaled(image, Point.Empty);
于 2013-03-21T19:46:11.840 に答える
0

なぜイメージを複製しているのか不思議です。pictureBox1.Image が null の場合、または画像のサイズまたはピクセル形式が変更された場合にのみ、新しい画像を割り当てる必要があることに気付きました。

private bool BitmapChanged(Bitmap old, Bitmap new)
{
    return old == null || old.PixelFormat != new.PixelFormat ||
        old.Width != new.Width || old.Height != new.Height;
}

private Bitmap MakeSimilarBitmap(Bitmap source)
{
    Bitmap copy = new Bitmap(source.Width, source.Height, source.PixelFormat);
    return copy;
}

private void DrawOnto(Image im, Bitmap source)
{
    using (Graphics g = Graphics.FromImage(im)) {
        g.DrawImage(source, 0, 0);
    }
}

フレームを取得したら、次のようにします。

Image im = BitmapChanged(pictureBox1.Image as Bitmap, srcBmp) ?
                          MakeSimilarBitmap(image) : pictureBox1.Image;
DrawOnto(im, srcBmp);
bool same = im == pictureBox1.Image;
if (same)
    pictureBox1.Invalidate();
else {
    Image old = pictureBox1.Image;
    pictureBox1.Image = im;
    old.Dispose();
}
于 2013-03-21T20:28:15.523 に答える