Created
May 14, 2023 04:11
-
-
Save JacquesDuflos/0a4914099d497631cff9211737e2f24f to your computer and use it in GitHub Desktop.
a plug-in for python that draws a path around a text.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# GIMP plugin to draw convex hulls around shapes | |
# (c) Jacques Duflos 2023 | |
# | |
# History: | |
# | |
# v0.0: 2023-xx-xx: First published version | |
# This program is free software; you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software | |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
#credit https://gist.github.com/lvngd for the ConvexHull class | |
import random | |
import sys, os | |
from gimpfu import * | |
import gimpcolor | |
""" | |
Computes the Convex Hull with the Graham Scan algorithm | |
Use: | |
h = ConvexHull() | |
print(h.hull) | |
""" | |
debug = True | |
def trace(s): | |
if debug: | |
print "**** " | |
print s | |
print "**** " | |
trace("convex_hull test") | |
class ConvexHull: | |
def __init__(self, points): | |
if not points: | |
self.points = [(random.randint(0,100),random.randint(0,100)) for i in range(50)] | |
else: | |
self.points = points | |
self.hull = self.compute_convex_hull() | |
def get_cross_product(self,p1, p2, p3): | |
return ((p2[0] - p1[0])*(p3[1] - p1[1])) - ((p2[1] - p1[1])*(p3[0] - p1[0])) | |
def get_slope(self,p1, p2): | |
if p1[0] == p2[0]: | |
return float('inf') | |
else: | |
return 1.0*(p1[1]-p2[1])/(p1[0]-p2[0]) | |
def compute_convex_hull(self): | |
hull = [] | |
self.points.sort(key=lambda x:[x[0],x[1]]) | |
start = self.points.pop(0) | |
hull.append(start) | |
self.points.sort(key=lambda p: (self.get_slope(p,start), -p[1],p[0])) | |
for pt in self.points: | |
hull.append(pt) | |
while len(hull) > 2 and self.get_cross_product(hull[-3],hull[-2],hull[-1]) < 0: | |
hull.pop(-2) | |
return hull | |
def PointsFromVectors(vectors): | |
num_strokes, ids = pdb.gimp_vectors_get_strokes(vectors) | |
listOfPoints = [] | |
for stroke_id in ids: | |
type_, num_points, controlpoints, closed = pdb.gimp_vectors_stroke_get_points(vectors, stroke_id) | |
listOfPoints += controlpoints | |
trace(listOfPoints) | |
return listOfPoints | |
def ConvexHullVectors(image,vectors=None): | |
if vectors == None : vectors = pdb.gimp_image_get_active_vectors(image) | |
# get the list of every points of the vectors's stroke | |
listOfPoints = PointsFromVectors(vectors) | |
# organize the list to be compatible with the class | |
listOfPointsTupple=[] | |
while len(listOfPoints)>1: | |
listOfPointsTupple.append((listOfPoints.pop(0),listOfPoints.pop(0))) | |
trace ("list") | |
trace (listOfPointsTupple) | |
listOfPointsTupple = list(dict.fromkeys(listOfPointsTupple)) | |
# todo : delet at once the duplicated consecutive points (when tengents are superposed with the point) | |
trace("list sans doublons") | |
trace(listOfPointsTupple) | |
h = ConvexHull(listOfPointsTupple) | |
trace ("convex hull") | |
trace (h.hull) | |
hull=h.hull | |
#triple each element to get a list with tengants | |
hull = [[i,i,i] for i in hull] | |
trace(hull) | |
hull = [item for sublist in hull for item in sublist] | |
trace(hull) | |
#flatten the hull to be easyer tu use with gimp | |
hullFlattened = [item for sublist in hull for item in sublist] | |
trace ("flattened") | |
trace (hullFlattened) | |
#create the new vector | |
hullVectors = pdb.gimp_vectors_new(image, "convex hull") | |
stroke_id = pdb.gimp_vectors_stroke_new_from_points(hullVectors, VECTORS_STROKE_TYPE_BEZIER , len(hullFlattened), hullFlattened, True) | |
pdb.gimp_image_insert_vectors(image, hullVectors, None, 0) | |
trace ("fini") | |
return hullVectors | |
def ConvexHullText(image,layer): | |
vectorsText = pdb.gimp_vectors_new_from_text_layer(image, layer) | |
ConvexHullVectors(image,vectorsText) | |
### Registrations | |
whoiam='\n'+os.path.abspath(sys.argv[0]) | |
register( | |
'convex-hull', | |
'creer un convex hull autour d un texte %s' % whoiam, | |
'creer un convex hull autour d un texte', | |
'Jacques Duflos','Jacques Duflos','2023', | |
'creer un convex hull autour d un texte...', | |
'*', | |
[ | |
(PF_IMAGE, 'image', 'Image', None), | |
(PF_DRAWABLE, 'drawable', 'Drawable', None) | |
], | |
[], | |
ConvexHullText, | |
menu='<Image>/Layer' | |
) | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment