Initial commit
This commit is contained in:
commit
a2681d2a22
21
README.md
Normal file
21
README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# gimp-xsanecli
|
||||
|
||||
GIMP 3.0 plug-in for scanning via XSane
|
||||
|
||||
Uses XSane via CLI rather than requiring XSane to be compiled with GIMP support (which is currently unavailable for GIMP 3.0)
|
||||
|
||||
## Usage
|
||||
|
||||
gimp-xsanecli has only been tested on Linux. It requires [xsane](http://www.xsane.org/) to be installed, and the *xsane* command to be available on PATH.
|
||||
|
||||
Install *xsanecli.py* to *$HOME/.config/GIMP/3.0/plug-ins/xsanecli/xsanecli.py* and ensure that *xsanecli.py* is executable.
|
||||
|
||||
Click *File* → *Create* → *XSane via CLI…*.
|
||||
|
||||
By default, XSane's device chooser dialog is displayed. To hard-code a specific device, set *DEVICE_NAME* in *xsanecli.py* (e.g. `DEVICE_NAME = 'escl:http://10.0.0.1:80'`).
|
||||
|
||||
## Licence
|
||||
|
||||
Copyright © 2024 Lee Yingtong Li (RunasSudo)
|
||||
|
||||
Licensed under the GNU General Public License version 3 or later.
|
90
xsanecli.py
Executable file
90
xsanecli.py
Executable file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# GIMP 3.0 plug-in for scanning via XSane
|
||||
# Copyright (C) 2024 Lee Yingtong Li (RunasSudo)
|
||||
#
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import gi
|
||||
gi.require_version('Gimp', '3.0')
|
||||
from gi.repository import Gimp
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
DEVICE_NAME = None # e.g. DEVICE_NAME = 'escl:http://10.0.0.1:80'
|
||||
|
||||
def xsanecli_run(procedure, config, run_data, *args):
|
||||
# Get temporary directory
|
||||
tempdir = tempfile.mkdtemp('gimp-plugin-xsanecli')
|
||||
png_out = os.path.join(tempdir, 'out.png')
|
||||
|
||||
# Open XSane
|
||||
args = ['xsane', '--save', '--no-mode-selection', '--force-filename', png_out, '--print-filenames'] + ([DEVICE_NAME] if DEVICE_NAME else [])
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE, encoding='utf-8')
|
||||
|
||||
# Wait until XSane prints the name of the scanned file, indicating scanning is finished
|
||||
# This blocks Python but that is ok because GIMP UI is not affected
|
||||
result = proc.stdout.readline().strip()
|
||||
|
||||
proc.terminate()
|
||||
|
||||
if result == '':
|
||||
# XSane was closed
|
||||
return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.CANCEL)])
|
||||
|
||||
if result != 'XSANE_IMAGE_FILENAME: ' + png_out:
|
||||
Gimp.message('Unexpected XSane result')
|
||||
return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.EXECUTION_ERROR)])
|
||||
|
||||
# Open image
|
||||
image = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, Gio.File.new_for_path(png_out))
|
||||
Gimp.Display.new(image)
|
||||
|
||||
# Remove temporary files
|
||||
os.unlink(png_out)
|
||||
os.rmdir(tempdir)
|
||||
|
||||
return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS), GObject.Value(Gimp.Image.__gtype__, image)])
|
||||
|
||||
class XSaneCLI(Gimp.PlugIn):
|
||||
## GimpPlugIn virtual methods ##
|
||||
def do_set_i18n(self, procname):
|
||||
return False
|
||||
|
||||
def do_query_procedures(self):
|
||||
return ['plug-in-xsanecli']
|
||||
|
||||
def do_create_procedure(self, name):
|
||||
if name == 'plug-in-xsanecli':
|
||||
procedure = Gimp.Procedure.new(self, name, Gimp.PDBProcType.PLUGIN, xsanecli_run, None, None)
|
||||
procedure.set_menu_label('_XSane via CLI...')
|
||||
procedure.add_menu_path('<Image>/File/Create')
|
||||
procedure.add_enum_argument('run-mode', 'Run mode', 'The run mode', Gimp.RunMode.__gtype__, Gimp.RunMode.NONINTERACTIVE, GObject.ParamFlags.READWRITE)
|
||||
procedure.add_image_return_value('image', 'Image', 'Output image', False, GObject.ParamFlags.READWRITE)
|
||||
else:
|
||||
raise Exception('Unknown procedure')
|
||||
|
||||
procedure.set_attribution(
|
||||
'Lee Yingtong Li (RunasSudo)', # Author
|
||||
'Lee Yingtong Li (RunasSudo)', # Copyright
|
||||
'Lee Yingtong Li (RunasSudo)' # Year
|
||||
)
|
||||
return procedure
|
||||
|
||||
Gimp.main(XSaneCLI.__gtype__, sys.argv)
|
Loading…
Reference in New Issue
Block a user