It is currently Thu Jun 27, 2024 12:42 pm


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: A Text Bubble
PostPosted: Thu Jan 11, 2024 12:06 pm  (#1) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 3995
Location: Canada
Please see how to use this plug-in in the following video.
I got permission from my client if I could do something similar like this Plug-in to promote my fiverr GIG for writing GIMP Plug-ins.
www.youtube.com Video from : www.youtube.com

plug-in code
#!/usr/bin/env python

# speech-bubble.py
# Created by TT
# ------------
#| Change Log |
# ------------
# Rel 1.0:
from gimpfu import *

def text_bubble(img, layer,textfile,font,fontsize,fontcolor,backgroundcolor):
    # #Set up an undo group, so the operation will be undone in one step.
    pdb.gimp_undo_push_group_start(img)
    #get path points
    vectors = pdb.gimp_image_get_active_vectors(img)
    num_strokes,stroke_ids = pdb.gimp_vectors_get_strokes(vectors)
    pathpoints = []
    arrowpoints = []
    for i in range(0,len(stroke_ids)):
        _type,_num_points,controlpoints,_closed = pdb.gimp_vectors_stroke_get_points(vectors,stroke_ids[i])
        index = 1
        while (index*2+1 <= len(controlpoints)):
            #grab just the 2 points of center control point
            pathpoints.append(controlpoints[index*2:index*2+2])
            arrowpoints.append(controlpoints[index*2+2:index*2+4])
            index += 3; #increment by 3 to jump to next center control point
    with open(textfile,"r") as in_file:
        texts = in_file.read().split('\n[breaker]\n')
    for i in range(0,len(texts)):
        text = texts[i]
        number = i+1 #since we're indexing text1, text2, text3 and so on.   
        # new path version
        text_layer = pdb.gimp_text_layer_new(img,text,font,fontsize,0)#Units is either PIXELS(0) POINTS(1)
        pdb.gimp_image_insert_layer(img,text_layer,None,0)
        pdb.gimp_text_layer_set_color(text_layer,fontcolor)
        pdb.gimp_item_set_name(text_layer,'text #'+str(number))
        pdb.plug_in_autocrop_layer(img,text_layer) #auto crop
        x0 = 0; y0 = 0 #default at top left
        ax0 = 0; ay0 = 0 #default of arrow pointing to here
        if i <= len(pathpoints):
            x0 = pathpoints[i][0]
            y0 = pathpoints[i][1]
            pdb.gimp_layer_set_offsets(text_layer,x0,y0)
            ax0 = arrowpoints[i][0]
            ay0 = arrowpoints[i][1]

        bgwidth = text_layer.width + fontsize*2   
        bgheight = text_layer.height + fontsize*2
        bglayer = pdb.gimp_layer_new(img,bgwidth,bgheight,RGBA_IMAGE,"bg #"+str(number),100,LAYER_MODE_NORMAL)
        pdb.gimp_image_insert_layer(img,bglayer,None,1)
        pdb.gimp_layer_set_offsets(bglayer,x0-fontsize,y0-fontsize)
        roundcorner = fontsize/2.0
        pdb.gimp_image_select_round_rectangle(img,CHANNEL_OP_REPLACE,x0-fontsize,y0-fontsize,bgwidth,bgheight,roundcorner,roundcorner)
        pdb.gimp_context_set_foreground(backgroundcolor)
        pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)
       
        mx = x0 + text_layer.width/2.0 #middle of text layer
        my = y0 + text_layer.height/2.0
        xdiff = (ax0 - mx); ydiff = (ay0 - my)
        dist = (xdiff**2.0+ydiff**2.0)**0.5
        scaledxdiff = xdiff/dist * fontsize
        scaledydiff = ydiff/dist * fontsize
        p0x = mx + scaledydiff
        p0y = my - scaledxdiff
        p1x = mx - scaledydiff
        p1y = my + scaledxdiff
        pdb.gimp_layer_resize_to_image_size(bglayer)
        pdb.gimp_image_select_polygon(img,CHANNEL_OP_REPLACE,6,[p0x,p0y,p1x,p1y,ax0,ay0])
        #pdb.gimp_context_set_foreground((255,0,0))
        pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)

        pdb.gimp_selection_none(img)
    pdb.gimp_undo_push_group_end(img)
    #Ensure the updated image is displayed now
    pdb.gimp_displays_flush()

register(
    "python_fu_text_bubble",
    "Puts Text where path is drawn",
    "Puts Text where path is drawn",
    "TT",
    "TT",
    "2023.12.8",
    "A Text Bubble",
    "RGB*",      # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
    [
    #INPUT BEGINS
    (PF_IMAGE, "img", "Image", None),
    (PF_DRAWABLE,   "layer", "Drawable", None),
    (PF_FILENAME, "textfile", "Text File:", 0),
    (PF_FONT, "font", "Font:", "Verdana"),
    (PF_INT, "fontsize", "Font Size:", 20),
    (PF_COLOR, "fontcolor", "Font Color:", (0, 0, 0) ),
    (PF_COLOR, "backgroundcolor","Background Color:",(255,255,255)),
    #INPUT ENDS
    ],
    [],
    text_bubble,
    menu="<Image>/Python-Fu")
main()



hellobro.txt
Hello there, bro!
[breaker]
Hi bro, can you write me
a GIMP Plugin?
[breaker]
Sure I can
[breaker]
Sweet, bro...
Thanks!

Better version that creates layer_group for each text so that you can easily move layer-group

_________________
TinT


Last edited by trandoductin on Fri Jan 12, 2024 2:50 pm, edited 1 time in total.

Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: A Text Bubble
PostPosted: Thu Jan 11, 2024 12:32 pm  (#2) 
Offline
Administrator
User avatar

Joined: Aug 10, 2012
Posts: 13066
Location: Native to NYC living in Arizona, Gimp 2.8 & 2.10, Win 11 PC.
Nice one trandoductin!
:bigthup

_________________
Image
"A wise man learns more from a foolish question than a fool can learn from a wise answer"
Image


Top
 Post subject: Re: A Text Bubble
PostPosted: Thu Jan 11, 2024 12:33 pm  (#3) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 3995
Location: Canada
Thanks

_________________
TinT


Top
 Post subject: Re: A Text Bubble
PostPosted: Thu Jan 11, 2024 12:34 pm  (#4) 
Offline
Administrator
User avatar

Joined: Aug 10, 2012
Posts: 13066
Location: Native to NYC living in Arizona, Gimp 2.8 & 2.10, Win 11 PC.
trandoductin wrote:
Thanks

:bigthup
.

_________________
Image
"A wise man learns more from a foolish question than a fool can learn from a wise answer"
Image


Top
 Post subject: Re: A Text Bubble
PostPosted: Thu Jan 11, 2024 4:07 pm  (#5) 
Offline
GimpChat Member
User avatar

Joined: Nov 04, 2015
Posts: 1362
I did a lot of cartoons and used the Ellipse select or rectangle select (often with rounded edges) from toolbox for text bubbles.
Then I used a big white brush over them (it always stays in the select because its not locked-down), made a text and positioned it and finally used a thin pencil (make straight lines with shift key) to make the speech arrow. I rarely used 'thought bubbles'.

Point is this takes me all of 4 minutes and it is customized to the image being presented.
Quote:
Many script writers remind me of the saying 'to a hammer everything looks like a nail' :)


You could say that replacing basic Gimp operations reduces a persons ability to actually use Gimp. Instead they are very good at finding plug-ins :)


Last edited by Tas_mania on Thu Jan 11, 2024 4:15 pm, edited 1 time in total.

Top
 Post subject: Re: A Text Bubble
PostPosted: Thu Jan 11, 2024 4:13 pm  (#6) 
Offline
GimpChat Member
User avatar

Joined: Nov 04, 2015
Posts: 1362
This is the only cartoon I did that doesn't break the GC code :)


Image


Top
 Post subject: Re: A Text Bubble
PostPosted: Fri Jan 12, 2024 10:00 am  (#7) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 3995
Location: Canada
Many script writers remind me of the saying 'to a hammer everything looks like a nail' :)

For me it's when a person hammers 1000 nails, they get an automatic hammer heheh

_________________
TinT


Top
 Post subject: Re: A Text Bubble
PostPosted: Fri Jan 12, 2024 2:49 pm  (#8) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 3995
Location: Canada
Ok this version is way better.
#!/usr/bin/env python

# speech-bubble.py
# Created by TT
# ------------
#| Change Log |
# ------------
# Rel 1.0:
from gimpfu import *

def text_bubble(img, layer,textfile,font,fontsize,fontcolor,backgroundcolor):
    # #Set up an undo group, so the operation will be undone in one step.
    pdb.gimp_undo_push_group_start(img)
    #get path points
    vectors = pdb.gimp_image_get_active_vectors(img)
    num_strokes,stroke_ids = pdb.gimp_vectors_get_strokes(vectors)
    pathpoints = []
    arrowpoints = []
    for i in range(0,len(stroke_ids)):
        _type,_num_points,controlpoints,_closed = pdb.gimp_vectors_stroke_get_points(vectors,stroke_ids[i])
        index = 1
        while (index*2+1 <= len(controlpoints)):
            #grab just the 2 points of center control point
            pathpoints.append(controlpoints[index*2:index*2+2])
            arrowpoints.append(controlpoints[index*2+2:index*2+4])
            index += 3; #increment by 3 to jump to next center control point
    with open(textfile,"r") as in_file:
        texts = in_file.read().split('\n[breaker]\n')
    for i in range(0,len(texts)):
        text = texts[i]
        number = i+1 #since we're indexing text1, text2, text3 and so on.   
        # new path version
        layer_group = pdb.gimp_layer_group_new(img) #make layer group
        pdb.gimp_image_insert_layer(img,layer_group,None,0)
        pdb.gimp_item_set_name(layer_group,text)

        text_layer = pdb.gimp_text_layer_new(img,text,font,fontsize,0)#Units is either PIXELS(0) POINTS(1)
        pdb.gimp_image_insert_layer(img,text_layer,layer_group,0)
        pdb.gimp_text_layer_set_color(text_layer,fontcolor)
        pdb.gimp_item_set_name(text_layer,'text #'+str(number))
        pdb.plug_in_autocrop_layer(img,text_layer) #auto crop
        x0 = 0; y0 = 0 #default at top left
        ax0 = 0; ay0 = 0 #default of arrow pointing to here
        if i <= len(pathpoints):
            x0 = pathpoints[i][0]
            y0 = pathpoints[i][1]
            pdb.gimp_layer_set_offsets(text_layer,x0,y0)
            ax0 = arrowpoints[i][0]
            ay0 = arrowpoints[i][1]

        bgwidth = text_layer.width + fontsize*2   
        bgheight = text_layer.height + fontsize*2
        bglayer = pdb.gimp_layer_new(img,bgwidth,bgheight,RGBA_IMAGE,"bg #"+str(number),100,LAYER_MODE_NORMAL)
        pdb.gimp_image_insert_layer(img,bglayer,layer_group,1)
        pdb.gimp_layer_set_offsets(bglayer,x0-fontsize,y0-fontsize)
        roundcorner = fontsize/2.0
        pdb.gimp_image_select_round_rectangle(img,CHANNEL_OP_REPLACE,x0-fontsize,y0-fontsize,bgwidth,bgheight,roundcorner,roundcorner)
        pdb.gimp_context_set_foreground(backgroundcolor)
        pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)
       
        mx = x0 + text_layer.width/2.0 #middle of text layer
        my = y0 + text_layer.height/2.0
        xdiff = (ax0 - mx); ydiff = (ay0 - my)
        dist = (xdiff**2.0+ydiff**2.0)**0.5
        scaledxdiff = xdiff/dist * fontsize
        scaledydiff = ydiff/dist * fontsize
        p0x = mx + scaledydiff
        p0y = my - scaledxdiff
        p1x = mx - scaledydiff
        p1y = my + scaledxdiff
        pdb.gimp_layer_resize_to_image_size(bglayer)
        pdb.gimp_image_select_polygon(img,CHANNEL_OP_REPLACE,6,[p0x,p0y,p1x,p1y,ax0,ay0])
        #pdb.gimp_context_set_foreground((255,0,0))
        pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)

        pdb.gimp_selection_none(img)
    pdb.gimp_undo_push_group_end(img)
    #Ensure the updated image is displayed now
    pdb.gimp_displays_flush()

register(
    "python_fu_text_bubble",
    "Puts Text where path is drawn",
    "Puts Text where path is drawn",
    "TT",
    "TT",
    "2023.12.8",
    "A Text Bubble",
    "RGB*",      # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
    [
    #INPUT BEGINS
    (PF_IMAGE, "img", "Image", None),
    (PF_DRAWABLE,   "layer", "Drawable", None),
    (PF_FILENAME, "textfile", "Text File:", 0),
    (PF_FONT, "font", "Font:", "Verdana"),
    (PF_INT, "fontsize", "Font Size:", 20),
    (PF_COLOR, "fontcolor", "Font Color:", (0, 0, 0) ),
    (PF_COLOR, "backgroundcolor","Background Color:",(255,255,255)),
    #INPUT ENDS
    ],
    [],
    text_bubble,
    menu="<Image>/Python-Fu")
main()

Because it puts the texts into layer groups that's named like the text so users can choose to move active layer and move layer groups one at time which will move the text and background as the layer-group is moved.

_________________
TinT


Top
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) Bubble wrap text effect plugin

2

No new posts Attachment(s) Bubble glass e-maps

9

No new posts Attachment(s) GEGL Text Style Collection - plugin with many fancy text styles

14

No new posts Attachment(s) manipulate a portion of text inside a text layer using python-fu

2

No new posts script to load text file and create text layer

6



* Login  



Powered by phpBB3 © phpBB Group