minor math error (I scale the image to be 4 times width and 4 times the height before doing work on it) so it should be applied as maxpixels *4 *4.
Here's the fix for that and default should now be 12(threshold) and 25 for maxpixels.
I check to see if it removes the comma and it doesn't so that's a good number.
1. Scale image to be 4 timesx width and height (no interpolation).
2. Select by background color.
3. Turn it into path.
4. Select each stroke and create a path out of that and use histograms to count pixels of selection of path.
5. if it's less then equal to max pixels, fill it with bgcolor.
6. when done, scale back to original size.
#!/usr/bin/env python
# Author: (Tin Tran)
# Created On: 2024-07-10
# Remove only black spots in scanned documents?
# Possible Solution: use logics from http://gimpchat.com/viewtopic.php?f=9&t=14045&p=256687&hilit=DivideTransBG.scm#p256687
# which can divide up transparent background to get alpha shapes. Except this problem is just white
# so we'll let user select background color, threshold, and replace all shapes that have less than minimum allowed pixels
#
# License: Whatever GIMP's License is.
# Revisions:
# Rel 0.10: Initial Version
from gimpfu import *
import random
import math
def remove_dots(image,layer,bgcolor,threshold,maxpixels):
#interpolation none scale image so that dots are preserved when we
#selection to path it
pdb.gimp_image_scale_full(image,image.width*4,image.height*4,0)
pdb.gimp_by_color_select(layer,bgcolor,threshold,CHANNEL_OP_REPLACE,TRUE,FALSE,0,FALSE)
pdb.plug_in_sel2path(image,layer)
active_vectors = pdb.gimp_image_get_active_vectors(image)
num_strokes,stroke_ids = pdb.gimp_vectors_get_strokes(active_vectors)
for i in range(0,len(stroke_ids)):
_type,num_points,controlpoints,closed = pdb.gimp_vectors_stroke_get_points(active_vectors,stroke_ids[i])
new_vectors = pdb.gimp_vectors_new(image,"single vector")
pdb.gimp_image_insert_vectors(image,new_vectors,None,0)
pdb.gimp_vectors_stroke_new_from_points(new_vectors,_type,num_points,controlpoints,closed)
pdb.gimp_image_select_item(image,CHANNEL_OP_REPLACE,new_vectors)
mean,std_dev,median,pixels,count_,percentile = pdb.gimp_histogram(layer,HISTOGRAM_VALUE,0,255)
#if pixel count is less than or equal to our maximum fill it with color
if count_ <= maxpixels*4*4:
pdb.gimp_context_set_foreground(bgcolor)
pdb.gimp_edit_fill(layer,FILL_FOREGROUND)
#remove when done with this one
pdb.gimp_image_remove_vectors(image,new_vectors)
pdb.gimp_selection_none(image)
pdb.gimp_image_scale_full(image,image.width/4,image.height/4,0)
register(
"python_fu_remove_dots",
"remove dots",
"remove dots by filling in with bg color",
"author name",
"copyright name",
"2024.07.10",
"Remove Dots...",
"RGB*", # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
[
#INPUT BEGINS
(PF_IMAGE, "image", "Image", None),
(PF_DRAWABLE, "layer", "Drawable", None),
(PF_COLOR, "bgcolor", "Background Color:", (255, 255, 255) ), # extra param is RGB triple
(PF_SLIDER, "threshold", "Threshold:", 12, (0, 100, 1)),
(PF_SLIDER, "maxpixels", "Maximum No Of Pixels To Fill With BGColor:", 25, (0, 500, 1)),
#INPUT ENDS
],
[],
remove_dots,
menu="<Image>/Python-Fu")
main()
# Below is all the example input types for INPUTS for the plug-in which can be cut and pasted into #INPUT BEGINS section and edited to taste (found online years back that I didn't want to constantly look up)
# Since GIMP is free anyways, I thought it would be handy here for me to CUT and PASTE, CHANGE, USE.
# (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32 similar but no difference in Python.
# (PF_FLOAT, "p02", "_FLOAT:", 3.141),
# (PF_STRING, "p03", "_STRING:", "foo"), # alias PF_VALUE
# (PF_TEXT, "p04", "TEXT:", "bar"),
# # PF_VALUE
# # Pick one from set of choices
# (PF_OPTION,"p1", "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
# (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
# # PF_RADIO is usually called a radio button group.
# # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
# (PF_TOGGLE, "p2", "TOGGLE:", 1), # initially True, checked. Alias PF_BOOL
# # PF_TOGGLE is usually called a checkbox.
# (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
# (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)), # alias PF_ADJUSTMENT
# # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
# (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
# # PF_COLOUR is an alias by aussie PyGimp author lol
# (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
# (PF_FONT, "p17", "FONT:", 0),
# (PF_FILE, "p18", "FILE:", 0),
# (PF_BRUSH, "p19", "BRUSH:", 0),
# (PF_PATTERN, "p20", "PATTERN:", 0),
# (PF_GRADIENT, "p21", "GRADIENT:", 0),
# (PF_PALETTE, "p22", "PALETTE:", 0),
# (PF_LAYER, "p23", "LAYER:", None),
# (PF_CHANNEL, "p24", "CHANNEL:", None), # ??? Usually empty, I don't know why.
# (PF_DRAWABLE, "p25", "DRAWABLE:", None),
# # Mostly undocumented, but work
# (PF_VECTORS, "p26", "VECTORS:", None),
# (PF_FILENAME, "p27", "FILENAME:", 0),
# (PF_DIRNAME, "p28", "DIRNAME:", 0)
# # PF_REGION might work but probably of little use. See gimpfu.py.