Реализация Tiny Image Tagger на C #

Я пытаюсь реализовать крошечный теггер изображений с настраиваемыми параметрами тегов на C #. Главное окно выглядит следующим образом.

ГлавнаяUI Рисунок

Левый блок — это графическая коробка. MainPictureBox и есть две кнопки, PreviousButton и NextButton. Кроме того, в групповом поле есть несколько тегов. AttributeGroupBox. Кнопка сохранения SaveButton используется для сохранения информации с тегами.

Реализованные функции:

  • Загружать изображения автоматически в папку, в которой находится программа.

  • Каждое изображение можно было пометить.

  • Информация тега каждого изображения может быть сохранена в виде текстового файла. LabelResult.txt.

Экспериментальная реализация

  • Attribute Учебный класс
class Attribute
{
    public enum AttributeEnum
    {
        Mountain,
        Cat
    }

    public AttributeEnum attributeEnum;

    public override string ToString()
    {
        if (this.attributeEnum.Equals(AttributeEnum.Cat))
        {
            return "Cat";
        }
        if (this.attributeEnum.Equals(AttributeEnum.Mountain))
        {
            return "Mountain";
        }
        return "";
    }
}
  • Главная Winform
public partial class Form1 : Form
{
    List<string> ImagePaths;
    List<Attribute> AttributeList;
    int index = 0;
    string targetDirectory = "./";
    public Form1()
    {
        InitializeComponent();

        
        System.IO.FileSystemWatcher watcher = new FileSystemWatcher()
        {
            Path = targetDirectory,
            Filter = "*.jpg | *.jpeg| *.bmp | *.png"
        };
        // Add event handlers for all events you want to handle
        watcher.Created += new FileSystemEventHandler(OnChanged);
        // Activate the watcher
        watcher.EnableRaisingEvents = true;

        ImagePaths = new List<string>();
        
        string[] fileEntries = System.IO.Directory.GetFiles(targetDirectory);
        foreach (string fileName in fileEntries)
        {
            string filenameExt = System.IO.Path.GetExtension(fileName);
            if (filenameExt.Equals(".jpg") ||
                filenameExt.Equals(".jpeg") ||
                filenameExt.Equals(".bmp") ||
                filenameExt.Equals(".png")
                )
            {
                ImagePaths.Add(fileName);
            }
        }
        MainPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
        MainPictureBox.Image = Image.FromFile(ImagePaths[0]);

        AttributeList = new List<Attribute>();
        
    }

    private void OnChanged(object source, FileSystemEventArgs e)
    {
        ImagePaths.Clear();
        string[] fileEntries = System.IO.Directory.GetFiles(targetDirectory);
        foreach (string fileName in fileEntries)
        {
            string filenameExt = System.IO.Path.GetExtension(fileName);
            if (filenameExt.Equals(".jpg") ||
                filenameExt.Equals(".jpeg") ||
                filenameExt.Equals(".bmp") ||
                filenameExt.Equals(".png")
                )
            {
                ImagePaths.Add(fileName);
            }
        }
    }

    private void PreviousButton_Click(object sender, EventArgs e)
    {
        index--;
        if (index <= 0)
        {
            index = 0;
        }
        MainPictureBox.Image = Image.FromFile(ImagePaths[index]);
        GC.Collect();
    }

    private void NextButton_Click(object sender, EventArgs e)
    {
        NextAction();
    }

    private void NextAction()
    {
        index++;
        if (index >= ImagePaths.Count)
        {
            index = ImagePaths.Count - 1;
        }
        MainPictureBox.Image = Image.FromFile(ImagePaths[index]);
        GC.Collect();
    }

    private void SaveButton_Click(object sender, EventArgs e)
    {
        Attribute attribute = new Attribute();
        
        if (radioButton1.Checked)
        {
            attribute.attributeEnum = Attribute.AttributeEnum.Mountain;
        }
        if (radioButton2.Checked)
        {
            attribute.attributeEnum = Attribute.AttributeEnum.Cat;
        }
        MessageBox.Show(attribute.ToString());
        AttributeList.Add(attribute);
        AttributeListToTxt();
        NextAction();
    }

    private void AttributeListToTxt()
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < this.AttributeList.Count; i++)
        {
            sb.Append(this.ImagePaths[i] + "t" + this.AttributeList[i].ToString() + Environment.NewLine);
        }
        File.WriteAllText("LabelResult.txt", sb.ToString());
    }
}

Все предложения приветствуются.

Если есть какие-либо улучшения по поводу:

  • Возможный недостаток или ненужные накладные расходы
  • Дизайн реализованных методов

пожалуйста, дайте мне знать.

1 ответ
1

Есть много возможностей для улучшения

Атрибут

  • Существует встроенный класс в BCL с тем же именем, которые помогут вам определить декораторы.
    • Поэтому я бы не рекомендовал так называть ваш класс.
  • AttributeEnum: Мне лично не нравится включать перечисления в определение класса.
    • Использование также действительно странное (заикание): Attribute.AttributeEnum.Cat
  • Вам не нужно выполнять такое ветвление: this.attributeEnum.Equals(AttributeEnum.Cat)
    • this.attributeEnum.ToString("G") было бы достаточно. Ссылка

Форма 1

  • FileSystemWatcher одноразовый, поэтому обязательно утилизируйте его
  • Расширения файлов: повторяются не менее 3 раз.
    • Пожалуйста, предпочитайте общеклассовые константы
  • watcher.Created += OnChanged: Это действительно заблуждение, потому что watcher есть мероприятие для Измененный также.
  • System.IO.Directory.GetFiles(targetDirectory): Выполнение операции ввода-вывода внутри ctor не является хорошей практикой.
    • Пожалуйста, переместите каждую несущественную логику в Init метод.
  • GC.Collect();: Пожалуйста, никогда не звоните GC.Collect напрямую. Ссылка:

Вызывается метод GC.Collect. Практически во всех случаях вам не нужно вызывать этот метод, потому что сборщик мусора работает непрерывно. Этот метод в основном используется для уникальных ситуаций и тестирования.

  • NextAction: Это наименование не имеет никакого значения.
    • Пожалуйста, используйте осмысленные имена.
  • radioButton1.Checked: Еще раз, пожалуйста, используйте осмысленное именование.
    • Например rb_Montain был бы намного лучшим вариантом.
  • AttributeListToTxt: Попробуйте называть свои методы так, чтобы они начинались с глагола, например: PersistAttributeListIntoTxt или же SaveAttributeList, так далее.
    • Почему бы вам просто не писать построчно вместо того, чтобы составлять весь контент, а затем написать его один раз.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *