回憶視窗小程式

回憶視窗小程式

第一支自己無聊發想寫出來的程式

使用C#,需.NET Framework 4.5

用法,將執行檔與欲瀏覽照片放在同個資料夾,即可全部隨機 or 指定日期區段隨機瀏覽

起意是我出去玩喜歡拍照片,但照片量太多不喜歡照順序看且偶爾只想回憶那年那天做了什麼的時候

就把所有出去玩的照片丟進去,邊看邊有種驚喜的感覺,對齁我來過這邊..我那時候還做了這種事,等等

視窗畫面如下

程式原碼

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RandomPic
{
    public partial class frmMain : Form
    {
        /// <summary>
        /// 存放指定資料夾裡所有檔案的路徑
        /// </summary>
        string[] picPaths = null;
        /// <summary>
        /// 存放指定時間區段所有檔案的路徑
        /// </summary>
        ArrayList picRange = new ArrayList();

        Random randomNum = new Random(Guid.NewGuid().GetHashCode()); // 用雜湊產生亂數
        //Random randomNum = new Random(DateTime.UtcNow.Millisecond); // 用毫秒產生亂數
        int picIndex = 0;

        public frmMain()
        {
            InitializeComponent();
            // 將日期選取預設為空白
            dtpBegin.CustomFormat = dtpEnd.CustomFormat = " ";
            dtpBegin.Format = dtpEnd.Format = DateTimePickerFormat.Custom;
        }
        private void frmMain_Load(object sender, EventArgs e)
        {
            // 產生指定資料夾的隨機圖片路徑
#if (DEBUG)
            picPaths = Directory.GetFiles("../Picture/"); // System/Picture裡所有檔案
#else
            picPaths = Directory.GetFiles(Application.StartupPath); // 同資料夾所有檔案
#endif
            picIndex = randomNum.Next(picPaths.Count() - 1); // 產生亂數圖片序號
        }
        private void frmMain_Shown(object sender, EventArgs e)
        {
            // 將決定的圖片路徑指向pbx
            if (picPaths != null)
            {
                FileStream fs = File.OpenRead(picPaths[picIndex]);
                pbxMain.Image = Image.FromStream(fs);
                fs.Close();
            }
            else
            {
                MessageBox.Show("資料夾裡沒有可顯示圖片!");
            }
        }
        private void btnChange_Click(object sender, EventArgs e)
        {
            try
            {
                if (picRange.Count > 0) // 選取的日期有符合檔案
                {                    
                    pbxMain.Image.Dispose();
                    picIndex = randomNum.Next(picRange.Count - 1);

                    FileStream fs = File.OpenRead(picRange[picIndex].ToString());
                    pbxMain.Image = Image.FromStream(fs);
                    fs.Close();
                }
                else if (dtpBegin.Format == DateTimePickerFormat.Short && dtpEnd.Format == DateTimePickerFormat.Short) // 選取的日期沒有符合檔案
                {
                    MessageBox.Show("這個日期區段沒有符合的照片喔!");
                }
                else // 沒有選取日期
                {                    
                    pbxMain.Image.Dispose();
                    picIndex = randomNum.Next(picPaths.Count() - 1);

                    FileStream fs = File.OpenRead(picPaths[picIndex]);
                    pbxMain.Image = Image.FromStream(fs);
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                // 即使有例外也讓程式繼續執行
#if(DEBUG)
                MessageBox.Show(ex.ToString());
#endif
            }
        }
        private void dtp_ValueChanged(object sender, EventArgs e)
        {
            if (dtpBegin.Value == null || dtpEnd.Value == null)
            {
                return;
            }
            else
            {
                string strdtpBegin = dtpBegin.Value.ToString("yyyy/MM/dd");
                string strdtpEnd = dtpEnd.Value.ToString("yyyy/MM/dd");
                dtpBegin.Value = DateTime.Parse(strdtpBegin + " 00:00:00");
                dtpEnd.Value = DateTime.Parse(strdtpEnd + " 23:59:59");
            }

            picRange.Clear();
            foreach (string pic in picPaths)
            {
                // 讀取照片資訊並挑出符合日期的檔案
                System.IO.FileInfo diImage = new System.IO.FileInfo(pic);

                DateTime picTime = new DateTime();

                FileStream stream = new FileStream(diImage.Name, FileMode.Open, FileAccess.Read);
                System.Drawing.Image image = System.Drawing.Image.FromStream(stream, true, false);
                PropertyItem[] r = image.PropertyItems;
                stream.Close();

                Encoding ascii = Encoding.ASCII;
                int intSpaceLoc = 0;
                string strDateTime = "";
                foreach (System.Drawing.Imaging.PropertyItem p in r)
                {
                    if (p.Id == 0x0132)
                    {
                        strDateTime = ascii.GetString(p.Value);
                        intSpaceLoc = strDateTime.IndexOf(" ");
                        string date = strDateTime.Substring(0, intSpaceLoc);
                        date = date.Replace(":", "-");
                        string time = strDateTime.Substring(intSpaceLoc + 1, strDateTime.Length - intSpaceLoc - 2);
                        strDateTime = date + " " + time;

                        picTime = Convert.ToDateTime(strDateTime);
                    }
                }
                if (picTime >= dtpBegin.Value && picTime <= dtpEnd.Value)
                {
                    picRange.Add(pic);
                }
            }
        }
        private void dtpButton_DropDown(object sender, EventArgs e)
        {
            if (dtpBegin.Format == DateTimePickerFormat.Custom && dtpEnd.Format == DateTimePickerFormat.Custom)
            {
                dtpBegin.Format = dtpEnd.Format = DateTimePickerFormat.Short;
            }
        }
        private void dtpButton_CloseUp(object sender, EventArgs e)
        {
            if (dtpBegin.Value > dtpEnd.Value)
            {
                MessageBox.Show("起始日期請勿超過結束日期!!");
                dtpBegin.Value = dtpEnd.Value;
            }
        }
    }
}

小記,此程式初版原為抓取"檔案建立時間"來判斷,後覺得照片當然是要以拍攝時間為主

而照片的拍攝時間字串並不符合 DateTime 格式,使用網路資料他人提供調整的方式,完成現在的程式

參考文章

之後有空再新增簡單的編輯照片功能(朋友建議,看到歪的照片很麻煩XD)