楼主: 独孤求败

[切脸辅助] 【独孤求败】最强DF人脸座标编辑V18收官版

[复制链接]

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-13 11:54:18 | 显示全部楼层
本帖最后由 独孤求败 于 2025-12-13 12:04 编辑
青青子衿 发表于 2025-12-13 10:12
我看没人搞,那我就再提一个,一般处理素材的时候,通常是多个文件夹,处理完第一个素材后就还要在退出去处 ...

我的理解是这样:

你有多个目录的素材要编辑
例如
.\a
.\b
.\c 等多个目录。。。。
你想程序运行时按默认,例如 .\a
那下次每次运行就会默认选 .\a
如果不是那么你还能手动自己去选择合适的目录
其实这个都是小问题,但会增加一个设定档在同级目录里
因为这是独立运行的绿色免安装档,为了干净所以我就没额外增加一个设定档在旁边当跟班
若把程序放在桌面上,那么运行时桌面会多一个设定档案,才能记录起来路径,同理其它目录也是相同
程序是 exe 档无法自己写入自己,这样讲你就能明白了
假如你想的是这个意思,其实在 V2 版本早就实现了,只是后来我又把他给拆了
理由简单:独立运行的绿色免安装档
我V2设计逻辑是当你离开时自动记录起那个目录
而不会采每次都默认是 .\a
例如你在 .\b 编辑,那么下次就直接默认为 .\b
当然你也可以手动改变
我看了下载次数 786 次,好像也挺多人使用呢

回复

使用道具 举报

2713

积分

105

帖子

938

符石

化神丹师

Rank: 5

积分
2713

热心会员突出贡献

发表于 2025-12-13 12:30:48 | 显示全部楼层
独孤求败 发表于 2025-12-13 11:54
我的理解是这样:

你有多个目录的素材要编辑

我的意思是,首次启动时检测有没有aligned目录,如果有就加载,没有就保持默认界面,即不带任何图片的界面,然后添加一个按钮,这个按钮的功能是选择目录,就是把自动弹出打开目录的功能,手动选择打开,这样可以再修改完一个素材集合后不用关闭就可以继续选择打开下一个素材集合,这样不用写入配置文件。我这样说能明白不,
回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-13 20:48:10 | 显示全部楼层
我大概知道你的思路
1.首先这是绿色版,可以放在电脑任意位置,所以他无法辨别你的 aligned 在那个磁盘,除非一开始就大规模搜索所有磁盘的目录,但这不确实。
2.根据V2版本的构想,你需要把程序放在 DF 工作目录,那么这个就好办,判断本层级以下是否有 .\workspace\DATA_SRC\aligned 或 .\workspace\data_dst\aligned 这个目录,这时候就只能默认一个,若无就开启一个选择目录的路径窗口.
3.如果是这样的想法,想要懒到这种程度,不如我在主控台直接弄个工作按扭,切换目录的功能,也不用关闭重启程序,默认的目录为工作目录的上一个层级显示,这样随意切换目录运行。
回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-14 01:28:20 | 显示全部楼层
本帖最后由 独孤求败 于 2025-12-14 04:52 编辑
青青子衿 发表于 2025-12-13 12:30
我的意思是,首次启动时检测有没有aligned目录,如果有就加载,没有就保持默认界面,即不带任何图片的界 ...

已经增加新功能和更智能效果能力
编辑DF人脸座标V13
请更新。。。。。
回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-14 01:45:10 | 显示全部楼层
青青子衿 发表于 2025-12-13 12:30
我的意思是,首次启动时检测有没有aligned目录,如果有就加载,没有就保持默认界面,即不带任何图片的界 ...

累的我半死。。。。




# ----------------------------------------------------------
# 配置文件管理 - 用于记忆上次使用的目录 2025/12/14日新增代码
# ----------------------------------------------------------
class ConfigManager:
    """配置文件管理器,用于记忆上次使用的目录(Windows专用)不适用跨平台喔~~"""
   
    @staticmethod
    def get_config_path():
        """获取配置文件路径(程序同目录的隐藏文件)"""
        if getattr(sys, 'frozen', False):
            exe_dir = os.path.dirname(sys.executable)
        else:
            exe_dir = os.path.dirname(os.path.abspath(__file__))
        
        config_path = os.path.join(exe_dir, 'config.json')
        return config_path
   
    @staticmethod
    def set_file_hidden(path, hidden=True):
        """设置或取消文件隐藏属性(仅Windows)"""
        try:
            if hidden:
                # 设置为隐藏 (0x02)
                attrs = 0x02
            else:
                # 设置为正常 (0x80) - 即取消隐藏
                attrs = 0x80
               
            ctypes.windll.kernel32.SetFileAttributesW(path, attrs)
            return True
        except Exception as e:
            # print(f"设置属性失败: {e}")
            return False
   
    @staticmethod
    def save_last_directory(directory):
        """保存上次使用的目录到配置文件"""
        config_path = ConfigManager.get_config_path()
        
        # 写入前,先强制取消隐藏属性,否则 Windows 会拒绝写入
        if os.path.exists(config_path):
            ConfigManager.set_file_hidden(config_path, hidden=False)
        
        config_data = {
            'last_directory': directory,
            'last_directory_encoded': base64.b64encode(directory.encode('utf-8')).decode('utf-8')
        }
        
        try:
            with open(config_path, 'w', encoding='utf-8') as f:
                json.dump(config_data, f, ensure_ascii=False, indent=2)
            
            # 写入完成后,再次设为隐藏
            ConfigManager.set_file_hidden(config_path, hidden=True)
            
            return True
        except Exception as e:
            print(f"保存配置失败: {e}")
            return False
   
    @staticmethod
    def load_last_directory():
        """从配置文件加载上次使用的目录"""
        config_path = ConfigManager.get_config_path()
        
        if not os.path.exists(config_path):
            return None
        
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config_data = json.load(f)
            
            if 'last_directory_encoded' in config_data:
                directory = base64.b64decode(config_data['last_directory_encoded']).decode('utf-8')
            elif 'last_directory' in config_data:
                directory = config_data['last_directory']
            else:
                return None
            
            if os.path.exists(directory):
                return directory
            else:
                return None
               
        except Exception as e:
            print(f"加载配置失败: {e}")
            return None


def select_directory(parent, initial_dir=None):
    """选择目录函数,支持指定初始目录"""
    # 如果提供了初始目录且存在,则尝试获取其父目录作为对话框的初始目录
    if initial_dir and os.path.exists(initial_dir):
        # 获取父目录
        parent_dir = os.path.dirname(initial_dir)
        # 如果父目录存在,使用父目录作为初始目录;否则使用原始目录
        if parent_dir and os.path.exists(parent_dir):
            initialdir = parent_dir
        else:
            initialdir = initial_dir
    else:
        initialdir = None
   
    # 打开目录选择对话框
    directory = filedialog.askdirectory(
        title="选择编辑目录",
        parent=parent,
        initialdir=initialdir
    )
   
    if not directory:
        return None, None
   
    try:
        # 检查目录中是否有图片文件
        image_files = [f for f in os.listdir(directory) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
        if not image_files:
            messagebox.showerror("错误", "找不到图片!")
            return None, None
        
        # 创建错误目录
        error_dir = os.path.join(os.path.dirname(directory), "aligned_error")
        os.makedirs(error_dir, exist_ok=True)
        
        # 保存到配置文件
        ConfigManager.save_last_directory(directory)
        
        return directory, error_dir
        
    except Exception as e:
        messagebox.showerror("错误", f"无法存取目录或读取档案:{e}")
        return None, None
        # 必须在方法开始时声明全局变量
        global IMAGE_DIR, ERROR_DIR
        
        #尝试加载上次使用的目录
        last_directory = ConfigManager.load_last_directory()
        
        try:
            if last_directory:
                # 如果找到上次使用的目录,直接使用
                IMAGE_DIR = last_directory
                ERROR_DIR = os.path.join(os.path.dirname(last_directory), "aligned_error")
                os.makedirs(ERROR_DIR, exist_ok=True)
               
                # 验证目录中是否有图片
                self.image_files = self.get_image_files()
                if not self.image_files:
                    # 如果目录中没有图片,则让用户重新选择
                    messagebox.showwarning("警告", "上次使用的目录中没有图片,请重新选择目录。")
                    result = select_directory(root, last_directory)
                    if result is None or result[0] is None:
                        sys.exit(1)
                    IMAGE_DIR, ERROR_DIR = result
            else:
                # 第一次使用或没有保存的目录,让用户选择
                result = select_directory(root)
                if result is None or result[0] is None:
                    sys.exit(1)
                IMAGE_DIR, ERROR_DIR = result
                    
        except Exception as e:
            print(f"初始化目录失败: {e}")
            sys.exit(1)
        
        self.image_files = self.get_image_files()
        
        if not self.image_files:
            messagebox.showerror("错误", "选择的目录中没有图片!")
            sys.exit(1)
    def change_directory(self):
        """切换目录功能"""
        # 在函数最开始声明 global,否则后面无法读取旧值
        global IMAGE_DIR, ERROR_DIR
        
        # 检查是否有未保存的修改,有则自动保存
        if self.has_unsaved_changes:
            self.save_landmarks()
        
        # 获取当前目录作为初始目录
        # 现在读取 IMAGE_DIR 是安全的,因为上面已经声明了 global
        current_dir = IMAGE_DIR if IMAGE_DIR else None
        
        # 打开目录选择对话框
        result = select_directory(self.root, current_dir)
        
        if result is None or result[0] is None:
            # 用户取消了选择
            return
        
        new_directory, new_error_dir = result
        
        # 验证新目录是否有图片
        temp_files = sorted([f for f in os.listdir(new_directory) if f.lower().endswith(('.jpg', '.jpeg', '.png'))])
        if not temp_files:
            messagebox.showerror("错误", "新目录中没有图片!")
            return
        
        # 更新全局变量
        IMAGE_DIR = new_directory
        ERROR_DIR = new_error_dir
        
        # 同时保存到配置文件,确保下次启动能记住
        ConfigManager.save_last_directory(IMAGE_DIR)
        
        # 重新加载图片列表
        self.image_files = self.get_image_files()
        self.current_index = 0
        
        # 更新UI显示
        total_files = len(self.image_files)
        max_index = total_files - 1 if total_files > 0 else 0
        self.max_index_label.config(text=f"/ {max_index}")
        
        # 加载第一张图片
        self.load_current_image()
        
        # 显示提示信息
        self.msg_overlay = f"已切换到新目录: {os.path.basename(IMAGE_DIR)}"
        self.render_image()
        


回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-14 04:59:30 | 显示全部楼层
本帖最后由 独孤求败 于 2025-12-14 05:06 编辑
青青子衿 发表于 2025-12-13 12:30
我的意思是,首次启动时检测有没有aligned目录,如果有就加载,没有就保持默认界面,即不带任何图片的界 ...

我的意思是,首次启动时检测有没有aligned目录,如果有就加载,没有就保持默认界面,即不带任何图片的界面,然后添加一个按钮,这个按钮的功能是选择目录,就是把自动弹出打开目录的功能,手动选择打开,这样可以再修改完一个素材集合后不用关闭就可以继续选择打开下一个素材集合,这样不用写入配置文件。我这样说能明白不,



修改的思路:
首次你选择好要编辑的目录(之后就不用了),进入后就被纪录起来你所在的目录所看到的图档,当你随时想退出时,那么退出后,再运行软件就会回到你刚才那张图档的画面,你可以随意切换目录选择你要编辑的目录,下方的功能按钮,有可以切换目录的选项,好了其它的你自行摸索,都非常简单人性化,全程支援中文目录中文档名


回复

使用道具 举报

572

积分

35

帖子

533

符石

元婴丹师

Rank: 4Rank: 4Rank: 4Rank: 4

积分
572
发表于 2025-12-17 21:26:21 | 显示全部楼层
默默的更新
回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-18 23:28:18 | 显示全部楼层

还有一个功能正在新增。。。。
让使用者更便利,但我需要时间压力测试各种代码,以免更新频率太快
都被骂的不要不要的满脸豆花。。。
回复

使用道具 举报

572

积分

35

帖子

533

符石

元婴丹师

Rank: 4Rank: 4Rank: 4Rank: 4

积分
572
发表于 2025-12-20 08:47:26 | 显示全部楼层
独孤求败 发表于 2025-12-18 23:28
还有一个功能正在新增。。。。
让使用者更便利,但我需要时间压力测试各种代码,以免更新频率太快
都被骂 ...

别理那些臭傻吊  为爱发电的开发者都是被他们喷的停发的
回复

使用道具 举报

1万

积分

236

帖子

257

符石

玉皇大帝

Rank: 16Rank: 16Rank: 16Rank: 16

积分
19802

隐藏大神突出贡献论坛元老咸鱼勋章

 楼主| 发表于 2025-12-20 09:15:15 | 显示全部楼层
pasanonic 发表于 2025-12-20 08:47
别理那些臭傻吊  为爱发电的开发者都是被他们喷的停发的

新版 15x 可下载了
回复

使用道具 举报

小黑屋|ZhaTV ( 滇ICP备15003127号-4 ) |网站地图

GMT+8, 2026-1-1 13:08

Powered by Zhatv.cn

© 2022-2023

快速回复 返回顶部 返回列表