Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Processing XCF files in batch
#11
(12-11-2022, 04:55 PM)Ofnuts Wrote: Just replace
Code:
layer.fill(FOREGROUND_FILL)


with:
Code:
layer.lock_alpha=True
pdb.gimp_edit_fill(layer,FILL_FOREGROUND)

So now you bucket-fill with the alpha channel locked, so pixels keep their opacity. layer.fill() always fill the whole layer, it is intended to initialize the layer after creation, not for general painting.

This seems to have done the trick, thanks.
Reply
#12
So it turns out there's one more problem I've discovered with some of the XCF files, where locking the alpha channel prevents some of the coloured pixels from being filled. I confirmed  this by opening the files manually in GIMP and trying to bucket fill them. Doing so with the alpha channel unlocked worked fine, but if I locked the alpha channel, they wouldn't get bucket-filled.

My guess is some of the red/green/blue pixels have non-0 non-255 values of alpha (I can't see alpha values in GIMP's colour picker tool though to confirm this). I have no idea how this was introduced to the images, but I have managed to replicate the issue using a layer mask. I've attached a sample project that shows the issue - bucket filling the Arm layer works fine, but if you lock the alpha channel, you can't fill it any longer.

Is there a way to adapt the script to handle this problem, so that partially transparent pixels in the layers are still filled and only the fully transparent pixels are ignored?

For reference, my current script looks like this in full (I've made some minor adjustments to address some other issues in the images, such as hidden layers, wrong layer names, and saved selections):

Code:
from gimpfu import *
import gimpcolor
import os
import os.path as osp
import sys


sys.stderr = open(osp.splitext(__file__)[0] + '.log', 'w')
sys.stdout = sys.stderr


def run(project_dir, save_dir, export_dir):
    for root, _, fnames in os.walk(project_dir):
        for fname in fnames:
            bname, ext = osp.splitext(fname)
            if ext.lower() != '.xcf':
                continue

            project_f = osp.join(root, fname)
            rel_path = osp.dirname(osp.relpath(project_f, project_dir))
            save_f = osp.join(save_dir, rel_path, bname + '.xcf')
            export_f = osp.join(export_dir, rel_path, bname + '.png')
            fix_project(project_f, save_f, export_f)


def fix_project(project_f, save_f, export_f):
    print project_f
    xcf = pdb.gimp_xcf_load(0, project_f, project_f)
    pdb.gimp_selection_none(xcf)

    for layer in xcf.layers:
        layer.visible = True
        layer.opacity = 100.
        layer.lock_alpha = True
        if 'snek' in layer.name.lower():
            pdb.gimp_context_set_foreground(gimpcolor.RGB(255, 0, 0))
            pdb.gimp_edit_fill(layer, FILL_FOREGROUND)
        elif 'phone' in layer.name.lower():
            pdb.gimp_context_set_foreground(gimpcolor.RGB(0, 255, 0))
            pdb.gimp_edit_fill(layer, FILL_FOREGROUND)
        elif 'arm' in layer.name.lower():
            pdb.gimp_context_set_foreground(gimpcolor.RGB(0, 0, 255))
            pdb.gimp_edit_fill(layer, FILL_FOREGROUND)
        layer.lock_alpha = False

    if not osp.isdir(osp.dirname(save_f)):
        os.makedirs(osp.dirname(save_f))
    if not osp.isdir(osp.dirname(export_f)):
        os.makedirs(osp.dirname(export_f))
    pdb.gimp_xcf_save(0, xcf, None, save_f, save_f)
    xcf.merge_visible_layers(EXPAND_AS_NECESSARY)
    pdb.file_png_save(xcf, xcf.layers[0], export_f, export_f, 0, 9, 1, 0, 0, 1, 1)
    pdb.gimp_image_delete(xcf)


Attached Files
.xcf   Sample.xcf (Size: 721.58 KB / Downloads: 78)
Reply
#13
I don't see such a problem. If you are talking about the partially transparent area in the arm (covering the thumb), then the layer color has been replaced. However, since the layer is partially transparent, the color picker will report the blend of the color and whatever color is below if the Sample merged option is checked.  If you uncheck the option, you get the actual color in the layer.

Here is what I see (I use the Pointer dialog to explore the image, faster and more options than the color picker)

   
Reply
#14
I see.. Yes, I also get pure blue if I uncheck Sample merged in the colour picker. But the issue still remains, I'd like to remove this transparency from the partially transparent pixels in the layer. I.e. I'd like all the pixels in the red/green/blue layers to be either fully transparent or fully opaque red/green/blue (i.e. RGBA 255/0/0/255, 0/255/0/255, and 0/0/255/255). Is this possible to accomplish from the script? I tried replacing gimpcolor.RGB(255, 0, 0) with gimpcolor.RGBA(255, 0, 0, 255) but that threw an error.
Reply
#15
(12-16-2022, 11:45 AM)Mate de Vita Wrote: I see.. Yes, I also get pure blue if I uncheck Sample merged in the colour picker. But the issue still remains, I'd like to remove this transparency from the partially transparent pixels in the layer. I.e. I'd like all the pixels in the red/green/blue layers to be either fully transparent or fully opaque red/green/blue (i.e. RGBA 255/0/0/255, 0/255/0/255, and 0/0/255/255). Is this possible to accomplish from the script? I tried replacing gimpcolor.RGB(255, 0, 0) with gimpcolor.RGBA(255, 0, 0, 255) but that threw an error.

Try pdb.plug_in_threshold_alpha(image, layer, threshold), with suitable threshold value. But you may get pixellated edges.
Reply


Forum Jump: