示例#1
0
def prepare_tts(img, _, output_folder):  # pylint: disable=R0914
    """ Prepare a TTS sheet image.
    """
    gimp.progress_init('Prepare a TTS sheet image...')
    pdb.gimp_undo_push_group_start(img)

    try:
        file_name, _ = _get_filename_backside(img, 'jpg')
    except Exception:  # pylint: disable=W0703
        pdb.gimp_undo_push_group_end(img)
        return

    parts = file_name.split('_')
    num = int(parts[-3])
    rows = int(parts[-4])
    columns = int(parts[-5])
    new_width = columns * 750
    new_height = rows * 1050
    pdb.gimp_image_scale(img, new_width, new_height)

    json_path = re.sub(r'\.jpg$', '.json', pdb.gimp_image_get_filename(img))
    try:
        with open(json_path, 'r') as fobj:
            cards = json.load(fobj)
    except Exception:  # pylint: disable=W0703
        pdb.gimp_undo_push_group_end(img)
        return

    cards = [c['path'] for c in cards]
    if len(cards) != num:
        pdb.gimp_undo_push_group_end(img)
        return

    card_rows = [
        cards[i * columns:(i + 1) * columns]
        for i in range((len(cards) + columns - 1) // columns)
    ]
    if len(card_rows) != rows:
        pdb.gimp_undo_push_group_end(img)
        return

    for i, card_row in enumerate(card_rows):
        for j, card_path in enumerate(card_row):
            if not os.path.exists(card_path):
                pdb.gimp_undo_push_group_end(img)
                return

            card_layer = pdb.gimp_file_load_layer(img, card_path)
            pdb.gimp_image_insert_layer(img, card_layer, None, -1)
            rotation = _get_rotation(card_layer)
            if rotation:
                _rotate(card_layer, True)

            pdb.gimp_layer_set_offsets(card_layer, j * 750, i * 1050)
            pdb.gimp_image_merge_down(img, card_layer, 1)

    pdb.file_jpeg_save(img, img.layers[0],
                       os.path.join(output_folder, file_name), file_name, 1, 0,
                       1, 0, '', 2, 1, 0, 0)
    pdb.gimp_undo_push_group_end(img)
def png(image=None):
    if not image:
        image = gimp.image_list()[0]
    prefix = pdb.gimp_image_get_filename(image)[:-4] + "_"
    gimp.progress_init("Save frames as {}_*.png".format(prefix))
    for (layer_index, layer) in enumerate(image.layers):
        try:
            filename = "{}{:02d}.png".format(prefix, int(layer.name))
        except ValueError:
            filename = "{}{}.png".format(prefix, layer.name)
        pdb.file_png_save(
            image,
            layer,
            filename,
            None,
            True,  # interlace
            9,  # compression
            True,  # bkgd
            True,  # gama
            True,  # offs
            True,  # phys
            True,  # time
        )
        gimp.progress_update(100 * (layer_index + 1) / len(image.layers))
    gimp.message("All frames saved as {}_*.png".format(prefix))
def pythonSaveToPSD(image):

    # Prep
    pdb.gimp_image_undo_group_start(image)
    pdb.gimp_context_push()

    # Code
    drawable = pdb.gimp_image_get_active_drawable(image)
    filename = pdb.gimp_image_get_filename(image)
    temp = filename.replace("_CLEAN", "")
    temp2 = temp.replace("_EDIT", "")
    temp = temp2.replace("_XCF", "")
    filename = temp.replace("_PSD", "")
    path = os.path.dirname(filename)
    path += "_PSD"
    name = os.path.basename(filename)
    out_psd = os.path.join(path, name)
    out_psd = os.path.splitext(out_psd)[0] + '.psd'

    # Create folder
    if not os.path.exists(path):
        os.makedirs(path)

    # Save in PSD
    pdb.gimp_file_save(image, drawable, out_psd, out_psd)
    pdb.gimp_image_clean_all(image)

    # Finish
    pdb.gimp_context_pop()
    pdb.gimp_image_undo_group_end(image)
    pdb.gimp_displays_flush()
示例#4
0
def pythonSaveToClean(image):

    # Prep
    pdb.gimp_image_undo_group_start(image)
    pdb.gimp_context_push()

    # Code
    filename_old = pdb.gimp_image_get_filename(image)
    filename = filename_old.replace("_CLEAN", "")
    # drawable = pdb.gimp_image_get_active_drawable(image)
    path = os.path.dirname(filename)
    path += "_CLEAN"
    name = os.path.basename(filename)
    out_file = os.path.join(path, name)

    # Create CLEAN folder
    if not os.path.exists(path):
        os.makedirs(path)

    # Merge visible layers in new image and export in CLEAN folder
    new_image = pdb.gimp_image_duplicate(image)
    layer = pdb.gimp_image_merge_visible_layers(new_image, CLIP_TO_IMAGE)
    pdb.gimp_file_save(new_image, layer, out_file, out_file)
    pdb.gimp_image_delete(new_image)
    pdb.gimp_image_clean_all(image)

    # Finish
    pdb.gimp_context_pop()
    pdb.gimp_image_undo_group_end(image)
    pdb.gimp_displays_flush()
def pythonSaveToEditJpeg(image):

    # Prep
    pdb.gimp_image_undo_group_start(image)
    pdb.gimp_context_push()

    # Code
    # drawable = pdb.gimp_image_get_active_drawable(image)
    filename = pdb.gimp_image_get_filename(image)
    temp = filename.replace("_CLEAN", "")
    temp2 = temp.replace("_EDIT", "")
    filename = temp2.replace("_XCF", "")
    path = os.path.dirname(filename)
    path += "_EDIT"
    name = os.path.basename(filename)
    out_file = os.path.join(path, name)
    out_file = os.path.splitext(out_file)[0] + '.jpg'

    # Create _EDIT folder
    if not os.path.exists(path):
        os.makedirs(path)

    # Merge visible layers in new image and export in JPEG
    new_image = pdb.gimp_image_duplicate(image)
    layer = pdb.gimp_image_merge_visible_layers(new_image, CLIP_TO_IMAGE)
    pdb.gimp_file_save(new_image, layer, out_file, out_file)
    pdb.gimp_image_delete(new_image)
    pdb.gimp_image_clean_all(image)

    # Finish
    pdb.gimp_context_pop()
    pdb.gimp_image_undo_group_end(image)
    pdb.gimp_displays_flush()
示例#6
0
def _get_filename_backside(img, file_type='png'):
    """ Determine card side and output file name.
    """
    file_name = pdb.gimp_image_get_filename(img)
    file_name = os.path.split(file_name)[-1]
    file_name = '.'.join(file_name.split('.')[:-1])
    back_side = file_name.endswith('-Back-Face') or file_name.endswith('-2')
    file_name = file_name + '.' + file_type
    return (file_name, back_side)
def gif(image=None, suffix=None, fps=24):
    if not image:
        image = gimp.image_list()[0]
    file_path = pdb.gimp_image_get_filename(image)[:-4]
    if suffix:
        file_path += "_" + suffix.strip()
    file_path += ".gif"
    ms = int(1000.0 / fps)
    temp_image = False
    try:
        gimp.progress_init(
            "Save animated GIF @ {} fps = {} ms/frame as {}".format(
                fps, ms, file_path))
        if pdb.gimp_image_base_type(image) != 2:
            temp_image = True
            image = pdb.gimp_image_duplicate(image)
            pdb.gimp_image_convert_indexed(
                image,
                0,  # dither-type=CONVERT-DITHER-NONE
                0,  # palette-type=CONVERT-PALETTE-GENERATE
                255,  # num-cols
                False,  # alpha-dither
                False,  # remove-unused
                ""  # palette
            )
            gimp.progress_update(50)
        pdb.file_gif_save(
            image,
            image.layers[0],
            file_path,
            file_path,
            True,  # interlace
            True,  # loop
            ms,  # default-delay
            2  # default-dispose
        )
        gimp.progress_update(100)
        gimp.message("Saved animated GIF @ {} fps = {} ms/frame as {}".format(
            fps, ms, file_path))
    finally:
        if temp_image:
            pdb.gimp_image_delete(image)
def sheet(image=None, cols=0):
    if not image:
        image = gimp.image_list()[0]
    if not cols:
        best = (1, 10000000)
        for cols in range(1, len(image.layers) + 1):
            rows = (len(image.layers) + (cols - 1)) // cols
            (sheet_width, sheet_height) = (cols * image.width,
                                           rows * image.height)
            sheet_aspect_ratio = sheet_width / sheet_height if sheet_width > sheet_height else sheet_height / sheet_width
            if sheet_aspect_ratio < best[1]:
                best = (cols, sheet_aspect_ratio)
        cols = best[0]
    file_path = "{}_sheet_{}_frames_{}_columns_{}x{}.png".format(
        pdb.gimp_image_get_filename(image)[:-4], len(image.layers), cols,
        image.width, image.height)
    gimp.progress_init("Save sheet as {}".format(file_path))
    rows = (len(image.layers) + (cols - 1)) // cols
    sheet = pdb.gimp_image_new(image.width * cols, image.height * rows, 0)
    try:
        sheet_layer = pdb.gimp_layer_new(
            sheet,
            sheet.width,
            sheet.height,
            1,  # type = RGBA-IMAGE
            "sprite sheet",
            100,  # opacity = 100 %
            0  # mode = LAYER-MODE-NORMAL-LEGACY
        )
        pdb.gimp_image_insert_layer(sheet, sheet_layer, None, 0)

        (row, col) = (0, 0)
        for (layer_index, layer) in enumerate(image.layers):
            pdb.gimp_selection_none(image)
            pdb.gimp_layer_resize_to_image_size(layer)
            pdb.gimp_edit_copy(layer)
            floating = pdb.gimp_edit_paste(sheet_layer, True)
            (left, top) = floating.offsets
            pdb.gimp_layer_translate(floating, col * image.width - left,
                                     row * image.height - top)
            pdb.gimp_floating_sel_anchor(floating)
            col += 1
            if col >= cols:
                col = 0
                row += 1
            gimp.progress_update(100 * (layer_index + 1) / len(image.layers))
        pdb.file_png_save(
            sheet,
            sheet_layer,
            file_path,
            None,
            True,  # interlace
            9,  # compression
            True,  # bkgd
            True,  # gama
            True,  # offs
            True,  # phys
            True,  # time
        )
        gimp.message("All frames saved as {}".format(file_path))
    finally:
        pdb.gimp_image_delete(sheet)
def cutter_single_image(
        image, drawable,
        limit, sl_thresh, sz_thresh,
        bg_manual, bg_color, bg_corner, bg_x, bg_y,
        padding, deskew, sq_crop, autoclose,
        save_same, save_dir, save_ftype, save_dpi, jpg_qual, save_suffix
    ):
    img_width = pdb.gimp_image_width(image)
    img_height = pdb.gimp_image_height(image)
    img_fullpath = pdb.gimp_image_get_filename(image)
    img_filename = os.path.basename(img_fullpath)
    img_name = '.'.join(img_filename.split('.')[:-1])
    img_ext = save_ftype or img_filename.split('.')[-1].lower()
    new_filename_tpl = ''.join([
        img_name, '-', save_suffix, '-',
        '%0', str(len(str(int(limit + 1)))), 'd',
        '.', img_ext
    ])
    new_fullpath_tpl = os.path.join(
        os.path.dirname(img_fullpath) if save_same else save_dir,
        new_filename_tpl
    )

    # gimp.message(new_fullpath_tpl)

    # function code goes here...
    gimp.context_push()
    pdb.gimp_image_undo_disable(image)

    # If the background wasn't manually defined, pick the colour from one of the four corners
    # (using radius 5 average)
    if not bg_manual:
        if bg_corner in (1, 3):
            bg_x = img_width - bg_x
        if bg_corner in (2, 3):
            bg_y = img_height - bg_y

        bg_color = pdb.gimp_image_pick_color(image, drawable, bg_x, bg_y, True, True, 5)

    pdb.gimp_context_set_defaults()
    pdb.gimp_context_set_antialias(True)
    pdb.gimp_context_set_sample_transparent(True)
    pdb.gimp_context_set_sample_threshold_int(sl_thresh)
    pdb.gimp_context_set_feather(True)
    fr = min(img_width, img_height) / 100.0     # NOTE why???
    pdb.gimp_context_set_feather_radius(fr, fr)
    pdb.gimp_context_set_background(bg_color)

    pdb.gimp_image_select_color(image, gimpfu.CHANNEL_OP_REPLACE, drawable, bg_color)

    # convert inverted copy of the background selection to a path
    pdb.gimp_selection_sharpen(image)
    pdb.gimp_selection_invert(image)

    # _, before = pdb.gimp_image_get_vectors(image)
    pdb.plug_in_sel2path(image, drawable)
    # _, after = pdb.gimp_image_get_vectors(image)
    # newpath_id = list(set(after) - set(before))[0]
    # newpath = gimp.Vectors.from_id(newpath_id)

    # looks like newly created vector is always active, so this should be sufficent
    newpath = pdb.gimp_image_get_active_vectors(image)

    pdb.gimp_context_set_feather(False)

    _, strokes = pdb.gimp_vectors_get_strokes(newpath)
    extracted = 0
    for stroke_id in strokes:
        stroke_points = pdb.gimp_vectors_stroke_get_points(newpath, stroke_id)
        # skip not closed paths
        if not stroke_points[3]:
            continue

        temp_vector = pdb.gimp_vectors_new(image, '-temp-')
        pdb.gimp_image_insert_vectors(image, temp_vector, None, -1)

        pdb.gimp_vectors_stroke_new_from_points(temp_vector, *stroke_points)
        pdb.gimp_image_select_item(image, gimpfu.CHANNEL_OP_REPLACE, temp_vector)
        pdb.gimp_image_remove_vectors(image, temp_vector)

        # check for minimum size
        bounds = pdb.gimp_selection_bounds(image)
        sizex = bounds[3] - bounds[1]
        sizey = bounds[4] - bounds[2]

        if (min(sizex, sizey) < sz_thresh or
                sizex >= img_width or
                sizey >= img_height):
            continue

        buffname = "dsibuff"
        if deskew and pdb.gimp_procedural_db_proc_exists('gimp_deskew_plugin'):
            pdb.gimp_progress_set_text('Running deskew plugin...')
            pdb.gimp_image_select_rectangle(
                image, gimpfu.CHANNEL_OP_REPLACE,
                bounds[1], bounds[2], sizex, sizey
            )
            buffname = pdb.gimp_edit_named_copy(drawable, buffname)
            temp_image = pdb.gimp_edit_named_paste_as_new(buffname)
            temp_layer = pdb.gimp_image_get_active_layer(temp_image)
            pdb.gimp_image_undo_disable(temp_image)

            pdb.gimp_layer_flatten(temp_layer)

            # RUN_NONINTERACTIVE causes 'calling error' exception
            pdb.gimp_deskew_plugin(temp_image, temp_layer, 0, 0, 0, 0, True,
                                   run_mode=gimpfu.RUN_INTERACTIVE)

            pdb.gimp_image_resize_to_layers(temp_image)
            pdb.gimp_layer_flatten(temp_layer)

            pdb.gimp_image_select_contiguous_color(
                temp_image, gimpfu.CHANNEL_OP_REPLACE, temp_layer, 0, 0
            )
            pdb.gimp_selection_invert(temp_image)
            bounds = pdb.gimp_selection_bounds(temp_image)
            sizex = bounds[3] - bounds[1]
            sizey = bounds[4] - bounds[2]
            pdb.gimp_selection_none(temp_image)
            pdb.gimp_image_crop(temp_image, sizex, sizey, bounds[1], bounds[2])

            if (sq_crop and sizex != sizey
                    and pdb.gimp_procedural_db_proc_exists('script_fu_addborder')):
                if sizex > sizey:
                    dx = 0
                    dy = (sizex - sizey) * 0.5
                else:
                    dx = (sizey - sizex) * 0.5
                    dy = 0

                pdb.script_fu_addborder(temp_image, temp_layer, dx, dy, bg_color, 0)
                pdb.gimp_image_raise_item_to_top(temp_image, temp_layer)
                pdb.gimp_image_merge_visible_layers(temp_image, gimpfu.EXPAND_AS_NECESSARY)
                temp_layer = pdb.gimp_image_get_active_layer(temp_image)
        else:
            temp_image = image
            pdb.gimp_image_undo_disable(temp_image)
            temp_layer = pdb.gimp_image_get_active_layer(temp_image)

            if sq_crop:
                c_x = 0.5 * (bounds[1] + bounds[3])
                c_y = 0.5 * (bounds[2] + bounds[4])
                hl = padding + max(sizex, sizey) * 0.5
                sel_x = c_x - hl
                sel_y = c_y - hl
                sel_w = sel_h = 2 * hl
            else:
                sel_x = bounds[1]
                sel_y = bounds[2]
                sel_w = sizex
                sel_h = sizey

            pdb.gimp_image_select_rectangle(
                temp_image, gimpfu.CHANNEL_OP_REPLACE,
                sel_x, sel_y, sel_w, sel_h
            )
            buffname = pdb.gimp_edit_named_copy(drawable, buffname)
            temp_image = pdb.gimp_edit_named_paste_as_new(buffname)
            temp_layer = pdb.gimp_image_get_active_layer(temp_image)

        if padding and pdb.gimp_procedural_db_proc_exists('script_fu_addborder'):
            pdb.script_fu_addborder(temp_image, temp_layer, padding, padding, bg_color, 0)
            pdb.gimp_image_merge_visible_layers(temp_image, gimpfu.EXPAND_AS_NECESSARY)
            temp_layer = pdb.gimp_image_get_active_layer(temp_image)

        pdb.gimp_image_undo_enable(temp_image)
        temp_display = pdb.gimp_display_new(temp_image)

        extracted += 1

        filename = new_fullpath_tpl % (extracted, )
        pdb.gimp_image_set_resolution(temp_image, save_dpi, save_dpi)
        if img_ext == 'jpg':
            pdb.file_jpeg_save(
                temp_image, temp_layer, filename, filename,
                jpg_qual, 0.1, 1, 1, '', 2, 0, 0, 1
            )
        else:
            pdb.gimp_file_save(temp_image, temp_layer, filename, filename)

        if autoclose:
            pdb.gimp_display_delete(temp_display)

        if extracted >= limit:
            break

    pdb.gimp_progress_set_text('Extracted %d images' % (extracted, ))

    pdb.gimp_image_remove_vectors(image, newpath)
    pdb.gimp_selection_none(image)

    pdb.gimp_image_undo_enable(image)
    pdb.gimp_progress_end()
    pdb.gimp_displays_flush()
    gimp.context_pop()

    return extracted