我正在音樂播放器中撰寫劇院模式部分。要求是遍歷包含任何型別(png,jpeg,gif)影像的檔案夾,并在圖片框中顯示型別(png,jpeg)的影像延遲5秒,gif的延遲時間應該是實際的gif時間期間。當在單個圖片框中從一個影像切換到另一個影像時,影像之間應該有淡入淡出過渡。所有需要在軟體空閑時完成讓我們說 60 秒
問題
目前播放歌曲目錄有“img”檔案夾,其中包含 3 個 png 影像和 3 個 gif。第一次嘗試閱讀 Helper.theaterImagesInfo.ToList() 效果很好
foreach (var img in Helper.theaterImagesInfo.ToList())
它開始顯示 3 個具有 5 秒延遲的 png 影像和具有實際 gif 持續時間延遲的 gif 影像。但是,如果我在軟體空閑狀態 60 秒后再次打開表單時單擊圖片框關閉劇院表單,然后回圈繼續再次迭代。默認影像顯示為從“img”檔案夾中開始 2 個 png 影像,第 3 個 png 被跳過,然后第 4 個 gif 開始播放幾秒鐘,而不是實際的 gif 持續時間,并以錯誤的順序和不正確的延遲繼續,看起來像 while 回圈總是在后臺運行。因此它變得波濤洶涌。
所需的解決方案 每當我播放歌曲時,如果歌曲仍在播放,即使在 60 秒后再次打開 theatreform,也應該顯示并開始顯示檔案夾中的影像(以相同的順序和延遲)。另外,如果在單個圖片框中更改影像時可以顯示淡入淡出
代碼在這里
程式.cs
internal static class Program
{
public static Timer IdleTimer = new Timer();
readonly static int miliseconds =
Convert.ToInt32(TimeSpan.FromSeconds(60).TotalMilliseconds);
internal static MainForm f = null;
static public TheaterForm tf;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MessageFilter limf = new MessageFilter();
Application.AddMessageFilter(limf);
Application.Idle = new EventHandler(Application_Idle);
IdleTimer.Interval = miliseconds;
IdleTimer.Tick = TimeDone;
IdleTimer.Start();
f = new MainForm();
tf = new TheaterForm();
var app = new MyApplication();
app.Run(Environment.GetCommandLineArgs());
Application.Idle -= new EventHandler(Application_Idle);
}
static private void Application_Idle(Object sender, EventArgs e)
{
if (!IdleTimer.Enabled) // not yet idling?
IdleTimer.Start();
}
static private void TimeDone(object sender, EventArgs e)
{
IdleTimer.Stop();
if (MainForm.waveOut.PlaybackState == PlaybackState.Playing)
{
if (!Helper.IsTheaterOpen)
{
if (Form.ActiveForm == f)
{
Helper.IsTheaterOpen = true;
tf.WindowState = FormWindowState.Maximized;
tf.Bounds = Screen.PrimaryScreen.Bounds;
tf.x = 1;
tf.ShowDialog(f);
}
}
}
else
{
if (!Helper.IsTheaterOpen)
{
if (Form.ActiveForm == f)
{
Helper.IsTheaterOpen = true;
tf.WindowState = FormWindowState.Maximized;
tf.Bounds = Screen.PrimaryScreen.Bounds;
tf.x = 0;
tf.ShowDialog(f);
}
}
}
}
}
public class MyApplication : WindowsFormsApplicationBase
{
protected override void OnCreateMainForm()
{
MainForm = Program.f;
}
protected override void OnCreateSplashScreen()
{
SplashScreen = new SplashForm();
}
}
助手.cs
internal class Helper
{
public static bool IsTheaterOpen { get; set; }
public struct ImageInfo
{
public bool IsAnimated;
public int durationInMilliseconds;
public Image ImageHere;
}
public static List<ImageInfo> theaterImagesInfo = new List<ImageInfo>(10);
}
MainForm.cs
/*
* Every song directory has one folder named img that contains images and gif relevant
to the song album
*/
private int GetGifDuration(Image img)
{
int delay = 0, this_delay = 0, index = 0;
FrameDimension frameDimension = new FrameDimension(img.FrameDimensionsList[0]);
int frameCount = img.GetFrameCount(frameDimension);
for (int f = 0; f < frameCount; f )
{
this_delay = BitConverter.ToInt32(img.GetPropertyItem(20736).Value, index) * 10;
delay = (this_delay < 100 ? 100 : this_delay); // Minimum delay is 100 ms
index = 4;
}
return delay;
}
private void PlayAudio()
{
// Getting images from folder and storing in struct on every song play
if (Directory.Exists(Path.GetDirectoryName(CurrentPlayingMusicUrl) "\\img"))
{
var files =
Directory.EnumerateFiles(Path.GetDirectoryName(CurrentPlayingMusicUrl)
"\\img", "*", SearchOption.AllDirectories).Where(s => s.EndsWith(".png") ||
s.EndsWith(".jpg") || s.EndsWith(".jpeg") || s.EndsWith(".gif"));
Helper.theaterImagesInfo.Clear();
foreach (var imagePath in files.ToArray())
{
using (System.Drawing.Image image = System.Drawing.Image.FromFile(imagePath))
{
if (image.RawFormat.Equals(ImageFormat.Gif))
{
Helper.theaterImagesInfo.Add(new Helper.ImageInfo { IsAnimated = true, durationInMilliseconds = GetGifDuration(image), ImageHere = Image.FromFile(imagePath) });
}
else
{
Helper.theaterImagesInfo.Add(new Helper.ImageInfo { IsAnimated = false, durationInMilliseconds = 5000, ImageHere = Image.FromFile(imagePath) });
}
}
}
}
else
{
Helper.theaterImagesInfo.Clear();
Program.tf.x = 0;
}
}
TheaterForm.cs
public partial class TheaterForm : Form
{
public TheaterForm()
{
InitializeComponent();
SetDefaultImage();
}
/*
* Getting Default image from top(root) directory ex. AllMusic. If no 'img' folder
found in song album directory ex. AllMusic -> Justin Bieber -> (img folder not
exist)song1, song2, song3 etc.
*/
private async void SetDefaultImage()
{
string path = KJ_Player.Properties.Settings.Default["MusicFolder"] "\\img";
if (Directory.Exists(path))
{
var files = Directory.EnumerateFiles(path, "*",
SearchOption.AllDirectories).Where(s => s.EndsWith(".png") ||
s.EndsWith(".jpg") || s.EndsWith(".jpeg"));
await Task.Run(() =>
{
if(files != null && files.Count()>0)
{
PictureBox1.Image = Image.FromFile(files.FirstOrDefault());
}
});
}
}
public int x=1;
private async void TheaterForm_Shown(object sender, EventArgs e)
{
if (this.PictureBox1.Image == null) SetDefaultImage();
if (Helper.theaterImagesInfo != null && Helper.theaterImagesInfo.Count > 0)
{
while (x == 1)
{
foreach (var img in Helper.theaterImagesInfo.ToList())
{
if (img.IsAnimated)
{
try
{
this.PictureBox1.Image = img.ImageHere;
await Task.Delay(img.durationInMilliseconds);
}
catch { }
}
else
{
try
{
await Task.Delay(img.durationInMilliseconds);
this.PictureBox1.Image = img.ImageHere;
}
catch { }
}
}
}
SetDefaultImage();
}
}
private void PictureBoxTheater_Click(object sender, EventArgs e)
{
this.x = 0;
if (this.PictureBox1.Image != null) this.PictureBox1.Image=null;
Helper.IsTheaterOpen = false;
this.Close();
}
}
uj5u.com熱心網友回復:
很可能您只需要跳出那個foreach回圈:
foreach (var img in Helper.theaterImagesInfo.ToList())
{
if (img.IsAnimated)
{
try
{
this.PictureBox1.Image = img.ImageHere;
await Task.Delay(img.durationInMilliseconds);
}
catch { }
}
else
{
try
{
await Task.Delay(img.durationInMilliseconds);
if (this.x == 1) {
this.PictureBox1.Image = img.ImageHere;
}
}
catch { }
}
if (this.x == 0) {
break; // exit the for loop early
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/454932.html
下一篇:如何為鏈接標簽設定事件監聽器?
