I needed to fit some text inside a circle.
After cropping to content, I needed to know the maximum distance (furthest non-transparent pixel) from center of content.
Knowing this distance, I can scale it such that the result fits inside the circle (centered) with the furthest pixel from center at a certain inner radius.
For example if I want the furthest pixel from center of text to be 10% of circle's radius from border.
So, after drawing the above diagram(s), I wrote a function that
sweeps through possible say for example 16 rays from minimum which is half the height of text to maximum which is distance from center to a corner of text.
if it finds a larger distance from center where pixel isn't transparent it sets maximum distance to this value.
At the end, i get maximum distance of pixel furthest from center.
def getmax_nontransparent(layer,jump):
#this function sweeps around the circle starting from center of layer to find
#furthest distance from center that isn't transparent
#meant to be used for scaling logics that requires this max distance from center
sweep_sections = 16.0 #16 lines sweep should be good enough
offsetx,offsety = pdb.gimp_drawable_offsets(layer) #take offsets into account
cx = offsetx + layer.width/2 #center
cy = offsety + layer.height/2
sweep_radius = ((layer.width/2)**2 + (layer.height/2)**2)**0.5 #to corner distance is the max radius that we sweep
start_sweep = min(layer.width,layer.height)/2 #sweep from smaller dimension/2
maxdist = -1
for s in range(0,int(sweep_sections)): #section
angle = 1.0*s/sweep_sections*2.0*math.pi
for r in range(int(start_sweep),int(sweep_radius)): #radius
r += max(jump,1)
px = int(cx + math.cos(angle)*r)
py = int(cy + math.sin(angle)*r)
if px >=0 and px < layer.width and py >=0 and py < layer.height:
num_channels,pixel = pdb.gimp_drawable_get_pixel(layer,px,py)
if pixel[3]>0: #non transparent
if r > maxdist:
maxdist = r
return maxdist
this function takes a layer of content and a jump value (jump will tell it to jump by how many pixels while it's sweeping so that we can make the function faster by setting a jump value greater than 0 but it'll also be less accurate).
The above is a version that was used when I first wrote it.
The below is revised version which is about 10 times faster than previous version.
What could take previous version 3.137 seconds now takes 0.368 of a second with the below version.
def getmax_nontransparent(layer,jump):
#this function sweeps around the circle starting from center of layer to find
#furthest distance from center that isn't transparent
#meant to be used for scaling logics that requires this max distance from center
sweep_sections = 16.0 #16 lines sweep should be good enough
offsetx,offsety = pdb.gimp_drawable_offsets(layer) #take offsets into account
cx = offsetx + layer.width/2 #center
cy = offsety + layer.height/2
sweep_radius = ((layer.width/2)**2 + (layer.height/2)**2)**0.5 #to corner distance is the max radius that we sweep
start_sweep = min(layer.width,layer.height)/2 #sweep from smaller dimension/2
maxdist = -1
angle = 0
incangle = math.pi*2.0/sweep_sections #use to to add for speed
layerwidth = layer.width
layerheight = layer.height
for s in range(0,int(sweep_sections)): #section
#angle += 1.0*s/sweep_sections*2.0*math.pi
angle += incangle
cos_angle = math.cos(angle) #for speed do this once outside of loop
sin_angle = math.sin(angle)
for r in range(int(start_sweep),int(sweep_radius)): #radius
r += max(jump,0)
px = int(cx + cos_angle*r)
py = int(cy + sin_angle*r)
if px >=0 and px < layerwidth and py >=0 and py < layerheight:
#num_channels,pixel = pdb.gimp_drawable_get_pixel(layer,px,py)
pixel = layer.get_pixel(px,py)
if pixel[3]>0: #non transparent
if r > maxdist:
maxdist = r
return maxdist