Question

I've a color list file I read it into a python list and I'd like to create one (or several) image(s) composed by squares with background color read from file and as foreground html string of the color (written with white). I.e. I read #ff0000 from input file then I create a 100x100 square with red background and a white string "#ff0000" as foreground...and so on for each color in input file.

This is my script:

#!/usr/bin/env python
from gimpfu import *

def readColors(ifc):
    """Read colors from input file and return a python list with all them"""
    a = []
    fd = open(ifc,"r")
    for i in fd:
        if not i.startswith("//"):#skip comment lines
            a.append(i.rstrip('\n'))
    return a

def rgb2html(col):
    """Converts a color: from (255,255,255) to #ffffff"""
    r,g,b = col
    return "#%x%x%x" % (r,g,b)

def html2rgb(col):
    """Converts a color: from #ffffff to (255,255,255)"""
    s=col.strip('#')
    r=int(s[:2],16)
    g=int(s[2:4],16)
    b=int(s[4:6],16)
    return r,g,b

def nextColor():
    """Gets next html color from color list"""
    col = nextColor.array[nextColor.counter]
    nextColor.counter +=1
    return col

def isNextColor():
    """Is there another color or list is over?"""
    return nextColor.counter<isNextColor.colorslenght

def isPageEnded(y,YSIZE):
    """Is there enough room to draw another square?"""
    return (y+100)>=YSIZE

def newPage(XSIZE,YSIZE):
    """Returns a new image"""
    return gimp.Image(XSIZE,YSIZE,RGB)      

def createImage(color,text):
    """Draws a square filled with color and white color text. It works!"""
    gimp.set_foreground((255,255,255))#text color
    gimp.set_background(color)        #background color
    image = gimp.Image(100,100,RGB)
    back = gimp.Layer(image,"font",100,100,RGB_IMAGE,100,NORMAL_MODE)   
    image.add_layer(back,1)
    back.fill(BACKGROUND_FILL)
    lay = back.copy()
    lay.name = "font"
    image.add_layer(lay,0)
    lay = pdb.gimp_text_fontname(image,None,2,100/4,text,2,True,18,PIXELS,"Sans")   
    image.merge_down(lay, NORMAL_MODE)
    image.flatten() 
    return image

def drawRect(image,x,y):
    """Here I'd like to copy the result of createImage at current x,y position of current image. It doesn't work!"""
    text  = nextColor()
    color = html2rgb(text)  
    img = createImage(color,text)
    drawable = pdb.gimp_image_active_drawable(image)    
    image.disable_undo()
    pdb.gimp_selection_none(image)
    pdb.gimp_image_select_rectangle(image, 2, x, y, 100, 100)   
    if pdb.gimp_edit_named_copy_visible(img, "buffer"):             
        floating_sel = pdb.gimp_edit_named_paste(drawable, "buffer", TRUE)
        pdb.gimp_selection_none(image)
        image.flatten() 
        gimp.Display(image)#to debug
        image.enable_undo()

def savePage(image,directory,filename):
    """Saves composed image to filename"""
    drawable = pdb.gimp_image_active_drawable(image)
    pdb.file_png_save(image, drawable, directory+"\\"+filename, filename, 0,9,1,0,0,1,1)


def draw(ifile,savedir,prefix):
    """Main method. it manage page's room, slicing it in several 100x100 squares"""
    YSIZE = 1000
    XSIZE = 1000
    x = y = pc = 0
    colorArray = readColors(ifile)
    nextColor.counter = 0
    nextColor.array = colorArray 
    isNextColor.colorslenght = len(colorArray)
    pdb.gimp_context_push()
    image = newPage(XSIZE,YSIZE)
    while(isNextColor()):
        drawRect(image,x,y)
        x += 100        # move to next column
        if x+100>=XSIZE:#move to next row
            x = 0
            y += 100
        if isPageEnded(y,YSIZE):
            savePage(image,savedir,prefix+str(pc)+".png")
            gimp.Display(image)#to debug
            pc += 1
            image = newPage(XSIZE,YSIZE)
            x = 0
            y = 0
    savePage(image,savedir,prefix+str(pc)+".png")#save last page
    pdb.gimp_context_pop()

ifc = '<path to color list file>\\colors.txt'
ofc = '<path to output directory>\\palette'
prefix = 'table' #prefix for each file(i.e.: table0.png, table1.png...)

draw(ifc,ofc,prefix) #main method call

My current problem is with drawRect method. I can't copy image returned by createImage method at coords x,y of bigger image in drawRect method. In drawRect method I tried to used gimp's "copy into selection": select an area, and paste in it stuff copied from another image. But I have a trouble with layers and I can't get image copied at right position.

Just for completeness this are few lines from ifc file:

#b6ffff
#f079f3
#9979f3
#79c2f3
#7a79f3
#79f380
#f3799a

Thanks in advance for any help.

Alberto

Was it helpful?

Solution

Maybe it could be useful for someone else (it must be saved as "draw-colors.py" and copied to GIMP 2/lib/gimp/2.0/plug-ins folder):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gimpfu import *

def readColors(ifile):
    """Read colors from input file and return a python list with all them"""
    a = []
    fd = open(ifile,"r")
    for i in fd:
        if not i.startswith('//'):
            a.append(i)
    return a

def rgb2html(col):
    """Converts a color: from (255,255,255) to #ffffff"""
    r,g,b = col
    return "#%x%x%x" % (r,g,b)

def html2rgb(col):
    """Converts a color: from #ffffff to (255,255,255)"""
    s=col.strip('#')
    r=int(s[:2],16)
    g=int(s[2:4],16)
    b=int(s[4:6],16)
    return r,g,b

def nextColor():
    """Gets next html color from color list"""
    col = html2rgb(nextColor.array[nextColor.counter])
    nextColor.counter +=1
    return col

def isNextColor():  
    """Is there another color or list is over?"""
    return nextColor.counter<isNextColor.colorslenght

def isPageEnded(y,sizey):
    """Is there enough room to draw another square?"""
    return (y+100)>=sizey

def newPage(sizex,sizey):       
    """Returns a new image"""
    image = pdb.gimp_image_new(sizex, sizey, RGB)
    layer = pdb.gimp_layer_new(image, sizex, sizey, RGB, "layer", 0, 0)
    pdb.gimp_image_add_layer(image, layer, 0)
    drw = pdb.gimp_image_active_drawable(image)
    pdb.gimp_context_set_background((255,255,255))
    pdb.gimp_drawable_fill(drw, BACKGROUND_FILL)
    pdb.gimp_context_set_brush('Circle (01)')
    return image

def savePage(image,filename):
    """Saves composed image to filename"""
    layers = image.layers
    last_layer = len(layers)-1
    try:
        disable=pdb.gimp_image_undo_disable(image)
        pdb.gimp_layer_add_alpha(layers[0])
        pdb.plug_in_colortoalpha(image,image.active_layer,(0,0,0))
        layer = pdb.gimp_image_merge_visible_layers(image, 1)
        enable = pdb.gimp_image_undo_enable(image)
        pdb.file_png_save(image, image.active_layer, filename, filename, 0,9,1,0,0,1,1)
    except Exception as e:
        raise e

def drawRect(x,y,color,image):
    """draw a single square"""
    text = rgb2html(color)
    pdb.gimp_image_select_rectangle(image, 2, x, y, 100, 100)
    pdb.gimp_context_set_background(color)
    pdb.gimp_edit_fill(image.active_layer, 1)
    try:
        text_layer = pdb.gimp_text_fontname(image, None, x, y+(100/2), text, 2, 1, 18, 0, "Sans")
        pdb.gimp_image_merge_down(image, text_layer, 0)
    except Exception as e:
        raise e 

def draw(ifile,odir,prefix,sizex,sizey):
    """Main method. it manage page's room, slicing it in several 100x100 squares"""
    colorArray = readColors(ifile)  
    nextColor.counter = 0
    nextColor.array = colorArray
    isNextColor.colorslenght = len(colorArray)  
    pc = x = y = 0
    image = newPage(sizex,sizey)
    try:
        while(isNextColor()):
            pdb.gimp_context_push()
            drawRect(x,y,nextColor(),image)
            x += 100#cambia colonna
            if x+100>=sizex:#cambia riga
                x = 0
                y += 100
            if isPageEnded(y,sizey):#salva pagina
                savePage(image,odir+'\\'+prefix+str(pc)+".png")
                pc += 1
                image = newPage(sizex,sizey)
                x = y = 0
            savePage(image,odir+'\\'+prefix+str(pc)+".png")
            pdb.gimp_context_pop()
    except Exception as e:
        raise e

register(
    "draw-colors",
    N_("Create a color map from a text color file"),
    "Create a color map from a text color file",
    "Alberto",
    "@Copyright Alberto 2014",
    "2014/10/21",
    N_("Draw Colors..."),
    "",
    [
        (PF_FILE, "ifile", N_("Color input file:"), 'default\\input\\colorfile\\path\\colorlist.txt'),

        (PF_DIRNAME, "odir", N_("Path for png export:"), 'default\\output\\path'),
        (PF_STRING, "prefix",  N_("Filename prefix for export:"),  "table"),
        (PF_INT8, "sizex", N_("Image's x size:"), 1024),
        (PF_INT8, "sizey", N_("Image's y size:"), 1024)
    ],
    [],
    draw,  #main method call
    menu="<Image>/Filters/Alberto",
    domain=("gimp20-python", gimp.locale_directory)
    )

main()  

Output example: enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top