#!/usr/bin/env python # -*- coding: utf-8 -*- # # python High Pass Sharpen # version-1.2 01/04/2010 # Copyright (c) 2008-2010 Paul Sherman # inspired by layerfx.py by Jonathan Stipe # and the high-pass-sharpen.scm by Martin Egger # # Impliments a preview/undo on active image so that # plugin does not need to be restarted when testing effect. # -------------------------------------------------------------------- # for use on Linux - # make sure the installed script is set to EXECUTABLE # usual location is /usr/lib/gimp/2.0/plug-ins # also have tosrestat gimp if running before installation... # -------------------------------------------------------------------- # # 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 . # --------------------------------------------------------------------- import gimp, gimpplugin, math from gimpenums import * pdb = gimp.pdb import gtk, gimpui, gimpcolor from gimpshelf import shelf class reuse_init(object): previewLayer = None def get_layer_pos(self, layer): i = 0 while i < len(self.img.layers): if layer == self.img.layers[i]: return i else: i += 1 return -1 def layer_exists(self, layer): return layer != None and layer in self.img.layers def removePreviews(self): if self.layer_exists(self.previewLayer): self.img.remove_layer(self.previewLayer) self.previewLayer = None gimp.displays_flush() def make_label(self, text): label = gtk.Label(text) label.set_use_underline(True) label.set_alignment(1.0, 0.5) label.show() return label def make_slider_and_spinner(self, init, min, max, step, page, digits): controls = {'adj':gtk.Adjustment(init, min, max, step, page), 'slider':gtk.HScale(), 'spinner':gtk.SpinButton()} controls['slider'].set_adjustment(controls['adj']) controls['slider'].set_draw_value(False) controls['spinner'].set_adjustment(controls['adj']) controls['spinner'].set_digits(digits) controls['slider'].show() controls['spinner'].show() return controls def show_error_msg(self, msg): origMsgHandler = pdb.gimp_message_get_handler() pdb.gimp_message_set_handler(ERROR_CONSOLE) pdb.gimp_message(msg) pdb.gimp_message_set_handler(origMsgHandler) def stringToColor(self, string): colorlist = string[5:-1].split(", ") return gimpcolor.RGB(float(colorlist[0]), float(colorlist[1]), float(colorlist[2]), float(colorlist[3])) class high_end_sharpen(reuse_init): def __init__(self, runmode, img, drawable, strength, flatten): self.img = img self.drawable = drawable self.shelfkey = 'layerfx-drop-shadow' self.showDialog() def showDialog(self): self.dialog = gimpui.Dialog("High End Sharpen", "highenddialog") self.table = gtk.Table(3, 3, True) self.table.set_homogeneous(False) self.table.set_row_spacings(8) self.table.set_col_spacings(8) self.table.show() self.distance_label = self.make_label("Strength:") self.table.attach(self.distance_label, 0, 1, 1, 2) self.strength_spinner = self.make_slider_and_spinner(10.0, 1.0, 20.0, 1.0, 10.0, 1) self.strength_spinner['adj'].set_value(10.0) self.distance_label.set_mnemonic_widget(self.strength_spinner['spinner']) self.table.attach(self.strength_spinner['slider'], 1, 2, 1, 2) self.table.attach(self.strength_spinner['spinner'], 2, 3, 1, 2) self.flatten_check = gtk.CheckButton("Flatten layer when complete") self.flatten_check.show() self.table.attach(self.flatten_check, 3, 4, 1, 2) self.dialog.vbox.hbox1 = gtk.HBox(False, 7) self.dialog.vbox.hbox1.show() self.dialog.vbox.pack_start(self.dialog.vbox.hbox1, True, True, 7) self.dialog.vbox.hbox1.pack_start(self.table, True, True, 7) reset_button = gtk.Button("_Reset") reset_button.connect("clicked", self.resetbutton) reset_button.show() self.preview_button = gtk.Button("Preview") self.preview_button.connect("clicked", self.preview) self.preview_button.set_size_request(100, -1) self.preview_button.show() if gtk.alternative_dialog_button_order(): ok_button = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) cancel_button = self.dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.dialog.action_area.add(reset_button) self.dialog.action_area.add(self.preview_button) else: self.dialog.action_area.add(self.preview_button) self.dialog.action_area.add(reset_button) cancel_button = self.dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) ok_button = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) ok_button.connect("clicked", self.okbutton) self.dialog.show() self.dialog.run() self.removePreviews() def okbutton(self, widget): # remove old preview layer if it exists if self.layer_exists(self.previewLayer): self.img.remove_layer(self.previewLayer) self.previewLayer = None # get values of the settings strength = self.strength_spinner['adj'].get_value() if self.flatten_check.get_active(): flatten = 1 else: flatten = 0 # then build new layer with current settings to actually impliment... # the True value at the end means it is a Final layer sent to "makeLayer" # hence it will flatten image if this is chosen (previews will not) fxlayer = self.makeLayer(self.img, self.drawable, strength, flatten, True) def resetbutton(self, widget): self.strength_spinner['adj'].set_value(10.0) self.flatten_check.set_active(True) def preview(self, widget): ptxt = self.preview_button.get_label() if self.layer_exists(self.previewLayer): self.img.remove_layer(self.previewLayer) gimp.displays_flush() else: self.previewLayer = self.makeLayer(self.img, self.drawable, self.strength_spinner['adj'].get_value(),1) if ptxt == "Preview": ptxt = "Undo Preview" else: ptxt = "Preview" self.preview_button.set_label(ptxt) def makeLayer(self, img, drawable, strength, flatten, final = False): pdb.gimp_image_undo_group_start(img) origselection = pdb.gimp_selection_save(img) tmpLayer1 = pdb.gimp_layer_copy(drawable, True) tmpLayer2 = pdb.gimp_layer_copy(drawable, True) pdb.gimp_image_add_layer(img, tmpLayer1, -1) pdb.gimp_image_add_layer(img, tmpLayer2, -1) pdb.plug_in_gauss(img, tmpLayer2, strength, strength, 0) pdb.gimp_invert(tmpLayer2) pdb.gimp_layer_set_opacity(tmpLayer2, 50) InOpacity = ((strength * 2.5) + 25) shadow = pdb.gimp_image_merge_down(img, tmpLayer2, 1) shadow.name = drawable.name + " shadow" shadow.lock_alpha = False pdb.gimp_levels(shadow, HISTOGRAM_VALUE, 100, 150, 1.0, 0, 255) pdb.gimp_layer_set_mode(shadow,OVERLAY_MODE) pdb.gimp_layer_set_opacity(shadow, InOpacity) if final and flatten: pdb.gimp_image_flatten(img) gimp.displays_flush() pdb.gimp_image_undo_group_end(img) return shadow class pyHighEnd(gimpplugin.plugin): def start(self): gimp.main(self.init, self.quit, self.query, self._run) def init(self): pass def quit(self): pass def query(self): authorname = "Paul Sherman" copyrightname = "Paul Sherman" menu_location = "/Script-Fu/Sharpness/Sharper/High-Sharpen with Preview" date = "July 2008" plug_description = "Sharpens high-end of image." plug_help = "Sharpens high-end of image." plug_params = [ (PDB_INT32, "run_mode", "Run mode"), (PDB_IMAGE, "image", "Input image"), (PDB_DRAWABLE, "drawable", "Input drawable"), ####### 3 params above needed by all scripts using gimpplugin.plugin ###################### (PDB_FLOAT, "strength", "The strength of the sharpen procedure on scale of 1-to-20"), (PDB_INT32, "flatten", "Flatten when complete (TRUE or FALSE)")] gimp.install_procedure("py_high_end_sharpen", plug_description, plug_help, authorname, copyrightname, date, menu_location, "RGB*, GRAY*", PLUGIN, plug_params, []) def py_high_end_sharpen(self, runmode, img, drawable, strength = 10.0, flatten = 0): high_end_sharpen(runmode, img, drawable, strength, flatten) if __name__ == '__main__': pyHighEnd().start()