Example #1
0
 def from_file(cls, file, **kwargs):
     """ 输入本地一个html文件的路径,加上导航栏打开 """
     file = File(file)
     content = file.read()
     # 输入文件的情况,生成的_content等html要在同目录
     return cls.from_content(content,
                             os.path.splitext(str(file))[0], **kwargs)
Example #2
0
        def func(g):
            # 1 获得图片id和文件
            image_id, df = g
            imfile = File(df.iloc[0]['file_name'], imdir)
            if not imfile:
                return  # 如果没有图片不处理
            image = self.images.loc[image_id]
            image = image.drop(['file_name', 'height', 'width'])

            # 2 生成这张图片对应的json标注
            if dst_dir:
                imfile = imfile.copy(dst_dir, if_exists='skip')
            lm = Coco2Labelme(imfile)

            height, width = lm.data['imageHeight'], lm.data['imageWidth']
            # 注意df取出来的image_id默认是int64类型,要转成int,否则json会保存不了int64类型
            lm.add_shape('', [0, 0, 10, 0],
                         shape_type='line',
                         shape_color=[0, 0, 0],
                         size=f'{height}x{width}',
                         **(image.to_dict()))
            getattr(lm, match_func_name)(df,
                                         segmentation=segmentation,
                                         hide_match_dt=hide_match_dt,
                                         **kwargs)
            lm.write()  # 保存json文件到img对应目录下
Example #3
0
def zoomsvg(file, scale=1):
    """ 缩放svg文件

    :param file:
        如果输入一个目录,会处理目录下所有的svg图片
        否则只处理指定的文件
        如果是文本文件,则处理完文本后返回
    :param scale: 缩放的比例,默认100%不调整
    :return:
    """
    if scale == 1: return

    def func(m):
        def g(m):
            return m.group(1) + str(float(m.group(2)) * scale)

        return re.sub(r'((?:height|width)=")(\d+(?:\.\d+)?)', g, m.group())

    if os.path.isfile(file):
        s = re.sub(r'<svg .+?>', func, File(file).read(), flags=re.DOTALL)
        File(file).write(s, if_exists='replace')
    elif os.path.isdir(file):
        for f in os.listdir(file):
            if not f.endswith('.svg'): continue
            f = os.path.join(file, f)
            s = re.sub(r'<svg\s+.+?>', func, File(f).read(), flags=re.DOTALL)
            File(file).write(s, if_exists='replace')
    elif isinstance(file, str) and '<svg ' in file:  # 输入svg的代码文本
        return re.sub(r'<svg .+?>', func, file, flags=re.DOTALL)
Example #4
0
    def judge(f):
        if root: f = os.path.join(root, f)
        if type_ == 'file' and not os.path.isfile(f):
            return False
        elif type_ == 'dir' and not os.path.isdir(f):
            return False

        # 尽量避免调用 os.stat,判断是否有自定义大小、时间规则,没有可以跳过这部分
        check_arg = first_nonnone([min_size, max_size, min_ctime, max_ctime, min_mtime, max_mtime])
        if check_arg is not None:
            msg = os.stat(f)
            if first_nonnone([min_size, max_size]) is not None:
                size = File(f).size
                if min_size is not None and size < min_size: return False
                if max_size is not None and size > max_size: return False

            if min_ctime or max_ctime:
                file_ctime = datetime.fromtimestamp(msg.st_ctime)
                if min_ctime and file_ctime < min_ctime: return False
                if max_ctime and file_ctime > max_ctime: return False

            if min_mtime or max_mtime:
                file_mtime = datetime.fromtimestamp(msg.st_mtime)
                if min_mtime and file_mtime < min_mtime: return False
                if max_mtime and file_mtime > max_mtime: return False

        if ignore_special:
            parts = File(f).parts
            if '.git' in parts or '$RECYCLE.BIN' in parts:
                return False

        if ignore_backup and File(f).backup_time:
            return False

        return True
Example #5
0
def debug_images(dir_, func, *, save=None, show=False):
    """
    :param dir_: 选中的文件清单
    :param func: 对每张图片执行的功能,函数应该只有一个图片路径参数  new_img = func(img)
        当韩式有个参数时,可以用lambda函数技巧: lambda im: func(im, arg1=..., arg2=...)
    :param save: 如果输入一个目录,会将debug结果图存储到对应的目录里
    :param show: 如果该参数为True,则每处理一张会imshow显示处理效果
        此时弹出的窗口里,每按任意键则显示下一张,按ESC退出
    :return:

    TODO 显示原图、处理后图的对比效果
    TODO 支持同时显示多张图处理效果
    """
    if save:
        save = File(save)

    for f in dir_.subfiles():
        im1 = xlcv.read(f)
        im2 = func(im1)

        if save:
            xlcv.write(im2, File(save / f.name, dir_))

        if show:
            xlcv.imshow2(im2)
            key = cv2.waitKey()
            if key == '0x1B':  # ESC 键
                break
Example #6
0
def distribute_package(root, version=None, repository=None, *, upload=True):
    """ 发布包的工具函数

    :param root: 项目的根目录,例如 'D:/slns/pyxllib'
        根目录下有对应的 setup.py 等文件
    :param repository: 比如我配置了 [xlpr],就可以传入 'xlpr'
    """
    from pyxllib.file.specialist import File, Dir

    # 1 切换工作目录
    os.chdir(str(root))

    # 2 改版本号
    if version:
        f = File('setup.py', root)
        s = re.sub(r"(version\s*=\s*)(['\"])(.+?)(\2)", fr'\1\g<2>{version}\4', f.read())
        f.write(s)

    # 3 打包
    subprocess.run('python setup.py sdist')

    # 4 上传
    if upload:
        # 上传
        cmd = 'twine upload dist/*'
        if repository:
            cmd += f' -r {repository}'
        subprocess.run(cmd)
        # 删除打包生成的中间文件
        Dir('dist').delete()
        Dir('build').delete()
Example #7
0
    def __init__(self,
                 root,
                 relpath2data=None,
                 *,
                 reads=True,
                 prt=False,
                 fltr='json',
                 slt='json',
                 extdata=None):
        """
        :param root: 文件根目录
        :param relpath2data: {jsonfile: lmdict, ...},其中 lmdict 为一个labelme文件格式的标准内容
            如果未传入data具体值,则根据目录里的情况自动初始化获得data的值

            210602周三16:26,为了工程等一些考虑,删除了 is_labelme_json_data 的检查
                尽量通过 fltr、slt 的机制选出正确的 json 文件
        """
        super().__init__(root,
                         relpath2data,
                         reads=reads,
                         prt=prt,
                         fltr=fltr,
                         slt=slt,
                         extdata=extdata)

        # 已有的数据已经读取了,这里要补充空labelme标注
        if self.pathgs:
            for stem, suffixs in tqdm(self.pathgs.data.items(),
                                      f'{self.__class__.__name__}优化数据',
                                      disable=not prt):
                f = File(stem, suffix=slt)
                if reads and not f:
                    self.rp2data[f.relpath(self.root)] = LabelmeDict.gen_data(
                        File(stem, suffix=suffixs[0]))
Example #8
0
def magick(infile,
           *,
           outfile=None,
           if_exists='error',
           transparent=None,
           trim=False,
           density=None,
           other_args=None):
    """ 调用iamge magick的magick.exe工具

    :param infile: 处理对象文件
    :param outfile: 输出文件,可以不写,默认原地操作(只设置透明度、裁剪时可能会原地操作)
    :param if_exists: 如果目标文件已存在要怎么处理
    :param transparent:
        True: 将白底设置为透明底
        可以传入颜色参数,控制要设置的为透明底的背景色,默认为'white'
        注意也可以设置rgb:'rgb(164,192,167)'
    :param trim: 裁剪掉四周空白
    :param density: 设置图片的dpi值
    :param other_args: 其他参数,输入格式如:['-quality', 100]
    :return:
        False:infile不存在或者不支持的文件扩展名
        返回生成的文件名(outfile)
    """
    # 1 条件判断,有些情况下不用处理
    if not outfile:
        outfile = infile

    # 2
    # 200914周一20:40,这有个相对路径的bug,修复了下,否则 test/a.png 会变成 test/test/a.png
    if File(outfile).exist_preprcs(if_exists):
        # 2.1 判断是否是支持的输入文件类型
        ext = os.path.splitext(infile)[1].lower()
        if not File(infile) or not ext in ('.png', '.eps', '.pdf', '.jpg',
                                           '.jpeg', '.wmf', '.emf'):
            return False

        # 2.2 生成需要执行的参数
        cmd = ['magick.exe']
        # 透明、裁剪、density都是可以重复操作的
        if density: cmd.extend(['-density', str(density)])
        cmd.append(infile)
        if transparent:
            if not isinstance(transparent, str):
                transparent_ = 'white'
            else:
                transparent_ = transparent
            cmd.extend(['-transparent', transparent_])
        if trim: cmd.append('-trim')
        if other_args: cmd.extend(other_args)
        cmd.append(outfile)

        # 2.3 生成目标png图片
        cmd = [x.replace('\\', '/') for x in cmd]
        print(' '.join(cmd))
        subprocess.run(cmd, stderr=subprocess.PIPE,
                       shell=True)  # 看不懂magick出错写的是啥,关了

    return outfile
Example #9
0
    def to_images(self,
                  dst_dir=None,
                  file_fmt='{filestem}_{number}.png',
                  num_width=None,
                  *,
                  scale=1,
                  start=1,
                  fmt_onepage=False):
        """ 将pdf转为若干页图片

        :param dst_dir: 目标目录
            默认情况下,只有一页pdf则存储到对应的pdf目录,多页则存储到同名子目录下
            如果不想这样被智能控制,只要指定明确的dst即可
        :param file_fmt: 后缀格式,包括修改导出的图片类型,注意要用 {} 占位符表示页码编号
        :param num_width: 生成的每一页文件编号,使用的数字前导0域宽
            默认根据pdf总页数来设置对应所用域宽
            0表示不设域宽
        :param scale: 对每页图片进行缩放,一般推荐都要设成2,导出的图片才清晰
        :param start: 起始页码,一般建议从1开始比较符合常识直觉
        :param fmt_onepage: 当pdf就只有一页的时候,是否还对导出的图片编号
            默认只有一页的时候,进行优化,不增设后缀格式
        :return: 返回转换完的图片名称清单

        注:如果要导出单张图,可以用 FitzPdfPage.get_cv_image
        """
        # 1 基本参数计算
        srcfile, doc = self.src_file, self.doc
        filestem, n_page = srcfile.stem, doc.page_count

        # 自动推导目标目录
        if dst_dir is None:
            dst_dir = Dir(srcfile.stem, srcfile.parent) if n_page > 1 else Dir(
                srcfile.parent)
        Dir(dst_dir).ensure_dir()

        # 域宽
        num_width = num_width or get_number_width(n_page)  # 根据总页数计算需要的对齐域宽

        # 2 导出图片
        if fmt_onepage or n_page != 1:  # 多页的处理规则
            res = []
            for i in range(n_page):
                im = self.load_page(i).get_cv_image(scale)
                number = ('{:0' + str(num_width) + 'd}').format(
                    i + start)  # 前面的括号不要删,这样才是完整的一个字符串来使用format
                f = xlcv.write(
                    im,
                    File(file_fmt.format(filestem=filestem, number=number),
                         dst_dir))
                res.append(f)
            return res
        else:
            im = self.load_page(0).get_cv_image(scale)
            return [
                xlcv.write(
                    im,
                    File(srcfile.stem + os.path.splitext(file_fmt)[1],
                         dst_dir))
            ]
Example #10
0
def extract_files(src, dst, pattern, if_exists='replace'):
    """ 提取满足pattern模式的文件
    """
    d1, d2 = Dir(src), Dir(dst)
    files = d1.select(pattern).subs
    for f in files:
        p1, p2 = File(d1 / f), File(d2 / f)
        p1.copy(p2, if_exists=if_exists)
Example #11
0
def browser_json(f):
    """ 可视化一个json文件结构 """
    data = File(f).read()
    # 使用NestedDict.to_html_table转成html的嵌套表格代码,存储到临时文件夹
    htmlfile = File(r'chrome_json.html',
                    root=Dir.TEMP).write(NestedDict.to_html_table(data))
    # 展示html文件内容
    browser(htmlfile)
Example #12
0
 def browser(_self, opt='html'):
     if opt == 'html':
         data = _self.get_text('html')  # html、xhtml 可以转网页,虽然排版相对来说还是会乱一点
         data = ''.join(data)
         etag = get_etag(data)
         f = File(etag, Dir.TEMP, suffix='.html')
         f.write(data)
         browser(f)
     else:
         raise ValueError
Example #13
0
    def to_image(_self, outfile, *, scale=1, if_exists=None):
        """ 转成为文件 """
        f = File(outfile)
        suffix = f.suffix.lower()

        if suffix == '.svg':
            content = _self.get_svg_image()
            f.write(content, if_exists=if_exists)
        else:
            im = _self.get_cv_image(scale)
            xlcv.write(im, if_exists=if_exists)
Example #14
0
def viewfiles(procname, *files, **kwargs):
    """ 调用procname相关的文件程序打开files

    :param procname: 程序名
    :param files: 一个文件名参数清单,每一个都是文件路径,或者是字符串等可以用writefile转成文件的路径
    :param kwargs:
        save: 如果True,则会按时间保存文件名;否则采用特定名称,每次运行就会把上次的覆盖掉
        wait: 是否等待当前进程结束后,再运行后续py代码
        filename: 控制写入的文件名
        TODO:根据不同软件,这里还可以扩展很多功能
    :param kwargs:
        wait:
            True:在同一个进程中执行子程序,即会等待bc退出后,再进入下一步
            False:在新的进程中执行子程序

    细节:注意bc跟其他程序有比较大不同,建议使用专用的bcompare函数
    目前已知可以扩展多文件的有:chrome、notepad++、texstudio

    >> ls = list(range(100))
    >> viewfiles('notepad++', ls, save=True)
    """
    # 1 生成文件名
    ls = []  # 将最终所有绝对路径文件名存储到ls
    save = kwargs.get('save')

    basename = ext = None
    if 'filename' in kwargs and kwargs['filename']:
        basename, ext = os.path.splitext(kwargs['filename'])

    for i, t in enumerate(files):
        if File(t) or is_url(t):
            ls.append(str(t))
        else:
            bn = basename or ...
            ls.append(
                File(bn, Dir.TEMP, suffix=ext).write(t,
                                                     if_exists=kwargs.get(
                                                         'if_exists',
                                                         'error')).to_str())

    # 2 调用程序(并计算外部操作时间)
    tictoc = TicToc()
    try:
        if kwargs.get('wait'):
            subprocess.run([procname, *ls])
        else:
            subprocess.Popen([procname, *ls])
    except FileNotFoundError:
        if procname in ('chrome', 'chrome.exe'):
            procname = 'explorer'  # 如果是谷歌浏览器找不到,尝试用系统默认浏览器
            viewfiles(procname, *files, **kwargs)
        else:
            raise FileNotFoundError(f'未找到程序:{procname}。请检查是否有安装及设置了环境变量。')
    return tictoc.tocvalue()
Example #15
0
 def __init__(self, imgpath):
     """
     :param imgpath: 可选参数图片路径,强烈建议要输入,否则建立的label json会少掉图片宽高信息
     """
     self.imgpath = File(imgpath)
     # 读取图片数据,在一些转换规则比较复杂,有可能要用到原图数据
     if self.imgpath:
         # 一般都只需要获得尺寸,用pil读取即可,速度更快,不需要读取图片rgb数据
         self.img = xlpil.read(self.imgpath)
     else:
         self.img = None
     self.data = self.get_data_base()  # 存储json的字典数据
Example #16
0
 def write(self, loc):
     f = File(loc, self.root, suffix='.json')
     imfile = self.imfiles[loc]
     lmdict = LabelmeDict.gen_data(imfile)
     for label, ann in self.data[loc].items():
         a = ann.copy()
         DictTool.isub(a, ['img'])
         shape = LabelmeDict.gen_shape(json.dumps(a, ensure_ascii=False),
                                       a['points'],
                                       a['shape_type'],
                                       group_id=a['group_id'],
                                       flags=a['flags'])
         lmdict['shapes'].append(shape)
     f.write(lmdict, indent=2)
Example #17
0
    def __init__(self,
                 alias=None,
                 database=None,
                 *,
                 user='******',
                 passwd='123456',
                 host=None,
                 port='3306',
                 connect_timeout=None,
                 account_file_path=None):
        """ 初始化需要连接数据库

        :param alias: 数据库的简化别名,为了方便快速调用及隐藏明文密码
            使用该参数将会覆盖掉已有的user、passwd、host、port参数值
            例如我自己设置的别名有:
                ckz,我自己阿里云上的个人数据库
                ckzlocal,本PC开的数据库
        :param account_file_path: 使用alias时才有效
            该参数指定存储账号信息的pkl文件所在位置,注意pkl的格式必须用类似下述的代码方式生成
            默认从与该脚本同目录下的 sqllibaccount.pkl 文件获取

        :param database: 数据库名称
            例如在快乐做教研时一些相关数据库名:
                tr,教研
                tr_develop,教研开发数据
                tr_test,教研测试数据

        :param connect_timeout: 连接超时时等待秒数
            如果设置,建议2秒以上

        :return:
        """

        # 1 读取地址、账号信息
        if alias:
            if account_file_path is None:
                account_file_path = File(SQL_LIB_ACCOUNT_FILE)
            # dprint(alias,account_file_path)
            record = File(account_file_path).read().loc[alias]  # 从文件读取账号信息
            user, passwd, host, port = record.user, record.passwd, record.host, record.port

        # 2 '数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'
        address = f'mysql+mysqldb://{user}:{passwd}@{host}:{port}/{database}?charset=utf8mb4'
        # 3 存储成员
        self.alias, self.database = alias, database
        connect_args = {
            "connect_timeout": connect_timeout
        } if connect_timeout else {}
        self.engine = sqlalchemy.create_engine(address,
                                               connect_args=connect_args)
Example #18
0
    def gen_data(cls, imfile=None, **kwargs):
        """ 主要框架结构
        :param imfile: 可以传入一张图片路径
        """
        # 1 传入图片路径的初始化
        if imfile:
            file = File(imfile)
            name = file.name
            img = xlpil.read(file)
            height, width = img.height, img.width
        else:
            name, height, width = '', 0, 0

        # 2 字段值
        data = {
            'version': '4.5.7',
            'flags': {},
            'shapes': [],
            'imagePath': name,
            'imageData': None,
            'imageWidth': width,
            'imageHeight': height,
        }
        if kwargs:
            data.update(kwargs)
        return data
Example #19
0
def ensure_content(ob=None, encoding=None):
    """
    :param ob:
        未输入:从控制台获取文本
        存在的文件名:读取文件的内容返回
            tex、py、
            docx、doc
            pdf
        有read可调用成员方法:返回f.read()
        其他字符串:返回原值
    :param encoding: 强制指定编码
    """
    # TODO: 如果输入的是一个文件指针,也能调用f.read()返回所有内容
    # TODO: 增加鲁棒性判断,如果输入的不是字符串类型也要有出错判断
    if ob is None:
        return sys.stdin.read()  # 注意输入是按 Ctrl + D 结束
    elif File(ob):  # 如果存在这样的文件,那就读取文件内容(bug点:如果输入是目录名会PermissionError)
        if ob.endswith('.docx'):  # 这里还要再扩展pdf、doc文件的读取
            # 安装详见: https://blog.csdn.net/code4101/article/details/79328636
            check_install_package('textract')
            text = textract.process(ob)
            return text.decode('utf8', errors='ignore')
        elif ob.endswith('.doc'):
            raise NotImplementedError
        elif ob.endswith('.pdf'):
            raise NotImplementedError
        else:  # 按照普通的文本文件读取内容
            return readtext(ob, encoding)
    else:  # 判断不了的情况,也认为是字符串
        return ob
Example #20
0
def file_or_dir_size(path):
    if os.path.isfile(path):
        return File(path).size
    elif os.path.isdir(path):
        return Dir(path).size
    else:
        return 0
Example #21
0
    def to_bcompare_files(cls, *args, files=None):
        """ 这个需要一次性获得所有的数据,才适合分析整体上要怎么获取对应的多个文件

        :param files: 每个arg对应的文件名,默认按 'left'、'right', 'base' 来生成
            也可以输入一个list[str],表示多个args依次对应的文件名
            filename的长度可以跟args不一致,多的不用,少的自动生成
        """
        # 1 如果oldfile和newfile都是dict、set、list、tuple,则使用特殊方法文本化
        #   如果两个都是list,不应该提取key后比较,所以限制第1个类型必须是dict或set,然后第二个类型可以适当放宽条件
        # if not oldfile: oldfile = str(oldfile)
        if len(args) > 1 and isinstance(args[0], (dict, set)) and isinstance(
                args[1], (dict, set, list, tuple)):
            args = copy.copy(list(args))
            t = [
                prettifystr(li) for li in intersection_split(args[0], args[1])
            ]
            args[0] = f'【共有部分】,{t[0]}\n\n【独有部分】,{t[1]}'
            args[1] = f'【共有部分】,{t[2]}\n\n【独有部分】,{t[3]}'

        # 2 参数对齐
        if not isinstance(files, (list, tuple)):
            files = [files]
        if len(files) < len(args):
            files += [None] * (len(args) - len(files))
        ref_names = ['left', 'right', 'base']

        # 3 将每个参数转成一个文件
        new_args = []
        default_suffix = None
        for i, arg in enumerate(args):
            f = File.safe_init(arg)
            if f:  # 是文件对象,且存在
                new_args.append(f)
                if not default_suffix:
                    default_suffix = f.suffix
            # elif isinstance(f, File):  # 文本内容也可能生成合法的伪路径,既然找不到还是统一按字符串对比差异好
            #     # 是文件对象,但不存在 -> 报错
            #     raise FileNotFoundError(f'{f}')
            else:  # 不是文件对象,要转存到文件
                if not files[i]:  # 没有设置文件名则生成一个
                    files[i] = File(ref_names[i],
                                    Dir.TEMP,
                                    suffix=default_suffix)
                files[i].write(arg)
                new_args.append(files[i])

        return new_args
Example #22
0
 def browser(self, opt='pdf'):
     if opt == 'pdf':
         f = self.src_file
         browser(self.src_file)
     elif opt == 'html':
         ls = []
         for i in range(self.page_count):
             page = self.load_page(i)
             ls.append(page.get_text('html'))
         data = '\n'.join(ls)
         etag = get_etag(data)
         f = File(etag, Dir.TEMP, suffix='.html')
         f.write(data)
         browser(f)
     else:
         raise ValueError(f'{opt}')
     return f
Example #23
0
 def write(self, dst=None, if_exists='replace'):
     """
     :param dst: 往dst目标路径存入json文件,默认名称在self.imgpath同目录的同名json文件
     :return: 写入后的文件路径
     """
     if dst is None and self.imgpath:
         dst = self.imgpath.with_suffix('.json')
     # 官方json支持indent=None的写法,但是ujson必须要显式写indent=0
     return File(dst).write(self.data, if_exists=if_exists, indent=0)
Example #24
0
def writefile(ob, path='', *, encoding='utf8', if_exists='backup', suffix=None, root=None, etag=None) -> str:
    """往文件path写入ob内容
    :param ob: 写入的内容
        如果要写txt文本文件且ob不是文本对象,只会进行简单的字符串化
    :param path: 写入的文件名,使用空字符串时,会使用etag值
    :param encoding: 强制写入的编码
    :param if_exists: 如果文件已存在,要进行的操作
    :param suffix: 文件扩展名
        以'.'为开头,设置“候补扩展名”,即只在fn没有指明扩展名时,会采用
    :param root: 相对位置
    :return: 返回写入的文件名,这个主要是在写临时文件时有用
    """
    if etag is None: etag = (not path)
    if path == '': path = ...
    f = File(path, root, suffix=suffix).write(ob, encoding=encoding, if_exists=if_exists)
    if etag:
        f = f.rename(get_etag(str(f)))
    return str(f)
Example #25
0
 def gen_gt_dict(cls, images, annotations, categories, outfile=None):
     data = {
         'images': images,
         'annotations': annotations,
         'categories': categories
     }
     if outfile is not None:
         File(outfile).write(data)
     return data
Example #26
0
def filetext_replace(files,
                     func,
                     *,
                     count=-1,
                     start=1,
                     bc=False,
                     write=False,
                     if_exists=None):
    r"""遍历目录下的文本文件进行批量处理的功能函数

    :param files: 文件匹配规则,详见filesmatch用法
    :param func: 通用文本处理函数
    :param count: 匹配到count个文件后结束,防止满足条件的文件太多,程序会跑死
    :param start: 从编号几的文件开始查找,一般在遇到意外调试的时候使用
    :param bc: 使用beyond compare软件
        注意bc的优先级比write高,如果bc和write同时为True,则会开bc,但并不会执行write
    :param write: 是否原地修改文件内容进行保存
    :param if_exists: 是否进行备份,详见writefile里的参数文件
    :return: 满足条件的文件清单
    """
    ls = []
    total = 0
    for f in filesmatch(files):
        # if 'A4-Exam' in f:
        #     continue
        total += 1
        if total < start:
            continue
        s0 = File(f).read()
        s1 = func(s0)
        if s0 != s1:
            match = len(ls) + 1
            dprint(f, total, match)
            if bc:
                bcompare(f, s1)
            elif write:  # 如果开了bc,程序是绝对不会自动写入的
                File(f).write(s1, if_exists=if_exists)
            ls.append(f)
            if len(ls) == count:
                break

    match_num = len(ls)
    dprint(total, match_num)
    return ls
Example #27
0
 def read(file, flags=None, **kwargs):
     if xlpil.is_pil_image(file):
         im = file
     elif xlcv.is_cv2_image(file):
         im = xlcv.to_pil_image(file)
     elif File.safe_init(file):
         im = PIL.Image.open(str(file), **kwargs)
     else:
         raise TypeError(f'类型错误或文件不存在:{type(file)} {file}')
     return xlpil.cvt_channel(im, flags)
Example #28
0
 def setToC(self):
     """设置书签目录
     可以调层级、改名称、修改指向页码
     """
     toc = self.doc.getToC()
     toc[1][1] = '改标题名称'
     self.doc.setToC(toc)
     file = File('a.pdf', Dir.TEMP).to_str()
     self.doc.save(file, garbage=4)
     browser(file)
Example #29
0
 def get_data(self, infile):
     lines = File(infile).read().splitlines()
     for line in lines:
         # 一般是要改这里,每行数据的解析规则
         vals = line.split(',', maxsplit=8)
         if len(vals) < 9: continue
         pts = [int(v) for v in vals[:8]]  # 点集
         label = vals[-1]  # 标注的文本
         # get_shape还有shape_type形状参数可以设置
         #  如果是2个点的矩形,或者3个点以上的多边形,会自动判断,不用指定shape_type
         self.add_shape(label, pts)
Example #30
0
    def main_normal(cls, imdir, labeldir=None, label_file_suffix='.txt'):
        """ 封装更高层的接口,输入目录,直接标注目录下所有图片

        :param imdir: 图片路径
        :param labeldir: 标注数据路径,默认跟imdir同目录
        :return:
        """
        ims = Dir(imdir).select_files(['*.jpg', '*.png'])
        if not labeldir: labeldir = imdir
        txts = [File(f.stem, labeldir, suffix=label_file_suffix) for f in ims]
        cls.main_pair(ims, txts)