From ec0a1a0def5107494ea3ba98efb0c2074d20f653 Mon Sep 17 00:00:00 2001 From: Sepera-okeq <54331959+Sepera-okeq@users.noreply.github.com> Date: Sun, 3 Nov 2024 16:14:25 +0300 Subject: [PATCH] feat: 1.2 (add support filters) --- .../dds_evrika_plugin/Manual.html | 31 ++++--- .../dds_evrika_plugin/dds_evrika_plugin.py | 91 +++++++++++++------ README.md | 44 ++++++--- 3 files changed, 110 insertions(+), 56 deletions(-) diff --git a/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/Manual.html b/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/Manual.html index 0acdc5a..3d4445b 100644 --- a/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/Manual.html +++ b/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/Manual.html @@ -21,17 +21,18 @@
-

Krita DDS Evrika Plugin - User Manual (Updated 1.1)

+

Krita DDS Evrika Plugin - User Manual (Updated 1.2)

Introduction

The DDS Evrika Plugin is an extension for Krita, enabling users to import and export DDS - image files using ImageMagick. DDS (DirectDraw Surface) is a popular format for storing textures and - images optimized for real-time rendering, often used in video games and 3D applications.

-

This updated version introduces support for customizable import, export settings, mipmap levels, and - integration with Krita's scripting interface for a more flexible workflow.

+ image files using ImageMagick. DDS (DirectDraw Surface) is a popular format for storing textures and + images optimized for real-time rendering, often used in video games and 3D applications.

+

This updated version introduces the ability to choose filters during export (Lanczos, Box, and more), + customizable import/export settings, mipmap levels, and integration with Krita's scripting interface + for a more flexible workflow.

@@ -45,8 +46,7 @@

Installation

  • Ensure that ImageMagick is installed and available in the "resources" folder of the plugin.
  • Restart Krita after copying the plugin files.
  • -
  • Activate the plugin from the Krita interface via "Tools > Scripts > Evrika DDS Plugin". -
  • +
  • Activate the plugin from the Krita interface via "Tools > Scripts > Evrika DDS Plugin".
  • @@ -58,7 +58,7 @@

    Importing DDS Files

    1. Navigate to Tools > Scripts > Import DDS.
    2. Select the DDS file you want to open.
    3. -
    4. The file will be converted to a chosen format such as PNG or TGA (based on your settings).
    5. +
    6. The file will be converted to a chosen format such as PNG, TIFF, GIF, or TGA (based on your settings).
    7. The image will open in Krita after conversion.
    @@ -71,10 +71,11 @@

    Importing DDS Files with Custom Format

    Exporting DDS Files

    -

    Exporting is straightforward with options for selecting compression and mipmap levels:

    +

    Exporting is straightforward with options for selecting compression, mipmap levels, and filters:

    1. Navigate to Tools > Scripts > Export DDS.
    2. -
    3. Select the compression type (DXT1, DXT3, DXT5, BC7) and set the Mipmap Levels (Auto, 1-5).
    4. +
    5. Select the compression type (DXT1, DXT3, DXT5, BC7) and set the Mipmap levels (Auto, 1-5).
    6. +
    7. Select a filter option (Lanczos, Box, Triangle, Mitchell, or Catmull-Rom)
    8. Export the file using the DDS format.
    @@ -83,18 +84,19 @@

    Exporting DDS Files with Custom Settings

    1. Use Tools > Scripts > Export DDS as....
    2. Select custom compression settings (DXT1, DXT3, DXT5, BC7, or None).
    3. -
    4. Adjust Mipmap levels, and export the file with the desired DDS settings.
    5. +
    6. Adjust Mipmap levels and filter settings.
    7. +
    8. Export the file with the desired DDS settings.

    Plugin Settings

    The DDS Evrika Plugin allows saving custom settings, simplifying the import/export process. Access the - settings dialog by navigating to:

    + settings dialog by navigating to:

    1. Tools > Scripts > Evrika Settings
    2. Adjust the plugin to use the original filenames during import/export.
    3. -
    4. Customize export file names and formats based on your preferences.
    5. +
    6. Customize export file names, filters, and formats based on your preferences.
    7. Configure default import/export formats for quicker conversions.
    @@ -107,8 +109,7 @@

    Troubleshooting

    works on your system.
  • Double-check if the plugin was copied into the correct directory.
  • If Krita crashes or hangs during conversion, verify the file size and available system memory.
  • -
  • If MipMap issues occur during export, try reducing the mipmap level setting to "Auto" for better - compatibility.
  • +
  • If MipMap or filter issues occur during export, try tweaking the mipmap level or filter setting for better compatibility.
  • diff --git a/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/dds_evrika_plugin.py b/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/dds_evrika_plugin.py index 2247ec8..348dc0e 100644 --- a/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/dds_evrika_plugin.py +++ b/DDS_EVRIKA_PLUGIN/dds_evrika_plugin/dds_evrika_plugin.py @@ -70,21 +70,17 @@ def __init__(self, settings_manager): else: self.locale_en() - # Основной layout layout = QVBoxLayout(self) - # Секция для временных имен файлов self.temp_export_check = QCheckBox(self.translations["use_original_export_name"]) self.temp_import_check = QCheckBox(self.translations["use_original_import_name"]) self.export_name_input = QLineEdit() self.export_name_input.setPlaceholderText(self.translations["export_custom_name"]) - # Загрузка сохраненных настроек self.temp_export_check.setChecked(self.settings.get("use_original_export_name", False)) self.temp_import_check.setChecked(self.settings.get("use_original_import_name", False)) self.export_name_input.setText(self.settings.get("export_custom_name", "")) - # Импорт и экспорт: выбор формата и компрессии form_layout = QFormLayout() self.import_format_combo = QComboBox() self.import_format_combo.addItems(["png", "tiff", "bmp", "jpeg", "tga"]) @@ -98,16 +94,18 @@ def __init__(self, settings_manager): self.export_mipmap_combo.addItems(["1", "2", "3", "4", "5", "Auto"]) self.export_mipmap_combo.setCurrentText(self.settings.get("export_mipmap", "Auto")) - # Добавляем поля в форму + self.export_filter_combo = QComboBox() + self.export_filter_combo.addItems(["Undefined", "Point", "Box", "Triangle", "Hermite", "Hanning", "Hamming", "Blackman", "Gaussian", "Quadratic", "Cubic", "Catrom", "Mitchell", "Jinc", "Sinc", "SincFast", "Kaiser", "Welch", "Parzen", "Bohman", "Bartlett", "Lagrange", "Lanczos", "LanczosSharp", "Lanczos2", "Lanczos2Sharp", "Robidoux", "RobidouxSharp", "Cosine", "Spline", "Sentinel"]) + self.export_filter_combo.setCurrentText(self.settings.get("export_filter", "Lanczos")) + form_layout.addRow(self.translations["import_format"], self.import_format_combo) form_layout.addRow(self.translations["export_compression"], self.export_compression_combo) form_layout.addRow(self.translations["export_mipmap"], self.export_mipmap_combo) + form_layout.addRow(self.translations["export_filter"], self.export_filter_combo) - # Кнопка "Сохранить" save_button = QPushButton(self.translations["save_settings"]) save_button.clicked.connect(self.save_settings) - # Добавляем элементы на Layout layout.addWidget(QLabel("{}".format(self.translations["temporary_file_settings"]))) layout.addWidget(self.temp_export_check) layout.addWidget(self.temp_import_check) @@ -124,6 +122,7 @@ def locale_ru(self): "import_format": "Формат (импорт)", "export_compression": "Компрессия (экспорт)", "export_mipmap": "Уровни Mipmap (экспорт)", + "export_filter": "Фильтр (экспорт)", "save_settings": "Сохранить настройки", "temporary_file_settings": "Настройки временных файлов", "custom_export_name": "Кастомное имя файла для экспорта", @@ -138,6 +137,7 @@ def locale_en(self): "import_format": "Format (import)", "export_compression": "Compression (export)", "export_mipmap": "Mipmap Levels (export)", + "export_filter": "Filter (export)", "save_settings": "Save settings", "temporary_file_settings": "Temporary file settings", "custom_export_name": "Custom export file name", @@ -145,13 +145,14 @@ def locale_en(self): } def save_settings(self): - """Сохраняем текущие настройки через объект SettingsManager.""" + """Save current settings through the SettingsManager.""" self.settings.set("use_original_export_name", self.temp_export_check.isChecked()) self.settings.set("use_original_import_name", self.temp_import_check.isChecked()) self.settings.set("export_custom_name", self.export_name_input.text()) self.settings.set("import_format", self.import_format_combo.currentText()) self.settings.set("export_compression", self.export_compression_combo.currentText()) self.settings.set("export_mipmap", self.export_mipmap_combo.currentText()) + self.settings.set("export_filter", self.export_filter_combo.currentText()) QMessageBox.information(self, "Evrika Settings", self.translations["saved_seccess_settings"]) @@ -179,6 +180,7 @@ def init_translations(self): "use_saved_settings": "Использовать мои настройки", "overwrite_settings": "Перезаписать текущие настройки", "mipmap_levels": "Уровни Mipmap", + "export_filter": "Фильтр (экспорт)", "ok": "ОК", "cancel": "Отмена", "error": "Ошибка", @@ -198,6 +200,7 @@ def init_translations(self): "use_saved_settings": "Use my settings", "overwrite_settings": "Overwrite current settings", "mipmap_levels": "Mipmap levels", + "export_filter": "Filter (export)", "ok": "OK", "cancel": "Cancel", "error": "Error", @@ -349,11 +352,15 @@ def process_export(self, is_export_as): compression_format = self.settings.get("export_compression", "dxt1") mipmap_levels = self.settings.get("export_mipmap", "Auto") + export_filter = self.settings.get("export_filter", "Lanczos") # Get the export filter setting + + args.extend(["-define", f"dds:compression={compression_format.lower()}"]) - if compression_format != "none": - args.extend(["-define", f"dds:compression={compression_format.lower()}"]) if mipmap_levels != "Auto": args.extend(["-define", f"dds:mipmaps={mipmap_levels}"]) + + # Add the filter option to the ImageMagick command + args.extend(["-filter", export_filter.lower()]) args.append(save_file) @@ -377,11 +384,20 @@ def showImportExportDialog(self, is_import=True): layout.addWidget(compression_format) mipmaps_label = QLabel(self.translations["mipmap_levels"]) + layout.addWidget(mipmaps_label) mipmaps_combo = QComboBox() mipmaps_combo.addItems(["Auto", "1", "2", "3", "4", "5"]) layout.addWidget(mipmaps_combo) - overwrite_checkbox = QCheckBox(self.translations["overwrite_settings"]) + # Добавляем Label и ComboBox для выбора фильтра + filter_label = QLabel(self.translations["export_filter"]) + layout.addWidget(filter_label) + + filter_combo = QComboBox() + filter_combo.addItems(["Lanczos", "Undefined", "Point", "Box", "Triangle", "Hermite", "Hanning", "Hamming", "Blackman", "Gaussian", "Quadratic", "Cubic", "Catrom", "Mitchell", "Jinc", "Sinc", "SincFast", "Kaiser", "Welch", "Parzen", "Bohman", "Bartlett", "Lagrange", "LanczosSharp", "Lanczos2", "Lanczos2Sharp", "Robidoux", "RobidouxSharp", "Cosine", "Spline", "Sentinel"]) + layout.addWidget(filter_combo) + + overwrite_checkbox = QCheckBox(self.translations.get("overwrite_settings", "Overwrite current settings")) layout.addWidget(overwrite_checkbox) buttons_layout = QHBoxLayout() @@ -394,18 +410,19 @@ def showImportExportDialog(self, is_import=True): def save_temporary_settings(): compression = compression_format.currentText() mipmaps = mipmaps_combo.currentText() + filter_option = filter_combo.currentText() # Получаем значение фильтра overwrite = overwrite_checkbox.isChecked() if overwrite: - self.save_user_preferences(compression, mipmaps) + self.save_user_preferences(compression, mipmaps, filter_option) - if is_import: + if is_import: # Для импорта self.process_import_dialog(compression, mipmaps) - else: - self.process_export_dialog(compression, mipmaps) - + else: # Для экспорта + self.process_export_dialog(compression, mipmaps, filter_option) + dialog.accept() - + confirm_button.clicked.connect(save_temporary_settings) cancel_button.clicked.connect(dialog.reject) dialog.exec_() @@ -424,10 +441,10 @@ def process_import_dialog(self, compression_format, mipmap_levels): imagick_path = os.path.join(os.path.dirname(__file__), 'resources', 'magick.exe') if platform == "win32" else 'magick' args = [imagick_path, input_file, output_file] - if compression_format != "none": - args.extend(['-define', f'dds:compression={compression_format.lower()}']) - if mipmap_levels != "Auto": - args.extend(['-define', f'dds:mipmaps={mipmap_levels}']) + #if compression_format != "none": + # args.extend(['-define', f'dds:compression={compression_format.lower()}']) + #if mipmap_levels != "Auto": + # args.extend(['-define', f'dds:mipmaps={mipmap_levels}']) try: subprocess.run(args, check=True) @@ -438,18 +455,22 @@ def process_import_dialog(self, compression_format, mipmap_levels): finally: shutil.rmtree(temp_directory_location) - def process_export_dialog(self, compression_format, mipmap_levels): + def process_export_dialog(self, compression_format, mipmap_levels, filter_option): + """Процесс экспорта с исправлением для обработки компрессии 'none'""" doc = Krita.instance().activeDocument() + if not doc: self.showError(self.translations["no_document"]) return + # Сохранение файла DDS save_file, _ = QFileDialog.getSaveFileName(caption=self.translations["export_dds"], filter="DDS files (*.dds)") if not save_file: return if not save_file.lower().endswith(".dds"): save_file += ".dds" + # Генерация временного файла PNG temp_filename = self.generate_temp_filename(doc.fileName(), ".png", for_export=True) temp_directory_location = os.path.join(os.path.dirname(__file__), "temp_dds_export") if not os.path.isdir(temp_directory_location): @@ -458,27 +479,43 @@ def process_export_dialog(self, compression_format, mipmap_levels): temp_png_file = os.path.join(temp_directory_location, temp_filename) doc.saveAs(temp_png_file) + # Путь для работы с ImageMagick imagick_path = os.path.join(os.path.dirname(__file__), "resources", "magick.exe") if platform == "win32" else "magick" + + # Создаем список аргументов для команды args = [imagick_path, temp_png_file] - if compression_format != "none": - args.extend(["-define", f"dds:compression={compression_format.lower()}"]) + # Добавляем фильтр + if filter_option: + args.extend(["-filter", filter_option]) + + # Указываем формат компрессии, включая "none" + args.extend(["-define", f"dds:compression={compression_format.lower()}"]) + + # Добавляем количество уровней Mipmap, если оно не "Auto" if mipmap_levels != "Auto": args.extend(["-define", f"dds:mipmaps={mipmap_levels}"]) + # Даем команду сохранить файл в формате DDS args.append(save_file) + # Показываем финальную версию аргументов команды для ImageMagick + #QMessageBox.information(None, "Отладка", f"Сформированная команда для ImageMagick:\n{' '.join(args)}") + try: + # Запускаем команду через subprocess subprocess.run(args, check=True) - self.showMessage(self.translations["file_saved"] + save_file) + self.showMessage(self.translations["file_saved"] + save_file) # Сообщаем об успешном сохранении except subprocess.CalledProcessError as e: self.showError(self.translations["error_processing"] + str(e)) finally: - shutil.rmtree(temp_directory_location) + shutil.rmtree(temp_directory_location) # Удаляем временные файлы - def save_user_preferences(self, compression, mipmaps): + def save_user_preferences(self, compression, mipmaps, filter_option): + """Сохраняем пользовательские параметры экспорта, включая фильтр""" self.settings.set("saved_compression", compression) self.settings.set("saved_mipmap", mipmaps) + self.settings.set("saved_filter", filter_option) def showError(self, message): messageBox = QMessageBox() diff --git a/README.md b/README.md index e8a9b01..2dfdf67 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,18 @@ ## Overview -**DDSEvrikaPlugin** is a plugin for Krita that allows users to import and export DDS (DirectDraw Surface) files with advanced compression and mipmap options. Using the power of ImageMagick, this plugin helps artists and game developers handle textures and images optimized for real-time rendering. +**DDSEvrikaPlugin** is a plugin for Krita that allows users to import and export DDS (DirectDraw Surface) files with advanced compression, mipmap, and filter options. The plugin relies on the power of ImageMagick to handle image format conversions and compressions, making it an ideal tool for texture creation and optimization in video games and 3D rendering environments. With **DDSEvrikaPlugin**, you can: - Import DDS files into Krita and convert them to editable formats. - Export Krita documents using various DDS compression formats, including `dxt1`, `dxt3`, `dxt5`, `bc7`, and more. -- Customize export settings such as DDS compression type, mipmap levels, and file naming options. +- Customize export settings such as DDS compression type, mipmap levels, filter options, and file naming configuration. + +## What's New in Version 1.2 + +- Added **filter support** during DDS export (available filters: Lanczos, Box, Triangle, Mitchell, and Catmull-Rom), enhancing the control over image resizing and quality. +- Improved **transparency handling**: Added guidelines for selecting an appropriate compression format (such as **DXT5**) to better handle textures with transparency or alpha channels. ## Features @@ -18,17 +23,21 @@ With **DDSEvrikaPlugin**, you can: 2. **Export DDS**: - Export images from Krita in DDS format using various compression options. - - Choose advanced DDS compression formats: `dxt1`, `dxt3`, `dxt5`, `bc7`, `none`. - - Control mipmap levels for enhanced texture quality across multiple resolutions. + - Choose advanced DDS compression formats: `dxt1`, `dxt3`, `dxt5`, `bc7`, or disable compression entirely with `none`. + - Easily control mipmap levels for better texture resolution handling. + - Apply filters like **Lanczos**, **Box**, **Mitchell**, among others, to control the image export quality. 3. **Settings Flexibility**: - - Customize how DDS files are named during import and export (retain original names or do custom naming). - - Automatically save and reuse your preferred import/export settings for more efficient workflows. + - Customize DDS file naming options (retain original names or create custom names). + - Automatically save and reuse your preferred import/export settings for faster workflows. + +4. **Improved Transparency Handling**: + - When dealing with semi-transparent images, use **DXT5** compression to preserve smooth transitions in transparency. -4. **ImageMagick Integration**: +5. **ImageMagick Integration**: - Leverage ImageMagick for robust image format conversions and compression processes. -5. **Localization Support**: +6. **Localization Support**: - English - Russian @@ -48,11 +57,11 @@ With **DDSEvrikaPlugin**, you can: ### Step 4: Enable the Plugin -- After restart, go to `Tools -> Scripts -> DDSEvrikaPlugin` to verify that the plugin is available in the Krita interface. +- After restart, go to `Tools -> Scripts -> DDSEvrikaPlugin` to ensure that the plugin is available. ## Alternative Installation -### Step 1: Download the Plugin (No ImageMagick include in archive) +### Step 1: Without ImageMagick included in the archive - Download the latest plugin version from [the official release page](https://github.com/Sepera-okeq/DDS-Evrika-Plugin/releases/latest). @@ -90,7 +99,8 @@ With **DDSEvrikaPlugin**, you can: 1. Navigate to `Tools -> Scripts -> Export to DDS`. 2. Select the desired DDS compression format and mipmap level. -3. The exported `.dds` file will be saved to your chosen directory. +3. Choose a filter (such as **Lanczos**, **Box**, or **Mitchell**) for optimal quality. +4. The exported `.dds` file will be saved to your chosen directory. ### Import/Export with Advanced Settings @@ -101,12 +111,17 @@ With **DDSEvrikaPlugin**, you can: - **Compression Formats**: Choose from `dxt1`, `dxt3`, `dxt5`, `bc7`, or none. - **Mipmap Levels**: Choose automatic mipmap detection or select levels 1-5. -- **File Naming**: Options to use original file names or temp generate name. Add support specify custom export name. +- **Image Filters**: Apply filters (Lanczos, Box, Mitchell, Catmull-Rom, Triangle) during the export process to manage image resizing quality. +- **File Naming**: Options to use original file names or generate custom names. Supports specifying custom export names. ## Requirements - **Krita 4.2+**: Ensure you have Krita version 4.2 or higher. -- **ImageMagick**: Installed and configured in your system's PATH. Use the provided `magick.exe` for Windows systems, or globally install ImageMagick on Linux and MacOS (`apt`/`brew`). +- **ImageMagick**: Installed and configured in your system's PATH. Use the provided `magick.exe` for Windows systems, or install ImageMagick globally on Linux and macOS (`apt`/`brew`). + +## Known Issues with Transparency + +For images containing transparency or semi-transparent areas, it is recommended to use the **DXT5** compression format. **DXT1**, while efficient, supports only binary transparency, leading to the loss of partial transparency. If this compression format is selected in conjunction with filters like **Lanczos**, it may blend and remove transparency, so use **DXT5** to preserve a smooth transition. ## Support & Troubleshooting @@ -119,9 +134,10 @@ With **DDSEvrikaPlugin**, you can: 2. **Issue: DDS export fails** - Ensure the output file has the correct `.dds` extension. - Verify that the DDS compression format is supported by ImageMagick. + - If you are working with transparency, make sure you're using **DXT5** to preserve the alpha channel. 3. **Krita crashes or the plugin doesn't appear** - - Make sure the plugin is unzipped in the correct `pykrita` folder. Restart Krita after installation. + - Ensure the plugin is unzipped in the correct `pykrita` folder. Restart Krita after installation. ## Development