2024-11-08 21:07:34 +01:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2025-04-15 14:24:15 +02:00
# (C) 2024-2025 Marek Pistorius
2025-02-03 17:42:38 +01:00
# This file is part of gimp-python-fu-removebg .
# gimp-python-fu-removebg 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.
# gimp-python-fu-removebg 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 Xfce-nameday-plugin. If not, see <https://www.gnu.org/licenses/>.
2024-11-08 21:07:34 +01:00
import gi
gi . require_version ( ' Gimp ' , ' 3.0 ' )
from gi . repository import Gimp
gi . require_version ( ' GimpUi ' , ' 3.0 ' )
from gi . repository import GimpUi
from gi . repository import GObject
from gi . repository import GLib
from gi . repository import Gio
gi . require_version ( ' Gtk ' , ' 3.0 ' )
from gi . repository import Gtk
import os , sys , string , tempfile , platform
2024-11-09 15:55:37 +01:00
import subprocess
2024-11-08 21:07:34 +01:00
def N_ ( message ) : return message
def _ ( message ) : return GLib . dgettext ( None , message )
tupleModel = ( " u2net " , " u2net_human_seg " , " u2net_cloth_seg " , " u2netp " , " silueta " , " isnet-general-use " , " isnet-anime " , " sam " , " birefnet-general " , " birefnet-general-lite " , " birefnet-portrait " , " birefnet-dis " , " birefnet-hrsod " , " birefnet-cod " , " birefnet-massive " )
class PythonRemoveBG ( Gimp . PlugIn ) :
## GimpPlugIn virtual methods ##
def do_set_i18n ( self , procname ) :
return True , ' gimp30-python ' , None
def do_query_procedures ( self ) :
return [ ' python-fu-removebg ' ]
def do_create_procedure ( self , name ) :
procedure = Gimp . ImageProcedure . new ( self , name ,
Gimp . PDBProcType . PLUGIN ,
self . removebg , None )
procedure . set_sensitivity_mask ( Gimp . ProcedureSensitivityMask . ALWAYS )
procedure . set_documentation ( _ ( " Remove Background AI " ) ,
_ ( " Remove Background AI " ) ,
name )
procedure . set_menu_label ( _ ( " RemoveBG.. " ) )
2024-11-10 13:37:56 +01:00
procedure . set_attribution ( " MP " ,
2024-11-08 21:07:34 +01:00
" (c) GPL V3.0 or later " ,
2025-03-12 16:11:27 +01:00
" 2024-2025 " )
2024-11-08 21:07:34 +01:00
procedure . add_menu_path ( ' <Image>/Filters/RemoveBG/ ' )
procedure . add_boolean_argument ( " asMask " , " as Mask " , " As mask " , False , GObject . ParamFlags . READWRITE )
procedure . add_boolean_argument ( " AlphaMatting " , " AlphaMatting " , " AlphaMatting " , False , GObject . ParamFlags . READWRITE )
procedure . add_double_argument ( " aeValue " , " aeValue " , " aeValue " , 0 , 100 , 15 , GObject . ParamFlags . READWRITE )
2025-04-15 14:24:15 +02:00
model_choice = Gimp . Choice . new ( )
model_choice . add ( " u2net " , 0 , " u2net " , " " )
model_choice . add ( " u2net_human_seg " , 1 , " u2net_human_seg " , " " )
model_choice . add ( " u2net_cloth_seg " , 2 , " u2net_cloth_seg " , " " )
model_choice . add ( " u2netp " , 3 , " u2netp " , " " )
model_choice . add ( " silueta " , 4 , " silueta " , " " )
model_choice . add ( " isnet-general-use " , 5 , " isnet-general-use " , " " )
model_choice . add ( " isnet-anime " , 6 , " isnet-anime " , " " )
model_choice . add ( " sam " , 7 , " sam " , " " )
model_choice . add ( " birefnet-general " , 8 , " birefnet-general " , " " )
model_choice . add ( " birefnet-cod " , 9 , " birefnet-cod " , " " )
model_choice . add ( " birefnet-massive " , 10 , " birefnet-massive " , " " )
model_choice . add ( " birefnet-portrait " , 11 , " birefnet-portrait " , " " )
model_choice . add ( " birefnet-general-lite " , 12 , " birefnet-general-lite " , " " )
model_choice . add ( " birefnet-hrsod " , 13 , " birefnet-hrsod " , " " )
model_choice . add ( " birefnet-dis " , 14 , " birefnet-dis " , " " )
2024-11-08 21:07:34 +01:00
procedure . add_choice_argument ( " Model " , _ ( " Model " ) ,
2025-04-15 14:24:15 +02:00
_ ( " Model " ) , model__choice ,
2024-11-08 21:07:34 +01:00
" u2net " , GObject . ParamFlags . READWRITE )
return procedure
def removebg ( self , procedure , run_mode , image , drawables , config , run_data ) :
if run_mode == Gimp . RunMode . INTERACTIVE :
GimpUi . init ( ' python-fu-removebg.py ' )
dialog = GimpUi . ProcedureDialog ( procedure = procedure , config = config )
dialog . fill ( None )
if not dialog . run ( ) :
dialog . destroy ( )
return procedure . new_return_values ( Gimp . PDBStatusType . CANCEL , GLib . Error ( ) )
else :
dialog . destroy ( )
AlphaMatting = config . get_property ( ' AlphaMatting ' )
asMask = config . get_property ( ' asMask ' )
2024-11-09 15:55:37 +01:00
selModel = config . get_choice_id ( " Model " )
aeValue = config . get_property ( ' aeValue ' )
2024-11-08 21:07:34 +01:00
removeTmpFile = True
tdir = tempfile . gettempdir ( )
print ( tdir )
2024-11-09 15:55:37 +01:00
jpgFileF = " Temp-gimp-0000.jpg "
jpgFile = os . path . join ( tdir , jpgFileF )
pngFileF = " Temp-gimp-0000.png "
pngFile = os . path . join ( tdir , pngFileF )
2024-11-08 21:07:34 +01:00
x1 = 0
y1 = 0
2024-11-09 15:55:37 +01:00
2024-11-08 21:07:34 +01:00
option = " "
Gimp . context_pop ( )
image . undo_group_start ( )
curLayer = image . get_selected_layers ( )
fileOut = Gio . File . new_for_path ( pngFile )
file = Gio . File . new_for_path ( jpgFile )
f = image . get_file ( )
if curLayer [ 0 ] :
if not file . query_exists ( ) :
file . create ( Gio . FileCreateFlags . REPLACE_DESTINATION , None )
else :
pdb . gimp_edit_copy ( drawable )
non_empty , x1 , y1 , x2 , y2 = pdb . gimp_selection_bounds ( image )
tmpImage = gimp . Image ( x2 - x1 , y2 - y1 , 0 )
tmpDrawable = gimp . Layer ( tmpImage , " Temp " , tmpImage . width , tmpImage . height , RGB_IMAGE , 100 , NORMAL_MODE )
pdb . gimp_image_add_layer ( tmpImage , tmpDrawable , 0 )
pat = pdb . gimp_context_get_pattern ( )
pdb . gimp_context_set_pattern ( " Leopard " )
pdb . gimp_drawable_fill ( tmpDrawable , 4 )
pdb . gimp_context_set_pattern ( pat )
pdb . gimp_floating_sel_anchor ( pdb . gimp_edit_paste ( tmpDrawable , TRUE ) )
pdb . file_jpeg_save ( tmpImage , tmpDrawable , jpgFile , jpgFile , 0.95 , 0 , 1 , 0 , " " , 0 , 1 , 0 , 0 )
pdb . gimp_image_delete ( tmpImage )
aiExe = " C: \\ Program Files (x86) \\ Rembg \\ rembg.exe "
2024-11-09 15:55:37 +01:00
2024-11-08 21:07:34 +01:00
if AlphaMatting :
option = " -a -ae %d " % ( aeValue )
2024-11-09 15:55:37 +01:00
cmd = ' %s i -m %s %s " %s " " %s " ' % ( aiExe , tupleModel [ selModel ] , option , f . get_path ( ) , pngFile )
print ( cmd )
subprocess . run ( cmd )
2024-11-08 21:07:34 +01:00
file_exists = os . path . exists ( pngFile )
if file_exists :
newlayer = Gimp . file_load_layer ( run_mode , image , fileOut )
image . insert_layer ( newlayer , None , - 1 )
file = Gio . File . new_for_path ( pngFile )
newLayer = Gimp . file_load_layer ( run_mode , image , fileOut )
image . insert_layer ( newlayer , None , - 1 )
if asMask :
2024-11-08 21:31:18 +01:00
image . select_item ( Gimp . ChannelOps . REPLACE , newlayer )
2024-11-08 21:07:34 +01:00
image . remove_layer ( newlayer )
2024-11-08 21:31:18 +01:00
copyLayer = Gimp . layer_copy ( curLayer )
image . insert_layer ( copyLayer , None , - 1 )
mask = copyLayer . create_mask ( ADD_SELECTION_MASK )
2024-11-08 21:07:34 +01:00
copyLayer . add_mask ( mask )
2024-11-08 21:31:18 +01:00
Gimp . selection_none ( image )
2024-11-08 21:07:34 +01:00
image . undo_group_end ( )
Gimp . displays_flush ( )
if removeTmpFile :
if file . query_exists ( ) :
file . delete ( )
if fileOut . query_exists ( ) :
fileOut . delete ( )
return procedure . new_return_values ( Gimp . PDBStatusType . SUCCESS , GLib . Error ( ) )
Gimp . main ( PythonRemoveBG . __gtype__ , sys . argv )