本來這個blog是記錄開發輸入法的點滴的,後來越來越雜,現在什麼都記錄了。

2014年9月14日 星期日

GIMP reverse curve-bend

This example shows how to curve-bend an label stuck on a cylindrical surface to rectangular area.

  1. Save the following Python-fu script to C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\my_curve_bend.py
    (Assume GIMP is installed in C:\Program Files\GIMP 2)
    Note that the pdb.plug_in_curve_bend() is used.

  2. Open the sample label in GIMP.


  3. Goto Menu Windows -> New Toolbar. Double click the "Path" toolbar


  4. Draw a upper path along the curved surface. Please use maximum 16 segments.
    (Note you can use Ctrl + Mouse scroll to zoom-in)


  5. Press the Shift key to start a new path segment.
    Draw a lower path along the curved surface. Please use maximum 16 segments.


  6. Start the bending by go to Menu Python-fu -> My curve bend.
    Here is the result:


  7. You can hide away / delete other layers by: Menu Windows -> Dockable Dialogue -> Layers
    And delete the layers


  8. The original image layer was removed. Note the red line showing the original
    image was bent according to mirror of the upper and lower path.


  9. The image was cropped and the result image:
    ->

my_curve_bend.py
#!/usr/bin/env python

from gimpfu import *
from array import array

def my_curve_bend(image, drawable) :
    pdb.gimp_message('my_curve_bend')

    # Please plot the upper path from left to right.
    # then press shift
    # then plot the lower path from left to right.
    cur_image = gimp.image_list()[0];
    cur_layer = cur_image.layers[0];
    
    # get the points of upper path and lower paths.
    # Note that: with gimp_vectors_stroke_get_points, the vectors has control points, center and control points.
    # some code is added to extract only the center points.
    active_vectors = pdb.gimp_image_get_active_vectors(cur_image)
    nstrokes, strokes = pdb.gimp_vectors_get_strokes(active_vectors)
    upper_type, upper_num_points, upper_controlpoints, upper_closed = pdb.gimp_vectors_stroke_get_points(active_vectors, strokes[0])
    lower_type, lower_num_points, lower_controlpoints, lower_closed = pdb.gimp_vectors_stroke_get_points(active_vectors, strokes[1])

    upper_point_x_s = array('d', [])
    for i in xrange(2,len(upper_controlpoints),6):
      upper_point_x_s.append(upper_controlpoints[i])
    
    upper_point_y_s = array('d', [])
    for i in xrange(3,len(upper_controlpoints),6):
      upper_point_y_s.append(upper_controlpoints[i])
    
    lower_point_x_s = array('d', [])
    for i in xrange(2,len(lower_controlpoints),6):
      lower_point_x_s.append(lower_controlpoints[i])
    
    lower_point_y_s = array('d', [])
    for i in xrange(3,len(lower_controlpoints),6):
      lower_point_y_s.append(lower_controlpoints[i])
    
    # calculate the bounding rectangle and make selection
    top_l_x = upper_point_x_s[0];
    top_l_y = upper_point_y_s[0];
    top_r_x = upper_point_x_s[len(upper_point_x_s)-1];
    top_r_y = upper_point_y_s[len(upper_point_y_s)-1];
    btm_l_x = lower_point_x_s[0];
    btm_l_y = lower_point_y_s[0];
    btm_r_x = lower_point_x_s[len(lower_point_x_s)-1];
    btm_r_y = lower_point_y_s[len(lower_point_y_s)-1];
    
    bb_x = min(upper_point_x_s + lower_point_x_s)
    bb_y = min(upper_point_y_s + lower_point_y_s)
    bb_w = max(upper_point_x_s + lower_point_x_s) - bb_x
    bb_h = max(upper_point_y_s + lower_point_y_s) - bb_y
    
    pdb.gimp_rect_select(
        cur_image, # image           \
        bb_x,      # x               \
        bb_y,      # y               \
        bb_w,      # width           \
        bb_h,      # height          \
        0,         # operation       \
        0,         # feather         \
        0          # feather_radius  \
    )

    # calculate the bending curve mirrored.
    top_avg_y = (top_l_y + top_r_y)/2.0
    btm_avg_y = (btm_l_y + btm_r_y)/2.0
    
    top_len = (top_r_x - top_l_x)
    btm_len = (btm_r_x - btm_l_x)
    
    upper_point_x_s_final = [ (x - top_l_x) / top_len for x in upper_point_x_s]
    upper_point_y_s_final = [ 0.5 + ((y-top_avg_y) / (1.0 * top_len)) for y in upper_point_y_s]
    
    lower_point_x_s_final = [ (x - btm_l_x) / btm_len for x in lower_point_x_s]
    lower_point_y_s_final = [ 0.5 + ((y-btm_avg_y) / (1.0 * btm_len)) for y in lower_point_y_s]
    
    upper_val_y_s = array('b', [])
    lower_val_y_s = array('b', [])
    
    bent_layer = pdb.plug_in_curve_bend(\
          cur_image                  # image               \
        , cur_layer                  # drawable            \
        , 0.0                        # rotation            \
        , TRUE                       # smoothing           \
        , TRUE                       # antialias           \
        , TRUE                       # work_on_copy        \
        , 0                          # curve_type          \
        , len(upper_point_x_s_final) # argc_upper_point_x  \
        , upper_point_x_s_final      # upper_point_x       \
        , len(upper_point_y_s_final) # argc_upper_point_y  \
        , upper_point_y_s_final      # upper_point_y       \
        , len(lower_point_x_s_final) # argc_lower_point_x  \
        , lower_point_x_s_final      # lower_point_x       \
        , len(lower_point_y_s_final) # argc_lower_point_y  \
        , lower_point_y_s_final      # lower_point_y       \
        , len(upper_val_y_s)         # argc_upper_val_y    \
        , upper_val_y_s              # upper_val_y         \
        , len(lower_val_y_s)         # argc_lower_val_y    \
        , lower_val_y_s              # lower_val_y         \
    );
    
    pdb.gimp_layer_set_visible(bent_layer, TRUE)

    return

# This is the plugin registration function
# I have written each of its parameters on a different line
register(
    #Your plugin's main function name, as it will be found in Gimp's Procedure Browser.
    #This means that your plugin will be callable by other plugins, using this function
    #name (even by a script in a another language)!
    "my_curve_bend",    

    #Your plugin's "documentation" name, as it will also appears in the Procedure Browser.
    #This name should describe your plugin briefly.
    "My Curve Bend Python-Fu",  

    #Plugin's help. Here you should explain in a more detailed manner what kind of function
    #your plugin provides.
    "This script does the reverse of curve bending",

    #The name of the author of this plugin
    "Y Lam",

    #Any copyright information needed
    "Y Lam",

    #The date this version of the plugin was released
    "Sep 2014",

    #The path in the menu where your plugin should be found
    "<Image>/Python-Fu/My Curve Bend",

    #The image types supported by your plugin
    "*",

    #The list of the parameters needed by your plugin
    [],

    #The results sent back by your plugin
    [],

    #The name of the local function to run to actually start processing, which will be called with a set of parameters.
    my_curve_bend,
    )

main()

沒有留言: