class ImageParadise::GUI::Gtk::ImageEditor
Constants
- CLOCKWISE_ROTATION_SYMBOL
#¶ ↑
CLOCKWISE_ROTATION_SYMBOL
¶ ↑#¶ ↑
- HEIGHT
#¶ ↑
HEIGHT
¶ ↑#¶ ↑
- HINT_FOR_BUTTON_OPEN_THE_IMAGE_IN_THE_BROWSER
#¶ ↑
HINT_FOR_BUTTON_OPEN_THE_IMAGE_IN_THE_BROWSER
¶ ↑#¶ ↑
- HINT_FOR_BUTTON_UNDO
#¶ ↑
HINT_FOR_BUTTON_UNDO
¶ ↑#¶ ↑
- HINT_MAGIC_CARD_CORNER
#¶ ↑
HINT_MAGIC_CARD_CORNER
¶ ↑#¶ ↑
- HINT_MESSAGE_FOR_ROTATING_THE_IMAGE
#¶ ↑
HINT_MESSAGE_FOR_ROTATING_THE_IMAGE
¶ ↑#¶ ↑
- NAMESPACE
#¶ ↑
NAMESPACE
¶ ↑#¶ ↑
- SMALLER_FONT
#¶ ↑
SMALLER_FONT
¶ ↑#¶ ↑
- TITLE
#¶ ↑
TITLE
¶ ↑#¶ ↑
- USE_THIS_FONT
#¶ ↑
USE_THIS_FONT
¶ ↑#¶ ↑
- WIDTH
#¶ ↑
WIDTH
¶ ↑#¶ ↑
Public Class Methods
#¶ ↑
ImageParadise::GUI::Gtk::ImageEditor.run
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1987 def self.run( i = ARGV ) require 'gtk_paradise/app/app.rb' _ = ::ImageParadise::GUI::Gtk::ImageEditor.new(i) r = ::Gtk.run r << _ r.automatic_size_then_automatic_title r.enable_quick_exit r.top_left_then_run end
Public Instance Methods
#¶ ↑
connect_skeleton
(connect tag)¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/connect_skeleton.rb, line 20 def connect_skeleton abort_on_exception most_outer_vbox = gtk_vbox vbox1 = gtk_vbox vbox1.minimal(@button_flip_the_image, 2) vbox1.minimal(@button_greyscale_this_image, 2) vbox1.minimal(@button_make_the_image_transparent, 2) vbox1.minimal(@button_negate, 2) vbox1.minimal(@button_create_drop_shadow_effect, 2) @button_box1.minimal(vbox1, 2) vbox2 = gtk_vbox vbox2.minimal(@button_circle_mask, 2) vbox2.minimal(@button_torn_paper_effect, 2) vbox2.minimal(@button_shadow_effect, 2) vbox2.minimal(@button_chop_away_n_pixel, 2) vbox2.minimal(@button_blur, 2) @button_box1.minimal(vbox2, 2) @button_box1.minimal(return_vbox_containing_the_round_the_corner_button_and_other_buttons, 2) @button_box1.minimal(return_vbox_containing_the_colour_filled_image_button_and_other_buttons, 2) @button_box1.minimal(return_widget_with_more_buttons_starting_with_the_sharpen_button, 2) @button_box1.minimal(return_the_widget_containing_the_button_create_border, 2) mini_vbox = gtk_vbox mini_vbox.minimal(return_widget_containing_the_write_text_functionality, 2) # ======================================================================= # # Next add this tiny vbox widget: # ======================================================================= # @button_box1.minimal(mini_vbox, 0) @box_for_the_main_image.maximal(@work_on_this_image) @box_for_the_main_image.css_class('pad10px') # ======================================================================= # # Create the scrolled-window for our main image next. # ======================================================================= # create_the_scrolled_window_and_associated_event_box_for_the_box_for_the_main_image most_outer_vbox.minimal(@header_bar, 2) # ======================================================================= # # Next we will create the vbox that holds the widget containing # information about the image. # ======================================================================= # vbox_containing_info_and_tool_buttons = gtk_vbox vbox_containing_info_and_tool_buttons.minimal( return_widget_containing_information_about_an_image, 1) vbox_containing_info_and_tool_buttons.minimal( return_widget_containing_the_undo_button, 1) vbox_containing_info_and_tool_buttons.minimal( @spin_button_for_the_first_argument, 1) vbox_containing_info_and_tool_buttons.minimal( @spin_button_for_the_second_argument, 1) vbox_containing_info_and_tool_buttons.minimal( @button_colour_button, 1) pane_top_to_bottom1 = gtk_top_to_bottom_pane( vbox_containing_info_and_tool_buttons, @scrolled_window_for_the_box_for_the_main_image ) pane_top_to_bottom1.position = (width? - 1420) hbox_resize_the_image_and_entry = gtk_hbox hbox_resize_the_image_and_entry.minimal(@button_resize_the_image, 2) @entry_rotate_n_percent = entry('50') @spin_button_percentage_value = gtk_spin_button(1, 250, 1) @spin_button_percentage_value.to_the_middle @spin_button_percentage_value.start_value = 50 @spin_button_percentage_value.on_changed { # On changed, sync it with the entry below. _ = @spin_button_percentage_value.text?.to_s @entry_rotate_n_percent.set_text(_) } @entry_rotate_n_percent.hint = 'This says how '\ 'much to shrink or increase the image-size, '\ 'in <b>percent</b>.' hbox_resize_the_image_and_entry.minimal(@entry_rotate_n_percent, 2) @entry_rotate_n_percent.center @entry_rotate_n_percent.width_height(48, 18) hbox_resize_the_image_and_entry.minimal(text('%'), 2) hbox_resize_the_image_and_entry.minimal(@spin_button_percentage_value, 2) @button_box2.minimal(return_rotate_the_image_widget, 2) @button_box2.minimal(return_the_widget_containing_the_crop_button_and_the_associated_entries, 2) @button_box2.minimal(return_draw_rectangle_widget, 2) @button_box2.minimal(return_the_widget_containing_the_draw_line_functionality, 2) @button_box2.minimal(hbox_resize_the_image_and_entry, 2) vbox = gtk_vbox vbox.minimal(@button_box1, 2) # This contains e. g. the "flip horizontally" button. vbox.minimal(@button_box2, 2) _ = gtk_vbox _.minimal(pane_top_to_bottom1, 2) _.minimal(return_hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box, 2) left_to_right_pane = gtk_left_to_right_pane(_, vbox) # ======================================================================= # # Next add the left-to-right pane that will contain the image that we # may modify. # ======================================================================= # most_outer_vbox.minimal(left_to_right_pane) # ======================================================================= # # Embed this all into a scrolling-window next: # ======================================================================= # scrolled_window = gtk_scrolled_window(most_outer_vbox) { :only_top_to_bottom } scrolled_window.width_height(480, 480) maximal(scrolled_window) end
#¶ ↑
create_the_entries
(entries tag, entry tag)¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1323 def create_the_entries( length_of_the_selection = 300 ) # ======================================================================= # # === @entry_work_on_the_following_image # # This entry contains the path to our current image. # ======================================================================= # @entry_work_on_the_following_image = gtk_entry @entry_work_on_the_following_image.set_max_length(150) @entry_work_on_the_following_image.center @entry_work_on_the_following_image.yellow_background @entry_work_on_the_following_image.read_only @entry_work_on_the_following_image.select_region(0, 1) @entry_work_on_the_following_image.css_class('border_steelblue_2px') @entry_work_on_the_following_image.on_enter_key { _ = @entry_work_on_the_following_image.text? if _ and File.exist?(_) this_file_is_the_new_image_file(_) end } @entry_work_on_the_following_image.make_scrollable @entry_work_on_the_following_image.on_scrolled {|widget, event| _ = widget.text? if scroll_up_event?(event) and !_.empty? and _.include?('.') and _.include?('/') # =================================================================== # # Scroll-up event: # =================================================================== # try_to_assign_a_new_random_image_from_the_base_directory_of_entry_work_on_the_following_image elsif scroll_down_event?(event) and !_.empty? and _.include?('.') and _.include?('/') # =================================================================== # # Scroll-down event: # =================================================================== # try_to_assign_a_new_random_image_from_the_base_directory_of_entry_work_on_the_following_image end } # ======================================================================= # # === @entry_rotate_by_n_degrees # # This is the entry associated with the rotate-image functionality. # ======================================================================= # @entry_rotate_by_n_degrees = gtk_entry('+90') @entry_rotate_by_n_degrees.on_enter { do_rotate_the_image } @entry_rotate_by_n_degrees.hint = 'Rotate by n degrees. You can use '\ 'leading + or - to indicate forward-rotation or backwards '\ 'rotation. Forward rotation means clock-wise rotation. Backwards '\ 'rotation refers to counter-clock-wise rotation.' @entry_rotate_by_n_degrees.center @entry_crop1 = gtk_entry(length_of_the_selection.to_s) {{ max_length: 8 }} @entry_crop1.center @entry_crop1.hint = 'Width of the new image' @entry_crop2 = gtk_entry(length_of_the_selection.to_s) {{ max_length: 8 }} @entry_crop2.center @entry_crop2.hint = 'Height of the new image' @entry_crop3 = gtk_entry('15') {{ max_length: 8 }} @entry_crop3.center @entry_crop3.hint = 'Left-start of the crop-rectangle' @entry_crop4 = gtk_entry('15') {{ max_length: 8 }} @entry_crop4.center @entry_crop4.hint = 'Right-start of the crop-rectangle' @entry_rectangle_start_position1 = gtk_entry('0') @entry_rectangle_start_position1.center @entry_rectangle_start_position1.hint = 'start-position of the x-axis' @entry_rectangle_start_position2 = gtk_entry('0') @entry_rectangle_start_position2.center @entry_rectangle_start_position2.hint = 'start-position of the y-axis' @entry_rectangle_start_position3 = gtk_entry('40') @entry_rectangle_start_position3.center @entry_rectangle_start_position3.hint = 'This designates the <b>width</b> of the rectangle.' @entry_rectangle_start_position4 = gtk_entry('140') @entry_rectangle_start_position4.center @entry_rectangle_start_position4.hint = 'This designates the <b>height</b> of the rectangle.' @entry_background_colour_for_a_new_image = gtk_entry('white') @entry_background_colour_for_a_new_image.select_everything_on_click @entry_background_colour_for_a_new_image.center @entry_background_colour_for_a_new_image.hint = 'This entry designates the <b>background-color</b> '\ 'for a new image.' @entry_background_colour_for_a_new_image.enable_scroll_events @entry_background_colour_for_a_new_image.on_scrolled { do_randomly_change_the_colour_of_the_entry_keeping_track_of_the_colour( @entry_background_colour_for_a_new_image ) } # ======================================================================= # # Next create the entry that contains which colour we should use, when # making a border. # ======================================================================= # @entry_use_this_colour = gtk_entry('black') @entry_use_this_colour.hint = 'This specifies the colour to use for '\ 'any particular operation, if it makes sense in that context. The '\ 'default will be black, so if you make a border, that border '\ 'will be black. You can use the scrollwheel of the mouse '\ 'to randomly pick another colour here.' @entry_use_this_colour.center @entry_use_this_colour.on_click_select_everything @entry_use_this_colour.enable_scroll_events @entry_use_this_colour.on_scrolled { do_randomly_change_the_colour_of_the_entry_keeping_track_of_the_colour } # @entry_use_this_colour.on_clicked { # do_create_a_border_around_the_image #} end
#¶ ↑
create_the_headerbar
(top tag, menubar tag)¶ ↑
This is the top-bar.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 402 def create_the_headerbar @header_bar = gtk_header_bar { :with_close_button } @header_bar.spacing = 5 # @header_bar.title = 'Image-manipulation via ruby-gtk3 and ImageMagick' button = gtk_button button.on_clicked { do_open_a_local_image_file } button.add(image_document_open) button.hint = 'Open a local (image) file.' @header_bar.add(button) button = gtk_button button.on_clicked { do_revert_the_last_action } button.hint = HINT_FOR_BUTTON_UNDO button.add(image_document_revert) @header_bar.add(button) label_with_arrow = return_label_with_arrow_clock_wise_semi_circle event_box = gtk_event_box(label_with_arrow) event_box.hint = HINT_FOR_BUTTON_OPEN_THE_IMAGE_IN_THE_BROWSER event_box.on_clicked { do_open_the_current_image_in_the_browser } @header_bar.add(event_box) button = gtk_button button.on_clicked { do_create_a_magic_card_corner_effect } button.hint = HINT_MAGIC_CARD_CORNER button.add(image_document_revert) @header_bar.add(button) end
#¶ ↑
create_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1230 def create_the_main_image # ======================================================================= # # Load up the image from a file. @work_on_this_image will be an # instance of Gtk::Image. # ======================================================================= # @work_on_this_image = image_from_file(@path_to_the_image) @work_on_this_image.bblack2 @work_on_this_image.css_class('pad5px') this_file_is_the_new_image_file(@path_to_the_image) end
#¶ ↑
create_the_scrolled_window_and_associated_event_box_for_the_box_for_the_main_image
¶ ↑
This method will create the central scrolled window containing our image as well.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 465 def create_the_scrolled_window_and_associated_event_box_for_the_box_for_the_main_image @event_box_for_the_main_image = gtk_event_box( @box_for_the_main_image ) @scrolled_window_for_the_box_for_the_main_image = gtk_scrolled_window( @event_box_for_the_main_image ) { :always } @scrolled_window_for_the_box_for_the_main_image.set_size_request( 680, 520 ) @event_box_for_the_main_image.signal_connect(:event) {|widget, event| if is_mouse_button_event?(event) case event.button when 1,2,3 # These are all left-mouse-button events. handle_mouse_click_event_for_the_main_image(widget, event) end end } end
#¶ ↑
do_apply_a_circle_mask
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 763 def do_apply_a_circle_mask( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.circle_masked(i, output_file) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_apply_a_shadow_effect
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 789 def do_apply_a_shadow_effect( i = main_file?, colour_to_use = return_colour_from_the_border_colour_entry ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.shadow(i, colour_to_use, output_file) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_apply_a_shear_effect
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1060 def do_apply_a_shear_effect( i = path_to_the_main_image?, shear_factor = @spin_button_for_the_first_argument.value.to_s ) new_filename = increment_the_name_of_this_image(i) new_filename = ::ImageParadise.shear( i, shear_factor.to_s+'x0', new_filename ) if new_filename and File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_apply_a_torn_paper_effect
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 776 def do_apply_a_torn_paper_effect( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.torn_paper(i, :default, output_file) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_apply_the_sepia_filter
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 918 def do_apply_the_sepia_filter( i = main_file?, up_by_n = "#{@spin_button_for_the_first_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.sepia_filter( i, up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_apply_the_wave_transformation
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1008 def do_apply_the_wave_transformation( i = main_file?, noise_up_by_n = "#{@spin_button_for_the_first_argument.text?}x#{@spin_button_for_the_second_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.wave( i, noise_up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_blur_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1930 def do_blur_the_image( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.blur( i, @spin_button_for_the_first_argument.text?, # 5px output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_change_the_contrast
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1026 def do_change_the_contrast( i = main_file?, noise_up_by_n = "#{@spin_button_for_the_first_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.contrast( i, noise_up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_charcoal_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 820 def do_charcoal_the_main_image( i = main_file?, radius_to_apply = @spin_button_for_the_first_argument.text? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.charcoal( i, radius_to_apply, # 5px output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_chop_away_outer_pixels
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 803 def do_chop_away_outer_pixels( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.chop_away_outer_pixels( i, @spin_button_for_the_first_argument.text?, # 5px output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_colour_fill_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 838 def do_colour_fill_the_image( i = main_file?, percentage_to_apply = @spin_button_for_the_first_argument.text? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.colour_fill_this_image( i, main_colour?, percentage_to_apply, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_convert_the_image_to_an_ASCII_representation
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 165 def do_convert_the_image_to_an_ASCII_representation( i = @entry_work_on_the_following_image.text? ) a = ::ImageParadise::ImageToAscii.new(i) puts a.to_ascii(color: true) end
#¶ ↑
do_convert_to_png_format
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1483 def do_convert_to_png_format( i = main_file? ) if i.end_with? '.png' e 'Can not convert as it is already a .png file.' else # ===================================================================== # # We prefer the absolute path, as it is easier to find out where # the new image file will reside at. # ===================================================================== # output_file = File.absolute_path( File.basename(i).delete_suffix(File.extname(i))+'.png' ) esystem "convert #{i} #{output_file}" if output_file and File.exist?(output_file) this_is_the_new_image(File.absolute_path(output_file)) end end end
#¶ ↑
do_create_a_border_around_the_image
¶ ↑
The third argument defines which colour is to be used for the border.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1133 def do_create_a_border_around_the_image( i = path_to_the_main_image?, border_size = @spin_button_for_the_first_argument.value.to_s, use_this_colour = @entry_use_this_colour.text? ) new_filename = increment_the_name_of_this_image(i) new_filename = ::ImageParadise.add_border_to_this_image( i, border_size, use_this_colour, new_filename ) if new_filename and File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_create_a_drop_shadow_effect
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1186 def do_create_a_drop_shadow_effect( i = path_to_the_main_image?, use_this_colour = @entry_use_this_colour.text? ) new_filename = increment_the_name_of_this_image(i) new_filename = ::ImageParadise.drop_shadow_effect( i, use_this_colour, new_filename ) if new_filename and File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_create_a_new_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1076 def do_create_a_new_image( new_filename = 'foobar.png', width = first_value?, height = second_value? ) esystem 'convert -size '+width.to_s+'x'+height.to_s+ ' xc:'+@entry_background_colour_for_a_new_image.text?+ ' '+new_filename if File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_create_a_shade_effect
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 954 def do_create_a_shade_effect( i = main_file?, up_by_n = "#{@spin_button_for_the_first_argument.text?}x#{@spin_button_for_the_second_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.shade_effect( i, up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_create_a_thumbnail_from_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 503 def do_create_a_thumbnail_from_the_main_image( i = @entry_work_on_the_following_image.text? ) new_filename = increment_the_name_of_this_image(i) ::ImageParadise.thumbnail( i, :default_width_and_size, new_filename ) if File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_crop_the_image
(crop tag)¶ ↑
This method can be used to crop the main image.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 537 def do_crop_the_image( main_file = main_file? ) string_to_use = @entry_crop1.text?+ 'x'+ @entry_crop2.text?+ '+'+ @entry_crop3.text?+ '+'+ @entry_crop4.text? # ======================================================================= # # We must query the data-set points to use. Thus we need four entries # as shown above. # ======================================================================= # new_filename = increment_the_name_of_this_image(main_file) ::ImageParadise.crop( main_file, string_to_use, new_filename ) if File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_draw_a_line
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 611 def do_draw_a_line( main_file = main_file? ) output_file = increment_the_name_of_this_image(main_file) _ = 'convert '+main_file.to_s+' '+ ::ImageParadise.return_draw_line( [@entry_start_position1.text?, @entry_start_position2.text?], [@entry_start_position3.text?, @entry_start_position4.text?], return_colour_from_the_border_colour_entry, strokewidth: @entry_strokewidth.text? )+ ' '+ output_file esystem _ if File.exist? output_file this_file_is_the_new_image_file(output_file) end end
#¶ ↑
do_draw_a_rectangle
¶ ↑
This method will draw a rectangle onto the main image.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 635 def do_draw_a_rectangle( main_file = main_file? ) output_file = increment_the_name_of_this_image(main_file) _ = 'convert '+main_file.to_s+' '+ ::ImageParadise.return_draw_rectangle( [@entry_rectangle_start_position1.text?, @entry_rectangle_start_position2.text?], [@entry_rectangle_start_position3.text?, @entry_rectangle_start_position4.text?], return_colour_from_the_border_colour_entry )+ ' '+ output_file esystem _ if File.exist? output_file this_file_is_the_new_image_file(output_file) end end
#¶ ↑
do_flip_the_main_image
¶ ↑
This will flip the image from left to right (or vice versa; is the same).
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 270 def do_flip_the_main_image _ = main_image? hash = { use_this_as_the_filepath: increment_the_name_of_this_image(work_on_which_image?) } ImageParadise.flip_image_left_right( _, hash ) # ======================================================================= # # Also designate it as the new main file in use. # ======================================================================= # if File.exist? hash[:use_this_as_the_filepath] this_file_is_the_new_image_file(hash[:use_this_as_the_filepath]) end end
#¶ ↑
do_greyscale_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 254 def do_greyscale_the_main_image( i = @entry_work_on_the_following_image.text? ) new_filename = increment_the_name_of_this_image(i) # The old code in place was: # 'greyscaled_image'+current_file_extension? ::ImageParadise.grayscale_this_image(i, new_filename) this_file_is_the_new_image_file(new_filename) end
#¶ ↑
do_implode_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 864 def do_implode_the_image( i = main_file?, percentage_to_apply = @spin_button_for_the_first_argument.text? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.implode( i, percentage_to_apply, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_make_the_main_image_transparent
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 518 def do_make_the_main_image_transparent( i = path_to_the_main_image? ) new_filename = increment_the_name_of_this_image(i) result = ::ImageParadise.make_this_image_transparent(i, new_filename) if result.is_a? Array result = result.first if File.exist? result this_file_is_the_new_image_file(result) end end end
#¶ ↑
do_negate_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 721 def do_negate_the_main_image( i = @entry_work_on_the_following_image.text? ) new_filename = increment_the_name_of_this_image(i) ::ImageParadise.negate(i, new_filename) this_file_is_the_new_image_file(new_filename) end
#¶ ↑
do_noise_up_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 882 def do_noise_up_the_image( i = main_file?, noise_up_by_n = @spin_button_for_the_first_argument.text? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.noise( i, noise_up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_normalize_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1044 def do_normalize_the_image( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.normalize( i, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_open_a_local_image_file
(open tag)¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1262 def do_open_a_local_image_file create_a_new_file_chooser_dialog(self) {{ start_dir: (Dir.pwd+'/').squeeze('/'), additional_directories: %w( /home/x/data/images/ /home/x/data/images/NJOY/, /Depot/j/ /Depot/jj/ /Depot/jjj/ ) }} _ = ::Gtk.main_file? if _ and File.exist?(_) this_is_the_new_image(_) end end
#¶ ↑
do_raise_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 900 def do_raise_the_image( i = main_file?, noise_up_by_n = "#{@spin_button_for_the_first_argument.text?}x#{@spin_button_for_the_second_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.raise( i, noise_up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_randomly_change_the_colour_of_the_entry_keeping_track_of_the_colour
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1175 def do_randomly_change_the_colour_of_the_entry_keeping_track_of_the_colour( modify_this_entry = @entry_use_this_colour ) modify_this_entry.set_text( random_html_colour.to_s ) end
#¶ ↑
do_resize_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 289 def do_resize_the_main_image( i = @entry_work_on_the_following_image.text?, by_n_percent = @entry_rotate_n_percent.text? ) by_n_percent = by_n_percent.to_i new_filename = ::ImageParadise.resized( i, by_n_percent, increment_the_name_of_this_image(work_on_which_image?) ) this_file_is_the_new_image_file(new_filename) end
#¶ ↑
do_rotate_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 303 def do_rotate_the_image( main_file = main_file? ) _ = @entry_rotate_by_n_degrees.text? new_filename = increment_the_name_of_this_image(main_file) ::ImageParadise.rotate_this_image( main_file, _, :default, new_filename ) if File.exist? new_filename this_file_is_the_new_image_file(new_filename) end end
#¶ ↑
do_round_the_corner
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1150 def do_round_the_corner( i = main_file? ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.rounded_corner(i, output_file) if File.exist? output_file this_is_the_new_image(output_file) end end
#¶ ↑
do_sharpen_the_image_at_hand
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 972 def do_sharpen_the_image_at_hand( i = main_file?, up_by_n = "#{@spin_button_for_the_first_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.sharpen( i, up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_solarize_the_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 990 def do_solarize_the_image( i = main_file?, up_by_n = "#{@spin_button_for_the_first_argument.text?}" ) output_file = increment_the_name_of_this_image(i) ::ImageParadise.solarize( i, up_by_n, output_file ) if File.exist? output_file this_is_the_new_image(File.absolute_path(output_file)) end end
#¶ ↑
do_write_text
¶ ↑
This method can be used to draw text onto the main image.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 734 def do_write_text( i = main_file?, x_coordinate = @entry_x_coordinate.text?, y_coordinate = @entry_y_coordinate.text? ) output_file = increment_the_name_of_this_image(i) _ = @entry_write_this_text.text? if _.empty? e 'No text has been assigned.' return_popover( 'Please assign some text.', @entry_write_this_text, 10 ) else cmd = 'convert '+i+' -fill '+main_colour?+' -pointsize 30 -draw '\ '"text '+x_coordinate.to_s+','+y_coordinate.to_s+' \''+_+'\'" '.dup cmd << '-font computerfont ' cmd << output_file esystem cmd if File.exist? output_file this_is_the_new_image(output_file) end end end
#¶ ↑
handle_mouse_click_event_for_the_main_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 214 def handle_mouse_click_event_for_the_main_image(widget, event) x = event.x_coordinate?.round(0) y = event.y_coordinate?.round(0) # This does not work correctly yet; we need to find out how to # get the x and y position from a sub-widget. # y = (width_of_the_main_image? - y) # ======================================================================= # # Next sync it onto the correct entry. # ======================================================================= # @entry_crop3.set_text(x.to_s) @entry_crop4.set_text(y.to_s) end
#¶ ↑
increment_the_name_of_this_image
¶ ↑
This method will change a name such as “foobar.png” to “foobar1.png”, or “foobar1.png” to “foobar2.png” and so forth.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 326 def increment_the_name_of_this_image( i = 'foobar.png' ) new_name = ''.dup extname = File.extname(i) # e. g. => ".png" basename = File.basename(i).delete_suffix(extname) # This is now e. g. 'foobar' # ======================================================================= # # In the past we just used the last character, but this will fail # if we have something like "foobar_012.png". Thus, we must # use a regex instead. # ======================================================================= # if basename =~ /\d+$/ # Ends with at the least one number. In this case, increment it by +1. basename = ::ImageParadise.increment_this_number_by_one(basename) new_name << basename else # else append it new_name << basename+'1' end # ======================================================================= # # And append the extname again, e. g. ".png". # ======================================================================= # new_name << extname return File.absolute_path(new_name) end
#¶ ↑
is_an_image_file?¶ ↑
Note that this does not work on .gif files, as some of them may be animated .gif files. One day this should be changed, if we can find out which .gif file is animated - but for now this is not the case.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1460 def is_an_image_file?(i) %w( .png .jpg ).include?(File.extname(i)) end
#¶ ↑
make_a_screenshot
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 184 def make_a_screenshot esystem 'import -window root screenshot.png' this_file_is_the_new_image_file('screenshot.png') end
#¶ ↑
reset (reset tag)¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 116 def reset reset_the_internal_variables # ======================================================================= # # === @configuration # ======================================================================= # @configuration = [true, __dir__, NAMESPACE] # ======================================================================= # # === Set the title, width, height and the font in use. # ======================================================================= # title_width_height_font(TITLE, WIDTH, HEIGHT, USE_THIS_FONT) use_gtk_paradise_project_css_file infer_the_size_automatically # ======================================================================= # # === @path_to_the_image # ======================================================================= # @path_to_the_image = '/Depot/j/Unknown1.jpg' # ======================================================================= # # === @array_images # # This array will store the images the user has been working on. # ======================================================================= # @array_images = [] button_hover_colour '#cef0ea; /* This is a very light blue. */' end
#¶ ↑
return_colour_from_the_border_colour_entry
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 857 def return_colour_from_the_border_colour_entry @entry_use_this_colour.text? end
#¶ ↑
return_draw_rectangle_widget
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 488 def return_draw_rectangle_widget outer_hbox = gtk_hbox inner_vbox = gtk_vbox inner_vbox.minimal(@entry_rectangle_start_position1, 1) inner_vbox.minimal(@entry_rectangle_start_position2, 1) inner_vbox.minimal(@entry_rectangle_start_position3, 1) inner_vbox.minimal(@entry_rectangle_start_position4, 1) outer_hbox.minimal(@button_draw_a_rectangle, 1) outer_hbox.minimal(inner_vbox, 1) return outer_hbox end
#¶ ↑
return_hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1962 def return_hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box = gtk_hbox _ = text('Work on the following image:') _.use_this_font = :deja_vu_15 hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box.minimal( _, 2 ) hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box.maximal( @entry_work_on_the_following_image, 2 ) label_with_arrow = return_label_with_arrow_clock_wise_semi_circle event_box = gtk_event_box(label_with_arrow) event_box.hint = HINT_FOR_BUTTON_OPEN_THE_IMAGE_IN_THE_BROWSER event_box.on_clicked { do_open_the_current_image_in_the_browser } hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box.minimal( event_box, 2 ) return hbox_containing_the_entry_work_on_the_following_image_and_the_open_in_browser_event_box end
#¶ ↑
return_rotate_the_image_widget
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1202 def return_rotate_the_image_widget button_rotate_the_image_with_a_symbol = gtk_button(CLOCKWISE_ROTATION_SYMBOL) button_rotate_the_image_with_a_symbol.bblack1 button_rotate_the_image_with_a_symbol.hint = HINT_MESSAGE_FOR_ROTATING_THE_IMAGE button_rotate_the_image_with_a_symbol.on_clicked { do_rotate_the_image } vbox = gtk_vbox vbox.minimal(@entry_rotate_by_n_degrees, 1) vbox.minimal(button_rotate_the_image_with_a_symbol, 1) vbox.maximal(@button_rotate_the_image, 1) return vbox end
#¶ ↑
return_the_widget_containing_the_draw_line_functionality
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 656 def return_the_widget_containing_the_draw_line_functionality outer_hbox = gtk_hbox inner_vbox = gtk_vbox @entry_start_position1 = gtk_entry('10') { :do_center } @entry_start_position2 = gtk_entry('10') { :do_center } @entry_start_position3 = gtk_entry('70') { :do_center } @entry_start_position4 = gtk_entry('90') { :do_center } @entry_strokewidth = gtk_entry('1') { :do_center } @entry_strokewidth.hint = 'This entry specifies the '\ '<b>stroke-width</b> of the line in use.' spinner_button = gtk_spinner_button {{ start_point: 1 }} spinner_button.connect_to(@entry_strokewidth) # Connect it to this widget. hbox_containing_entry_strokewidth_and_spinner_button = gtk_hbox hbox_containing_entry_strokewidth_and_spinner_button.minimal(@entry_strokewidth) hbox_containing_entry_strokewidth_and_spinner_button.minimal(spinner_button) inner_vbox.minimal(@entry_start_position1, 1) inner_vbox.minimal(@entry_start_position2, 1) inner_vbox.minimal(@entry_start_position3, 1) inner_vbox.minimal(@entry_start_position4, 1) inner_vbox.minimal(hbox_containing_entry_strokewidth_and_spinner_button, 1) outer_hbox.minimal(@button_draw_a_line, 1) outer_hbox.minimal(inner_vbox, 1) return outer_hbox end
#¶ ↑
return_widget_containing_information_about_an_image
¶ ↑
This is the widget that contains information about the image at hand.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1303 def return_widget_containing_information_about_an_image( main_image = main_image? ) frame = gtk_frame frame.set_label('Information about the image: ') frame.set_border_width(8) frame.use_this_font = smaller_font? vbox = gtk_vbox @label_resolution = label('Resolution: ') @label_comments_stored_in_the_image = label vbox << @label_resolution vbox << @label_comments_stored_in_the_image vbox.use_this_font = smaller_font? frame << vbox return frame end
#¶ ↑
return_widget_containing_the_write_text_functionality
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 565 def return_widget_containing_the_write_text_functionality vbox = gtk_vbox @entry_write_this_text = gtk_entry @entry_write_this_text.center @entry_write_this_text.on_enter { do_write_text } @entry_write_this_text.highlight_on_focus @entry_x_coordinate = gtk_entry('10') @entry_x_coordinate.hint = 'The <b>x coordinate</b>.' @entry_x_coordinate.center @entry_x_coordinate.on_enter { do_write_text } @entry_y_coordinate = gtk_entry('10') @entry_y_coordinate.hint = 'The <b>x coordinate</b>.' @entry_y_coordinate.center @entry_y_coordinate.on_enter { do_write_text } another_small_vbox = gtk_vbox another_small_vbox.minimal(text('Use this colour:')) another_small_vbox.minimal(@entry_use_this_colour) vbox.minimal(another_small_vbox, 1) vbox.minimal(@button_shade, 1) vbox.minimal(@button_write_text, 1) vbox.minimal(@entry_write_this_text, 1) hbox = gtk_hbox hbox.maximal(@entry_x_coordinate, 1) hbox.maximal(@entry_y_coordinate, 1) vbox.minimal( hbox, 1 ) return vbox end
#¶ ↑
run (run tag)¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1947 def run super() apply_the_css_string Thread.new { # This is a small hack. We avoid the "select everything" problem. sleep 0.001 @entry_work_on_the_following_image.set_editable(true) cd_to_the_log_directory menu # Process the commandline arguments next. update_the_info_box } end
#¶ ↑
this_file_is_the_new_image_file
¶ ↑
This method is used to designate the current main image file in use.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1508 def this_file_is_the_new_image_file(i, &block) i = i.to_s @path_to_the_image = File.absolute_path(i) if @path_to_the_image and File.exist?(@path_to_the_image) if block_given? yielded = yield case yielded # =================================================================== # # === :be_verbose # =================================================================== # when :be_verbose e "Assigning the image #{i} next." end end @work_on_this_image.set_file( @path_to_the_image ) unless (@array_images.last == @path_to_the_image) @array_images << @path_to_the_image end @entry_work_on_the_following_image.set_text(@path_to_the_image) update_the_info_box(@path_to_the_image) end end
#¶ ↑
try_to_assign_a_new_random_image_from_the_base_directory_of_entry_work_on_the_following_image
¶ ↑
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 1467 def try_to_assign_a_new_random_image_from_the_base_directory_of_entry_work_on_the_following_image _ = @entry_work_on_the_following_image.text? if _.include?('/') basedir = File.dirname(_)+'/' if File.directory? basedir random_file = Dir[basedir+'*'].select {|entry| is_an_image_file?(entry) }.sample if File.exist? random_file this_is_the_new_image(random_file) { :be_verbose } end end end end
#¶ ↑
undo (undo tag)¶ ↑
This is for the undo-operation.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 938 def undo( i = @array_images ) if i.size > 0 i.pop if i and i.last this_is_the_new_image(i.last) if File.exist?(i.last) end else e 'No image is stored in @array_images.' end end
#¶ ↑
update_the_info_box
¶ ↑
This method can be used to specifically update the widget showing information about the image - be it the width, the size, or any additional meta-data that may be stored in the image at hand.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 688 def update_the_info_box( main_image = main_image? ) if File.exist? main_image analysed_string = `convert #{main_image} -print "Resolution: <b>%wx%h px</b>" /dev/nul`.strip.dup # Assume a String like: "Size: 819x453" analysed_string << "\nFile size: "\ "<b>#{(File.size(main_image) / 1024.0).round(2)} kb</b>" @label_resolution.set_text(analysed_string) @label_resolution.do_markify # ===================================================================== # # Next, identify comments in the image at hand: # ===================================================================== # result = `identify -verbose #{main_image}` if result.include?('Properties:') and result.include?(' comment: ') scanned = result.scan(/ comment: (.+)$/).flatten unless scanned.empty? _ = scanned.first.to_s if _.size > 15 _ = _[0 .. 15]+' [...]' end @label_comments_stored_in_the_image.set_text( "Comment: \n<b>#{_}</b>" ) @label_comments_stored_in_the_image.do_markify end end end end
#¶ ↑
width_of_the_main_image?¶ ↑
This method depends on ImageMagick “convert” binary. It will return the width of the main image, as Integer.
#¶ ↑
# File lib/image_paradise/gui/gtk3/image_editor/image_editor.rb, line 205 def width_of_the_main_image?( main_image = main_image? ) `convert #{main_image} -print "%w" /dev/nul`.strip.dup.to_i end