我知道 Winforms 不是为大量图形使用而设计的,但我除了 C# 之外什么都不知道,所以多年来我使用 C# 和 Visual Studio 创建了各种程序,这些程序将事物推向了边缘(在我看来)可以在 Visual Studio / Winforms 的限制下有效地完成。
该程序读取摇滚乐队格式的文件并像音乐播放器一样播放它们,其附加功能是利用摇滚乐队文件中的附加信息(如图表、专辑封面和歌词)来完成体验。一切都运转良好。绘图是在图形上完成的,所有这些都没有加载和移动图像(我发现速度较慢)。
图形的每个实例都附有我在这里找到的以下代码:
graphics.SmoothingMode = SmoothingMode.HighSpeed;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
我相信这有助于提高绩效。
所有绘图都基于以 60Hz(16ms)运行的计时器,因此每秒 60 次,它会在屏幕上绘制所有内容。这适用于除歌词之外的所有内容。我可以在静态模式或卡拉 OK 模式下播放歌词,没有问题。但是,如果我将它们设置为随着声音音符滚动(在上图中,底部的蓝色音符,歌词应该捕捉到这些音符并随之滚动),除非您暂停,否则无法阅读它们,那么就非常困难了。清晰易读。我尝试过将计时器的刷新率从 1 毫秒调整到 500 毫秒,但行为并没有改变。滚动歌词难以辨认。
这是滚动歌词的相关代码:
private void DrawLyricsScrolling(IEnumerable<Lyric> lyrics, Control label, Color color, Graphics graphics)
{
if (!openSideWindow.Checked || PlayingSong == null || btnPlayPause.Tag.ToString() == "play" || !doScrollingLyrics)
return;
var time = GetCorrectedTime();
label.Text = "";
graphics.SmoothingMode = SmoothingMode.HighSpeed;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
using (var pen = new SolidBrush(MediaPlayer.Visible ? picVisuals.BackColor : LabelBackgroundColor))
{
graphics.FillRectangle(pen, label.ClientRectangle);
}
foreach (var lyric in lyrics.TakeWhile(lyric => lyric.LyricStart <= time + PlaybackWindow).Where(lyric => !(lyric.LyricStart + (PlaybackWindow * 2) < time)))
{
var left = (int)(((lyric.LyricStart - time) / PlaybackWindow) * label.Width);
TextRenderer.DrawText(graphics,lyric.LyricText,label.Font,new Point(left, 0),color);
}
}
我希望您能指出我可能做错的地方或我可能完全错过的方向,以提高性能(如果可能的话),在 Winforms 的范围内。我的程序中有超过 6,000 行独特的代码,因此我不打算更改为 WPF 或其他语言或环境。要么可以在 C# / Winforms 中改进,要么就保持这种状态。
谢谢!
您可以尝试使用 EmguCV,它是 OpenCV(用 C++ 编写的机器视觉库)的 C# .net 包装器,它具有用于在图像上绘制文本/形状的内置函数。
NuGet 中的库是:Emgu.CV 和 Emgu.CV.runtime.windows
如果这与您相关,请发表评论,我将就该主题添加更多提示。