image_paradise 0.4.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (650) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +38 -0
  3. data/README.md +1015 -0
  4. data/USAGE.md +10 -0
  5. data/bin/black_white +10 -0
  6. data/bin/confree_generator +7 -0
  7. data/bin/create_new_image +7 -0
  8. data/bin/display_text_from_this_image +7 -0
  9. data/bin/draw_as_specified_from_the_yaml_file +7 -0
  10. data/bin/embed_the_filename_into_this_image +7 -0
  11. data/bin/image_paradise +7 -0
  12. data/bin/image_paradise_shell +7 -0
  13. data/bin/image_to_ascii +54 -0
  14. data/bin/image_to_pdf +7 -0
  15. data/bin/imageparadise_img2pdf +12 -0
  16. data/bin/img_text +14 -0
  17. data/bin/interlace +7 -0
  18. data/bin/jpg_to_pdf +12 -0
  19. data/bin/magic_card_border +8 -0
  20. data/bin/make_this_image_transparent +7 -0
  21. data/bin/morph_these_images +7 -0
  22. data/bin/optimize_this_image +7 -0
  23. data/bin/quality +7 -0
  24. data/bin/rename_this_file_based_on_metadata_information +7 -0
  25. data/bin/resize_by_percent +10 -0
  26. data/bin/rotate_left +7 -0
  27. data/bin/rotate_right +7 -0
  28. data/bin/round_the_corner +7 -0
  29. data/bin/ruby_montage +7 -0
  30. data/bin/transparent +15 -0
  31. data/doc/README.gen +936 -0
  32. data/doc/todo/TODO_FOR_THE_GTK_GUI.md +9 -0
  33. data/doc/todo/TODO_FOR_THE_IMAGE_PARADISE_PROJECT.md +20 -0
  34. data/doc/todo/TODO_WORK_THROUGH_THESE_LINKS.md +3 -0
  35. data/doc/todo/todo_for_the_libui_gui.md +6 -0
  36. data/image_paradise.gemspec +46 -0
  37. data/images/IMAGE_PARADISE_LOGO.png +0 -0
  38. data/lib/image_paradise/base/base.rb +324 -0
  39. data/lib/image_paradise/cfdg/1dca_pattern.cfdg +48 -0
  40. data/lib/image_paradise/cfdg/3d_coloured_cube.cfdg +95 -0
  41. data/lib/image_paradise/cfdg/a_3D_spiral.cfdg +40 -0
  42. data/lib/image_paradise/cfdg/a_chaotic_city.cfdg +156 -0
  43. data/lib/image_paradise/cfdg/a_coloured_red.cfdg +21 -0
  44. data/lib/image_paradise/cfdg/a_daisy_flower.cfdg +66 -0
  45. data/lib/image_paradise/cfdg/a_decorated_window.cfdg +74 -0
  46. data/lib/image_paradise/cfdg/a_human_profile.cfdg +303 -0
  47. data/lib/image_paradise/cfdg/a_lost_heart.cfdg +28 -0
  48. data/lib/image_paradise/cfdg/a_plant_root.cfdg +26 -0
  49. data/lib/image_paradise/cfdg/a_rather_realistic_forest.cfdg +29 -0
  50. data/lib/image_paradise/cfdg/a_shoreline_next_to_a_forest.cfdg +127 -0
  51. data/lib/image_paradise/cfdg/a_simple_mini_brain.cfdg +17 -0
  52. data/lib/image_paradise/cfdg/a_simple_star.cfdg +22 -0
  53. data/lib/image_paradise/cfdg/adorned_tree.cfdg +58 -0
  54. data/lib/image_paradise/cfdg/adsorption.cfdg +19 -0
  55. data/lib/image_paradise/cfdg/alfabet_free.cfdg +346 -0
  56. data/lib/image_paradise/cfdg/alfreebet.cfdg +229 -0
  57. data/lib/image_paradise/cfdg/algal_flora.cfdg +25 -0
  58. data/lib/image_paradise/cfdg/alien_eyeball.cfdg +15 -0
  59. data/lib/image_paradise/cfdg/alien_flower.cfdg +35 -0
  60. data/lib/image_paradise/cfdg/alphabet_circles.cfdg +38 -0
  61. data/lib/image_paradise/cfdg/alveolo.cfdg +38 -0
  62. data/lib/image_paradise/cfdg/an_icosahedron.cfdg +134 -0
  63. data/lib/image_paradise/cfdg/an_oils_surface.cfdg +48 -0
  64. data/lib/image_paradise/cfdg/ancient_map.cfdg +30 -0
  65. data/lib/image_paradise/cfdg/ancient_scripts_tile.cfdg +96 -0
  66. data/lib/image_paradise/cfdg/angelfish.cfdg +58 -0
  67. data/lib/image_paradise/cfdg/angry_yarn.cfdg +82 -0
  68. data/lib/image_paradise/cfdg/apple_tree_small.cfdg +46 -0
  69. data/lib/image_paradise/cfdg/aqua_star.cfdg +27 -0
  70. data/lib/image_paradise/cfdg/army_explosion.cfdg +25 -0
  71. data/lib/image_paradise/cfdg/arrows_in_quadcity.cfdg +143 -0
  72. data/lib/image_paradise/cfdg/artificial_intelligence.cfdg +41 -0
  73. data/lib/image_paradise/cfdg/askew.cfdg +27 -0
  74. data/lib/image_paradise/cfdg/audio_diagram_waves.cfdg +54 -0
  75. data/lib/image_paradise/cfdg/autumn_fractal.cfdg +39 -0
  76. data/lib/image_paradise/cfdg/baignoire.cfdg +33 -0
  77. data/lib/image_paradise/cfdg/barcode.cfdg +781 -0
  78. data/lib/image_paradise/cfdg/basic_polygon_shapes.cfdg +311 -0
  79. data/lib/image_paradise/cfdg/basic_spreaders.cfdg +52 -0
  80. data/lib/image_paradise/cfdg/basic_square.cfdg +8 -0
  81. data/lib/image_paradise/cfdg/bats_hiding_in_foliage.cfdg +19 -0
  82. data/lib/image_paradise/cfdg/bees.cfdg +61 -0
  83. data/lib/image_paradise/cfdg/bent_squares.cfdg +46 -0
  84. data/lib/image_paradise/cfdg/benzo_dreaming.cfdg +54 -0
  85. data/lib/image_paradise/cfdg/beta_bet.cfdg +645 -0
  86. data/lib/image_paradise/cfdg/big_bang_theory.cfdg +31 -0
  87. data/lib/image_paradise/cfdg/big_pacman.cfdg +70 -0
  88. data/lib/image_paradise/cfdg/bigger_tree.cfdg +64 -0
  89. data/lib/image_paradise/cfdg/binary_connection.cfdg +34 -0
  90. data/lib/image_paradise/cfdg/birch_line.cfdg +57 -0
  91. data/lib/image_paradise/cfdg/blacksmith_masterpiece.cfdg +3 -0
  92. data/lib/image_paradise/cfdg/blocked_rectangles.cfdg +23 -0
  93. data/lib/image_paradise/cfdg/blood_tubes.cfdg +45 -0
  94. data/lib/image_paradise/cfdg/bloom.cfdg +23 -0
  95. data/lib/image_paradise/cfdg/blown_glass_spheres.cfdg +30 -0
  96. data/lib/image_paradise/cfdg/blue_daisies_in_detail.cfdg +101 -0
  97. data/lib/image_paradise/cfdg/blue_galaxy.cfdg +20 -0
  98. data/lib/image_paradise/cfdg/blue_moon.cfdg +36 -0
  99. data/lib/image_paradise/cfdg/boa_feathers.cfdg +53 -0
  100. data/lib/image_paradise/cfdg/bomb.cfdg +75 -0
  101. data/lib/image_paradise/cfdg/boxy_continent.cfdg +111 -0
  102. data/lib/image_paradise/cfdg/bright_coloured_neurons.cfdg +53 -0
  103. data/lib/image_paradise/cfdg/brightness_flower.cfdg +31 -0
  104. data/lib/image_paradise/cfdg/btp_71_beautiful_coloured_lines.cfdg +85 -0
  105. data/lib/image_paradise/cfdg/btp_73.cfdg +76 -0
  106. data/lib/image_paradise/cfdg/bubblesun.cfdg +46 -0
  107. data/lib/image_paradise/cfdg/burning_bush.cfdg +31 -0
  108. data/lib/image_paradise/cfdg/butterflies_in_the_moonlight.cfdg +55 -0
  109. data/lib/image_paradise/cfdg/cardiod_arc.cfdg +44 -0
  110. data/lib/image_paradise/cfdg/cardioid.cfdg +41 -0
  111. data/lib/image_paradise/cfdg/caros_wallpaper.cfdg +46 -0
  112. data/lib/image_paradise/cfdg/cartoony_face_arrays.cfdg +137 -0
  113. data/lib/image_paradise/cfdg/centerfold.cfdg +12 -0
  114. data/lib/image_paradise/cfdg/chain_link_fence.cfdg +31 -0
  115. data/lib/image_paradise/cfdg/chanukah.cfdg +109 -0
  116. data/lib/image_paradise/cfdg/chaos_red_sun.cfdg +42 -0
  117. data/lib/image_paradise/cfdg/chaotic_farn.cfdg +76 -0
  118. data/lib/image_paradise/cfdg/chaotic_fractal_shell.cfdg +41 -0
  119. data/lib/image_paradise/cfdg/charleston.cfdg +182 -0
  120. data/lib/image_paradise/cfdg/ciliasun.cfdg +109 -0
  121. data/lib/image_paradise/cfdg/cipal.cfdg +65 -0
  122. data/lib/image_paradise/cfdg/circuits.cfdg +176 -0
  123. data/lib/image_paradise/cfdg/city_map.cfdg +66 -0
  124. data/lib/image_paradise/cfdg/clifford_torus.cfdg +135 -0
  125. data/lib/image_paradise/cfdg/colonize_flat_colour_pattern.cfdg +14 -0
  126. data/lib/image_paradise/cfdg/colour_blind_squid.cfdg +30 -0
  127. data/lib/image_paradise/cfdg/colour_hole.cfdg +56 -0
  128. data/lib/image_paradise/cfdg/colour_wheel.cfdg +40 -0
  129. data/lib/image_paradise/cfdg/coloured_eyes.cfdg +40 -0
  130. data/lib/image_paradise/cfdg/coloured_forest.cfdg +133 -0
  131. data/lib/image_paradise/cfdg/coloured_tree.cfdg +50 -0
  132. data/lib/image_paradise/cfdg/colourful_lives.cfdg +123 -0
  133. data/lib/image_paradise/cfdg/colourful_neuronal_network.cfdg +32 -0
  134. data/lib/image_paradise/cfdg/complex_city_plans.cfdg +75 -0
  135. data/lib/image_paradise/cfdg/complex_kritworks.cfdg +75 -0
  136. data/lib/image_paradise/cfdg/complex_snowflake.cfdg +61 -0
  137. data/lib/image_paradise/cfdg/conspiracy_theory.cfdg +104 -0
  138. data/lib/image_paradise/cfdg/constellation_grid.cfdg +29 -0
  139. data/lib/image_paradise/cfdg/cool_caterpillar.cfdg +44 -0
  140. data/lib/image_paradise/cfdg/coolcubes.cfdg +70 -0
  141. data/lib/image_paradise/cfdg/crawler_battle.cfdg +93 -0
  142. data/lib/image_paradise/cfdg/crazy_octo.cfdg +48 -0
  143. data/lib/image_paradise/cfdg/cthulhu.cfdg +166 -0
  144. data/lib/image_paradise/cfdg/cubies.cfdg +43 -0
  145. data/lib/image_paradise/cfdg/cubist_sunset.cfdg +55 -0
  146. data/lib/image_paradise/cfdg/curled_tree.cfdg +37 -0
  147. data/lib/image_paradise/cfdg/curls.cfdg +45 -0
  148. data/lib/image_paradise/cfdg/curve_stiched.cfdg +59 -0
  149. data/lib/image_paradise/cfdg/curved_tubes.cfdg +20 -0
  150. data/lib/image_paradise/cfdg/cylinder_city.cfdg +27 -0
  151. data/lib/image_paradise/cfdg/cymbal.cfdg +38 -0
  152. data/lib/image_paradise/cfdg/d_mustard.cfdg +52 -0
  153. data/lib/image_paradise/cfdg/dance_party.cfdg +81 -0
  154. data/lib/image_paradise/cfdg/dance_party_and_background.cfdg +86 -0
  155. data/lib/image_paradise/cfdg/decreasing_aperture.cfdg +16 -0
  156. data/lib/image_paradise/cfdg/delicat_twist.cfdg +13 -0
  157. data/lib/image_paradise/cfdg/demo_text.cfdg +22 -0
  158. data/lib/image_paradise/cfdg/dennis_ritchie.cfdg +294 -0
  159. data/lib/image_paradise/cfdg/diablo.cfdg +47 -0
  160. data/lib/image_paradise/cfdg/different_flowers.cfdg +60 -0
  161. data/lib/image_paradise/cfdg/different_snowflakes_shapes.cfdg +149 -0
  162. data/lib/image_paradise/cfdg/dimensions.cfdg +33 -0
  163. data/lib/image_paradise/cfdg/domino_pieces.cfdg +166 -0
  164. data/lib/image_paradise/cfdg/dong.cfdg +41 -0
  165. data/lib/image_paradise/cfdg/drip_shape.cfdg +24 -0
  166. data/lib/image_paradise/cfdg/earthday2007b.cfdg +49 -0
  167. data/lib/image_paradise/cfdg/edera_circles.cfdg +55 -0
  168. data/lib/image_paradise/cfdg/eight_queens_problem.cfdg +85 -0
  169. data/lib/image_paradise/cfdg/electro_shock.cfdg +88 -0
  170. data/lib/image_paradise/cfdg/enter_the_force_field.cfdg +56 -0
  171. data/lib/image_paradise/cfdg/escargot_fleur.cfdg +98 -0
  172. data/lib/image_paradise/cfdg/european_city.cfdg +63 -0
  173. data/lib/image_paradise/cfdg/evil_eye.cfdg +74 -0
  174. data/lib/image_paradise/cfdg/evolving_coloured_spots.cfdg +47 -0
  175. data/lib/image_paradise/cfdg/excellines_nr2.cfdg +171 -0
  176. data/lib/image_paradise/cfdg/exoplanet_settlement.cfdg +117 -0
  177. data/lib/image_paradise/cfdg/explosion.cfdg +45 -0
  178. data/lib/image_paradise/cfdg/explosion_of_a_megabyte.cfdg +73 -0
  179. data/lib/image_paradise/cfdg/eye_of_katora.cfdg +20 -0
  180. data/lib/image_paradise/cfdg/family_tree.cfdg +169 -0
  181. data/lib/image_paradise/cfdg/feathers.cfdg +17 -0
  182. data/lib/image_paradise/cfdg/ferma_drawings.cfdg +23 -0
  183. data/lib/image_paradise/cfdg/fevrier.cfdg +66 -0
  184. data/lib/image_paradise/cfdg/fibmod.cfdg +25 -0
  185. data/lib/image_paradise/cfdg/field_of_boxes.cfdg +21 -0
  186. data/lib/image_paradise/cfdg/finetre.cfdg +34 -0
  187. data/lib/image_paradise/cfdg/fireblorks.cfdg +37 -0
  188. data/lib/image_paradise/cfdg/first_branch.cfdg +18 -0
  189. data/lib/image_paradise/cfdg/fish_with_coloured_bubbles.cfdg +77 -0
  190. data/lib/image_paradise/cfdg/fishing_lure.cfdg +30 -0
  191. data/lib/image_paradise/cfdg/flake.cfdg +20 -0
  192. data/lib/image_paradise/cfdg/flaming_spiro.cfdg +10 -0
  193. data/lib/image_paradise/cfdg/fleshflower.cfdg +25 -0
  194. data/lib/image_paradise/cfdg/flourescent_fish_btp.cfdg +48 -0
  195. data/lib/image_paradise/cfdg/flow_control_shape.cfdg +45 -0
  196. data/lib/image_paradise/cfdg/flower_galaxy.cfdg +57 -0
  197. data/lib/image_paradise/cfdg/flower_house.cfdg +115 -0
  198. data/lib/image_paradise/cfdg/flower_stories.cfdg +136 -0
  199. data/lib/image_paradise/cfdg/fluctuating_heart.cfdg +87 -0
  200. data/lib/image_paradise/cfdg/fly_agaric.cfdg +22 -0
  201. data/lib/image_paradise/cfdg/forest_and_ocean.cfdg +65 -0
  202. data/lib/image_paradise/cfdg/fractal_fern.cfdg +15 -0
  203. data/lib/image_paradise/cfdg/fractal_shell.cfdg +36 -0
  204. data/lib/image_paradise/cfdg/frost_bite.cfdg +23 -0
  205. data/lib/image_paradise/cfdg/fun_with_paper.cfdg +17 -0
  206. data/lib/image_paradise/cfdg/func_plot.cfdg +59 -0
  207. data/lib/image_paradise/cfdg/funky_squiggle.cfdg +40 -0
  208. data/lib/image_paradise/cfdg/fuzzy_sun.cfdg +47 -0
  209. data/lib/image_paradise/cfdg/galaxy.cfdg +59 -0
  210. data/lib/image_paradise/cfdg/gallery.cfdg +28 -0
  211. data/lib/image_paradise/cfdg/game1_turn6.cfdg +35 -0
  212. data/lib/image_paradise/cfdg/garland.cfdg +42 -0
  213. data/lib/image_paradise/cfdg/general_polygons.cfdg +20 -0
  214. data/lib/image_paradise/cfdg/generational_birds.cfdg +118 -0
  215. data/lib/image_paradise/cfdg/ghostly_spine.cfdg +24 -0
  216. data/lib/image_paradise/cfdg/gift_wrapping.cfdg +46 -0
  217. data/lib/image_paradise/cfdg/glass_cubes.cfdg +33 -0
  218. data/lib/image_paradise/cfdg/gleaming_bush.cfdg +33 -0
  219. data/lib/image_paradise/cfdg/glowing_bush.cfdg +33 -0
  220. data/lib/image_paradise/cfdg/go_grid.cfdg +32 -0
  221. data/lib/image_paradise/cfdg/gold_tiles.cfdg +21 -0
  222. data/lib/image_paradise/cfdg/golden_rectangle.cfdg +19 -0
  223. data/lib/image_paradise/cfdg/golden_sierpinski.cfdg +49 -0
  224. data/lib/image_paradise/cfdg/golgi_stain.cfdg +74 -0
  225. data/lib/image_paradise/cfdg/gothic_bath_tiles.cfdg +14 -0
  226. data/lib/image_paradise/cfdg/grass_land.cfdg +112 -0
  227. data/lib/image_paradise/cfdg/gray_matter.cfdg +110 -0
  228. data/lib/image_paradise/cfdg/great_forest.cfdg +91 -0
  229. data/lib/image_paradise/cfdg/growth.cfdg +46 -0
  230. data/lib/image_paradise/cfdg/gumtree.cfdg +28 -0
  231. data/lib/image_paradise/cfdg/haggards_bull.cfdg +92 -0
  232. data/lib/image_paradise/cfdg/haight_ashbury.cfdg +882 -0
  233. data/lib/image_paradise/cfdg/hair_pattern.cfdg +59 -0
  234. data/lib/image_paradise/cfdg/hairy.cfdg +43 -0
  235. data/lib/image_paradise/cfdg/hairy_branch.cfdg +48 -0
  236. data/lib/image_paradise/cfdg/hands_and_feet.cfdg +49 -0
  237. data/lib/image_paradise/cfdg/happy_new_year.cfdg +3435 -0
  238. data/lib/image_paradise/cfdg/hatagu_lila_spiral.cfdg +27 -0
  239. data/lib/image_paradise/cfdg/hexaeder_triangle.cfdg +43 -0
  240. data/lib/image_paradise/cfdg/hexclouds_textures.cfdg +75 -0
  241. data/lib/image_paradise/cfdg/hextiles.cfdg +73 -0
  242. data/lib/image_paradise/cfdg/hexy_continent.cfdg +83 -0
  243. data/lib/image_paradise/cfdg/human_ballet.cfdg +215 -0
  244. data/lib/image_paradise/cfdg/human_eyes.cfdg +102 -0
  245. data/lib/image_paradise/cfdg/hydra_tail.cfdg +57 -0
  246. data/lib/image_paradise/cfdg/i_like_it_dirty.cfdg +88 -0
  247. data/lib/image_paradise/cfdg/i_pix.cfdg +679 -0
  248. data/lib/image_paradise/cfdg/imaginary_star.cfdg +55 -0
  249. data/lib/image_paradise/cfdg/imaginery_forest.cfdg +61 -0
  250. data/lib/image_paradise/cfdg/impossible_stairs.cfdg +211 -0
  251. data/lib/image_paradise/cfdg/in_the_morning.cfdg +83 -0
  252. data/lib/image_paradise/cfdg/inertial_confinement.cfdg +150 -0
  253. data/lib/image_paradise/cfdg/infected_shell.cfdg +56 -0
  254. data/lib/image_paradise/cfdg/insect_fight.cfdg +316 -0
  255. data/lib/image_paradise/cfdg/insectivore.cfdg +80 -0
  256. data/lib/image_paradise/cfdg/interference.cfdg +43 -0
  257. data/lib/image_paradise/cfdg/interference_fields.cfdg +25 -0
  258. data/lib/image_paradise/cfdg/into_the_deep.cfdg +96 -0
  259. data/lib/image_paradise/cfdg/inverted_decorations.cfdg +85 -0
  260. data/lib/image_paradise/cfdg/irregular_galaxies.cfdg +29 -0
  261. data/lib/image_paradise/cfdg/iso_blocks.cfdg +35 -0
  262. data/lib/image_paradise/cfdg/jewelry_old_style.cfdg +31 -0
  263. data/lib/image_paradise/cfdg/just_some_flowers.cfdg +127 -0
  264. data/lib/image_paradise/cfdg/kaboom.cfdg +40 -0
  265. data/lib/image_paradise/cfdg/kaleidoskop.cfdg +27 -0
  266. data/lib/image_paradise/cfdg/kama_sutra.cfdg +182 -0
  267. data/lib/image_paradise/cfdg/kitakoa_akiyoshi_illusions_roller.cfdg +40 -0
  268. data/lib/image_paradise/cfdg/koch_snowflake.cfdg +11 -0
  269. data/lib/image_paradise/cfdg/kochlea.cfdg +43 -0
  270. data/lib/image_paradise/cfdg/kreepykrawler.cfdg +48 -0
  271. data/lib/image_paradise/cfdg/kw_expanded_explosion.cfdg +46 -0
  272. data/lib/image_paradise/cfdg/lapsang_abstrait.cfdg +51 -0
  273. data/lib/image_paradise/cfdg/laser.cfdg +51 -0
  274. data/lib/image_paradise/cfdg/last_pluto_dream.cfdg +95 -0
  275. data/lib/image_paradise/cfdg/lazy_dust.cfdg +42 -0
  276. data/lib/image_paradise/cfdg/lesson_one_two_three_four.cfdg +217 -0
  277. data/lib/image_paradise/cfdg/lila_lili.cfdg +60 -0
  278. data/lib/image_paradise/cfdg/lindenmayergrassef2_pretty_flowers.cfdg +94 -0
  279. data/lib/image_paradise/cfdg/lines_from_excel.cfdg +136 -0
  280. data/lib/image_paradise/cfdg/looking_out.cfdg +51 -0
  281. data/lib/image_paradise/cfdg/looking_up_in_the_sky.cfdg +43 -0
  282. data/lib/image_paradise/cfdg/lotus_logo.cfdg +49 -0
  283. data/lib/image_paradise/cfdg/lowercased_alphabet.cfdg +565 -0
  284. data/lib/image_paradise/cfdg/luma_smiley.cfdg +563 -0
  285. data/lib/image_paradise/cfdg/maggi_stars.cfdg +11 -0
  286. data/lib/image_paradise/cfdg/mandelbrot_3.cfdg +111 -0
  287. data/lib/image_paradise/cfdg/martini.cfdg +147 -0
  288. data/lib/image_paradise/cfdg/material_studies.cfdg +172 -0
  289. data/lib/image_paradise/cfdg/math_eye.cfdg +30 -0
  290. data/lib/image_paradise/cfdg/matrix_freestyle.cfdg +127 -0
  291. data/lib/image_paradise/cfdg/maze.cfdg +211 -0
  292. data/lib/image_paradise/cfdg/meaculpo.cfdg +46 -0
  293. data/lib/image_paradise/cfdg/medieval_madness.cfdg +140 -0
  294. data/lib/image_paradise/cfdg/menage_a_trois.cfdg +77 -0
  295. data/lib/image_paradise/cfdg/micky_mouse.cfdg +75 -0
  296. data/lib/image_paradise/cfdg/mistletoe_forest.cfdg +62 -0
  297. data/lib/image_paradise/cfdg/mixed_simple_bubbles.cfdg +20 -0
  298. data/lib/image_paradise/cfdg/mod4g_starhole.cfdg +27 -0
  299. data/lib/image_paradise/cfdg/moebius.cfdg +57 -0
  300. data/lib/image_paradise/cfdg/molecules.cfdg +30 -0
  301. data/lib/image_paradise/cfdg/momos_blossom.cfdg +70 -0
  302. data/lib/image_paradise/cfdg/mona_lisa.cfdg +7937 -0
  303. data/lib/image_paradise/cfdg/more_arrows_in_quadcity.cfdg +49 -0
  304. data/lib/image_paradise/cfdg/more_cats.cfdg +1002 -0
  305. data/lib/image_paradise/cfdg/mosaic_for_2D_games.cfdg +69 -0
  306. data/lib/image_paradise/cfdg/mr_bezier.cfdg +195 -0
  307. data/lib/image_paradise/cfdg/mtree.cfdg +33 -0
  308. data/lib/image_paradise/cfdg/multiple_triangles.cfdg +13 -0
  309. data/lib/image_paradise/cfdg/mycel.cfdg +88 -0
  310. data/lib/image_paradise/cfdg/mytohexagone.cfdg +56 -0
  311. data/lib/image_paradise/cfdg/nature_is_not_like_that.cfdg +48 -0
  312. data/lib/image_paradise/cfdg/negative_flowers.cfdg +85 -0
  313. data/lib/image_paradise/cfdg/neo_town.cfdg +41 -0
  314. data/lib/image_paradise/cfdg/nesting_pattern.cfdg +34 -0
  315. data/lib/image_paradise/cfdg/neuronal_network.cfdg +94 -0
  316. data/lib/image_paradise/cfdg/neuronal_root.cfdg +46 -0
  317. data/lib/image_paradise/cfdg/night.cfdg +82 -0
  318. data/lib/image_paradise/cfdg/nightwalker.cfdg +23 -0
  319. data/lib/image_paradise/cfdg/no_xcape.cfdg +41 -0
  320. data/lib/image_paradise/cfdg/noise.cfdg +12 -0
  321. data/lib/image_paradise/cfdg/octopodi.cfdg +51 -0
  322. data/lib/image_paradise/cfdg/octopussy.cfdg +49 -0
  323. data/lib/image_paradise/cfdg/oldschool_cartoon_figure.cfdg +181 -0
  324. data/lib/image_paradise/cfdg/open_shapes.cfdg +240 -0
  325. data/lib/image_paradise/cfdg/orange_blossom.cfdg +57 -0
  326. data/lib/image_paradise/cfdg/orange_guts.cfdg +43 -0
  327. data/lib/image_paradise/cfdg/orange_monster.cfdg +42 -0
  328. data/lib/image_paradise/cfdg/organic.cfdg +30 -0
  329. data/lib/image_paradise/cfdg/ouo_happy_smiley.cfdg +45 -0
  330. data/lib/image_paradise/cfdg/output.png +0 -0
  331. data/lib/image_paradise/cfdg/pacman.cfdg +18 -0
  332. data/lib/image_paradise/cfdg/palmen.cfdg +162 -0
  333. data/lib/image_paradise/cfdg/pandoras_box.cfdg +53 -0
  334. data/lib/image_paradise/cfdg/papillon_butterfly.cfdg +28 -0
  335. data/lib/image_paradise/cfdg/patchwork.cfdg +32 -0
  336. data/lib/image_paradise/cfdg/pattern_grass.cfdg +110 -0
  337. data/lib/image_paradise/cfdg/peau_de_grenouille.cfdg +16 -0
  338. data/lib/image_paradise/cfdg/penrose_tiling.cfdg +102 -0
  339. data/lib/image_paradise/cfdg/pentagon.cfdg +68 -0
  340. data/lib/image_paradise/cfdg/pentagons.cfdg +25 -0
  341. data/lib/image_paradise/cfdg/perspective_tsunami.cfdg +20 -0
  342. data/lib/image_paradise/cfdg/phi_cloud.cfdg +23 -0
  343. data/lib/image_paradise/cfdg/picnic_birds_eye_view.cfdg +132 -0
  344. data/lib/image_paradise/cfdg/ping_pong.cfdg +29 -0
  345. data/lib/image_paradise/cfdg/pink_blossom.cfdg +58 -0
  346. data/lib/image_paradise/cfdg/piupole.cfdg +77 -0
  347. data/lib/image_paradise/cfdg/plotting.cfdg +61 -0
  348. data/lib/image_paradise/cfdg/point_onto_root.cfdg +64 -0
  349. data/lib/image_paradise/cfdg/primitive_reptile_pattern.cfdg +96 -0
  350. data/lib/image_paradise/cfdg/psycho_knot.cfdg +20 -0
  351. data/lib/image_paradise/cfdg/pyramide.cfdg +67 -0
  352. data/lib/image_paradise/cfdg/pythagoras_puzzle.cfdg +17 -0
  353. data/lib/image_paradise/cfdg/pythagorean_tree.cfdg +70 -0
  354. data/lib/image_paradise/cfdg/qimica.cfdg +64 -0
  355. data/lib/image_paradise/cfdg/quad_green_satellite.cfdg +53 -0
  356. data/lib/image_paradise/cfdg/quadcity.cfdg +24 -0
  357. data/lib/image_paradise/cfdg/quiet_wood_town.cfdg +195 -0
  358. data/lib/image_paradise/cfdg/r180.cfdg +26 -0
  359. data/lib/image_paradise/cfdg/r45.cfdg +26 -0
  360. data/lib/image_paradise/cfdg/r_square.cfdg +36 -0
  361. data/lib/image_paradise/cfdg/rads.cfdg +33 -0
  362. data/lib/image_paradise/cfdg/rainbow_black_hole.cfdg +9 -0
  363. data/lib/image_paradise/cfdg/rainbow_sun.cfdg +9 -0
  364. data/lib/image_paradise/cfdg/random_handwriting.cfdg +50 -0
  365. data/lib/image_paradise/cfdg/random_tile_shapes_jens_revisited.cfdg +146 -0
  366. data/lib/image_paradise/cfdg/rays_attack.cfdg +29 -0
  367. data/lib/image_paradise/cfdg/razpad.cfdg +20 -0
  368. data/lib/image_paradise/cfdg/rectangular_distortion.cfdg +169 -0
  369. data/lib/image_paradise/cfdg/recurse_path.cfdg +38 -0
  370. data/lib/image_paradise/cfdg/red_flurry.cfdg +64 -0
  371. data/lib/image_paradise/cfdg/red_horse_tail.cfdg +36 -0
  372. data/lib/image_paradise/cfdg/red_yellow_mosaic.cfdg +26 -0
  373. data/lib/image_paradise/cfdg/rendering_tests.cfdg +183 -0
  374. data/lib/image_paradise/cfdg/repeat_floor_tile_pattern.cfdg +153 -0
  375. data/lib/image_paradise/cfdg/repeat_tile.cfdg +160 -0
  376. data/lib/image_paradise/cfdg/retro_disc.cfdg +736 -0
  377. data/lib/image_paradise/cfdg/ring_growth_variation.cfdg +41 -0
  378. data/lib/image_paradise/cfdg/robot_nightlife.cfdg +25 -0
  379. data/lib/image_paradise/cfdg/rolled_firespiral.cfdg +34 -0
  380. data/lib/image_paradise/cfdg/rose.cfdg +44 -0
  381. data/lib/image_paradise/cfdg/round_tree.cfdg +121 -0
  382. data/lib/image_paradise/cfdg/rubiks_cube.cfdg +120 -0
  383. data/lib/image_paradise/cfdg/ruins.cfdg +19 -0
  384. data/lib/image_paradise/cfdg/sails_and_the_sea.cfdg +27 -0
  385. data/lib/image_paradise/cfdg/salt_crystals.cfdg +26 -0
  386. data/lib/image_paradise/cfdg/saturn.cfdg +105 -0
  387. data/lib/image_paradise/cfdg/scary_pot.cfdg +49 -0
  388. data/lib/image_paradise/cfdg/schematic_worm.cfdg +35 -0
  389. data/lib/image_paradise/cfdg/school_script.cfdg +359 -0
  390. data/lib/image_paradise/cfdg/seahorse.cfdg +78 -0
  391. data/lib/image_paradise/cfdg/seasons.cfdg +115 -0
  392. data/lib/image_paradise/cfdg/segmental_veins.cfdg +66 -0
  393. data/lib/image_paradise/cfdg/select_mayhem.cfdg +28 -0
  394. data/lib/image_paradise/cfdg/seven_folded_symmetry.cfdg +7 -0
  395. data/lib/image_paradise/cfdg/several_cats.cfdg +996 -0
  396. data/lib/image_paradise/cfdg/shadow_box.cfdg +49 -0
  397. data/lib/image_paradise/cfdg/shadowrun_google_maps.cfdg +66 -0
  398. data/lib/image_paradise/cfdg/shadowrun_nightline.cfdg +18 -0
  399. data/lib/image_paradise/cfdg/shards.cfdg +70 -0
  400. data/lib/image_paradise/cfdg/sheet_music.cfdg +213 -0
  401. data/lib/image_paradise/cfdg/shy_guy.cfdg +886 -0
  402. data/lib/image_paradise/cfdg/sierpinski1.cfdg +41 -0
  403. data/lib/image_paradise/cfdg/sierpinski2.cfdg +34 -0
  404. data/lib/image_paradise/cfdg/sierpinski_like_red_swirl.cfdg +46 -0
  405. data/lib/image_paradise/cfdg/sierpinsktri.cfdg +9 -0
  406. data/lib/image_paradise/cfdg/silk_flowers.cfdg +68 -0
  407. data/lib/image_paradise/cfdg/silk_scarf.cfdg +18 -0
  408. data/lib/image_paradise/cfdg/simple_cilia.cfdg +88 -0
  409. data/lib/image_paradise/cfdg/simple_circle_and_square.cfdg +7 -0
  410. data/lib/image_paradise/cfdg/simple_coloured_square.cfdg +38 -0
  411. data/lib/image_paradise/cfdg/simple_ferns.cfdg +40 -0
  412. data/lib/image_paradise/cfdg/simple_fish.cfdg +77 -0
  413. data/lib/image_paradise/cfdg/simple_orchid.cfdg +23 -0
  414. data/lib/image_paradise/cfdg/simple_rounded_colour_wheel.cfdg +10 -0
  415. data/lib/image_paradise/cfdg/simple_sheet_music.cfdg +27 -0
  416. data/lib/image_paradise/cfdg/sincos_pattern_2.cfdg +42 -0
  417. data/lib/image_paradise/cfdg/singing_birdy.cfdg +112 -0
  418. data/lib/image_paradise/cfdg/skyscraper.cfdg +85 -0
  419. data/lib/image_paradise/cfdg/small_golden_rectangle.cfdg +12 -0
  420. data/lib/image_paradise/cfdg/smells_like_layered.cfdg +43 -0
  421. data/lib/image_paradise/cfdg/snowflake.cfdg +26 -0
  422. data/lib/image_paradise/cfdg/snowstorm.cfdg +26 -0
  423. data/lib/image_paradise/cfdg/soar_on_wings.cfdg +8 -0
  424. data/lib/image_paradise/cfdg/soft_core.cfdg +26 -0
  425. data/lib/image_paradise/cfdg/soft_touch.cfdg +20 -0
  426. data/lib/image_paradise/cfdg/some_sort_of_tree.cfdg +57 -0
  427. data/lib/image_paradise/cfdg/spade_ball.cfdg +39 -0
  428. data/lib/image_paradise/cfdg/sparks.cfdg +39 -0
  429. data/lib/image_paradise/cfdg/sperm.cfdg +63 -0
  430. data/lib/image_paradise/cfdg/sphinx.cfdg +17 -0
  431. data/lib/image_paradise/cfdg/spiral_clusters.cfdg +29 -0
  432. data/lib/image_paradise/cfdg/spiral_cross.cfdg +27 -0
  433. data/lib/image_paradise/cfdg/spiral_star.cfdg +19 -0
  434. data/lib/image_paradise/cfdg/spiral_sun.cfdg +39 -0
  435. data/lib/image_paradise/cfdg/spirit.cfdg +47 -0
  436. data/lib/image_paradise/cfdg/splatter_tree.cfdg +61 -0
  437. data/lib/image_paradise/cfdg/spliced.cfdg +27 -0
  438. data/lib/image_paradise/cfdg/spring_parade.cfdg +105 -0
  439. data/lib/image_paradise/cfdg/sprinkle_explosion.cfdg +23 -0
  440. data/lib/image_paradise/cfdg/square_limit_one.cfdg +15 -0
  441. data/lib/image_paradise/cfdg/square_rose.cfdg +75 -0
  442. data/lib/image_paradise/cfdg/square_spiral4.cfdg +41 -0
  443. data/lib/image_paradise/cfdg/square_star.cfdg +39 -0
  444. data/lib/image_paradise/cfdg/squiggle.cfdg +54 -0
  445. data/lib/image_paradise/cfdg/stacked_blob.cfdg +27 -0
  446. data/lib/image_paradise/cfdg/star_explosion.cfdg +38 -0
  447. data/lib/image_paradise/cfdg/star_flower.cfdg +72 -0
  448. data/lib/image_paradise/cfdg/star_mosaic_2007.cfdg +51 -0
  449. data/lib/image_paradise/cfdg/starry_pines.cfdg +79 -0
  450. data/lib/image_paradise/cfdg/stars_tentacles.cfdg +28 -0
  451. data/lib/image_paradise/cfdg/starshape.cfdg +57 -0
  452. data/lib/image_paradise/cfdg/strange_antlers.cfdg +49 -0
  453. data/lib/image_paradise/cfdg/strange_carpet.cfdg +13 -0
  454. data/lib/image_paradise/cfdg/sunset_city.cfdg +112 -0
  455. data/lib/image_paradise/cfdg/sweep.cfdg +946 -0
  456. data/lib/image_paradise/cfdg/swimmers_sperms.cfdg +54 -0
  457. data/lib/image_paradise/cfdg/sword.cfdg +24 -0
  458. data/lib/image_paradise/cfdg/tangle.cfdg +25 -0
  459. data/lib/image_paradise/cfdg/tapestry.cfdg +40 -0
  460. data/lib/image_paradise/cfdg/tasty_loops.cfdg +97 -0
  461. data/lib/image_paradise/cfdg/tendril.cfdg +6 -0
  462. data/lib/image_paradise/cfdg/tentacle_tree.cfdg +57 -0
  463. data/lib/image_paradise/cfdg/terraforming.cfdg +87 -0
  464. data/lib/image_paradise/cfdg/test.cfdg +7 -0
  465. data/lib/image_paradise/cfdg/tetris.cfdg +123 -0
  466. data/lib/image_paradise/cfdg/textured_giraffes.cfdg +122 -0
  467. data/lib/image_paradise/cfdg/the_eye.cfdg +16 -0
  468. data/lib/image_paradise/cfdg/the_go_game.cfdg +81 -0
  469. data/lib/image_paradise/cfdg/the_secret.cfdg +52 -0
  470. data/lib/image_paradise/cfdg/the_third_eye.cfdg +42 -0
  471. data/lib/image_paradise/cfdg/thingy.cfdg +13 -0
  472. data/lib/image_paradise/cfdg/thorns.cfdg +26 -0
  473. data/lib/image_paradise/cfdg/too_many_notes.cfdg +155 -0
  474. data/lib/image_paradise/cfdg/top_down_plant_root.cfdg +43 -0
  475. data/lib/image_paradise/cfdg/top_view_tree.cfdg +79 -0
  476. data/lib/image_paradise/cfdg/transparent_heart.cfdg +31 -0
  477. data/lib/image_paradise/cfdg/tree.cfdg +68 -0
  478. data/lib/image_paradise/cfdg/tree_number_5.cfdg +28 -0
  479. data/lib/image_paradise/cfdg/tree_retro.cfdg +46 -0
  480. data/lib/image_paradise/cfdg/tree_spiral.cfdg +52 -0
  481. data/lib/image_paradise/cfdg/treematic.cfdg +42 -0
  482. data/lib/image_paradise/cfdg/tri_arc.cfdg +16 -0
  483. data/lib/image_paradise/cfdg/tri_squares.cfdg +7 -0
  484. data/lib/image_paradise/cfdg/tube_map.cfdg +112 -0
  485. data/lib/image_paradise/cfdg/turing_morphogenesis.cfdg +788 -0
  486. data/lib/image_paradise/cfdg/twisted_hex_grid.cfdg +26 -0
  487. data/lib/image_paradise/cfdg/twisty_triangel.cfdg +79 -0
  488. data/lib/image_paradise/cfdg/twizeeded.cfdg +19 -0
  489. data/lib/image_paradise/cfdg/uncontrolled_fungus.cfdg +36 -0
  490. data/lib/image_paradise/cfdg/underground.cfdg +72 -0
  491. data/lib/image_paradise/cfdg/underwater.cfdg +75 -0
  492. data/lib/image_paradise/cfdg/unicorn_boi.cfdg +20 -0
  493. data/lib/image_paradise/cfdg/unification_sign.cfdg +52 -0
  494. data/lib/image_paradise/cfdg/urban_connections.cfdg +44 -0
  495. data/lib/image_paradise/cfdg/us_flag.cfdg +109 -0
  496. data/lib/image_paradise/cfdg/v_null.cfdg +89 -0
  497. data/lib/image_paradise/cfdg/very_simple_flower.cfdg +45 -0
  498. data/lib/image_paradise/cfdg/very_simple_hexagon.cfdg +16 -0
  499. data/lib/image_paradise/cfdg/very_simple_octagon.cfg +13 -0
  500. data/lib/image_paradise/cfdg/vigorous_vine.cfdg +45 -0
  501. data/lib/image_paradise/cfdg/ville_topview.cfdg +70 -0
  502. data/lib/image_paradise/cfdg/vine.cfdg +176 -0
  503. data/lib/image_paradise/cfdg/vinyl.cfdg +12 -0
  504. data/lib/image_paradise/cfdg/violet_ribbons.cfdg +45 -0
  505. data/lib/image_paradise/cfdg/voronoi_2.cfdg +61 -0
  506. data/lib/image_paradise/cfdg/wald.cfdg +46 -0
  507. data/lib/image_paradise/cfdg/water_ink.cfdg +71 -0
  508. data/lib/image_paradise/cfdg/water_monster.cfdg +33 -0
  509. data/lib/image_paradise/cfdg/web.cfdg +53 -0
  510. data/lib/image_paradise/cfdg/weighting_demo.cfdg +16 -0
  511. data/lib/image_paradise/cfdg/weird_spots.cfdg +15 -0
  512. data/lib/image_paradise/cfdg/welcome.cfdg +109 -0
  513. data/lib/image_paradise/cfdg/where_do_you_want_to_go_today.cfdg +632 -0
  514. data/lib/image_paradise/cfdg/where_is_the_head.cfdg +28 -0
  515. data/lib/image_paradise/cfdg/where_to_go.cfdg +62 -0
  516. data/lib/image_paradise/cfdg/willow.cfdg +39 -0
  517. data/lib/image_paradise/cfdg/witch_poison.cfdg +58 -0
  518. data/lib/image_paradise/cfdg/wooden_floor.cfdg +95 -0
  519. data/lib/image_paradise/cfdg/writhing.cfdg +15 -0
  520. data/lib/image_paradise/cfdg/wrooom_cars.cfdg +124 -0
  521. data/lib/image_paradise/cfdg/xmas_code.cfdg +101 -0
  522. data/lib/image_paradise/cfdg/xmas_tree.cfdg +70 -0
  523. data/lib/image_paradise/cfdg/yellow_cactus.cfdg +52 -0
  524. data/lib/image_paradise/cfdg/yet_another_explosion.cfdg +46 -0
  525. data/lib/image_paradise/cfdg/yin_yang_taijitu_pattern.cfdg +44 -0
  526. data/lib/image_paradise/cfdg/yog.cfdg +27 -0
  527. data/lib/image_paradise/cfdg/yurbanis_m.cfdg +27 -0
  528. data/lib/image_paradise/cfdg/zen_tree.cfdg +79 -0
  529. data/lib/image_paradise/cfdg/ziggy_flowers.cfdg +44 -0
  530. data/lib/image_paradise/cfdg/zodiac.cfdg +43 -0
  531. data/lib/image_paradise/chunky_png/chunky_png.rb +54 -0
  532. data/lib/image_paradise/colours/colours.rb +55 -0
  533. data/lib/image_paradise/confree_generator/confree_generator.rb +793 -0
  534. data/lib/image_paradise/confree_generator/constants.rb +93 -0
  535. data/lib/image_paradise/constants/constants.rb +50 -0
  536. data/lib/image_paradise/constants/image_file_types.rb +27 -0
  537. data/lib/image_paradise/crop/crop.rb +429 -0
  538. data/lib/image_paradise/gm_support.rb +34 -0
  539. data/lib/image_paradise/graphs/accumulator_bar.rb +29 -0
  540. data/lib/image_paradise/graphs/area.rb +64 -0
  541. data/lib/image_paradise/graphs/bar.rb +117 -0
  542. data/lib/image_paradise/graphs/bar_conversion.rb +53 -0
  543. data/lib/image_paradise/graphs/base.rb +1392 -0
  544. data/lib/image_paradise/graphs/bezier.rb +45 -0
  545. data/lib/image_paradise/graphs/bullet.rb +115 -0
  546. data/lib/image_paradise/graphs/deprecated.rb +42 -0
  547. data/lib/image_paradise/graphs/dot.rb +129 -0
  548. data/lib/image_paradise/graphs/line.rb +328 -0
  549. data/lib/image_paradise/graphs/mini/bar.rb +42 -0
  550. data/lib/image_paradise/graphs/mini/legend.rb +109 -0
  551. data/lib/image_paradise/graphs/mini/pie.rb +42 -0
  552. data/lib/image_paradise/graphs/mini/side_bar.rb +41 -0
  553. data/lib/image_paradise/graphs/net.rb +133 -0
  554. data/lib/image_paradise/graphs/photo_bar.rb +106 -0
  555. data/lib/image_paradise/graphs/pie.rb +139 -0
  556. data/lib/image_paradise/graphs/scatter.rb +264 -0
  557. data/lib/image_paradise/graphs/scene.rb +216 -0
  558. data/lib/image_paradise/graphs/side_bar.rb +144 -0
  559. data/lib/image_paradise/graphs/side_stacked_bar.rb +116 -0
  560. data/lib/image_paradise/graphs/spider.rb +163 -0
  561. data/lib/image_paradise/graphs/stacked_area.rb +73 -0
  562. data/lib/image_paradise/graphs/stacked_bar.rb +68 -0
  563. data/lib/image_paradise/graphs/stacked_mixin.rb +30 -0
  564. data/lib/image_paradise/graphs/themes.rb +117 -0
  565. data/lib/image_paradise/graphs.rb +36 -0
  566. data/lib/image_paradise/graphviz/README.md +2 -0
  567. data/lib/image_paradise/graphviz/generate_graphviz_image.rb +276 -0
  568. data/lib/image_paradise/gui/gtk3/cfdg_widget/cfdg_widget.rb +1452 -0
  569. data/lib/image_paradise/gui/gtk3/cfdg_widget/connect_skeleton.rb +46 -0
  570. data/lib/image_paradise/gui/gtk3/image_editor/connect_skeleton.rb +126 -0
  571. data/lib/image_paradise/gui/gtk3/image_editor/image_editor.rb +2003 -0
  572. data/lib/image_paradise/identify.rb +184 -0
  573. data/lib/image_paradise/image_paradise.rb +153 -0
  574. data/lib/image_paradise/image_to_ascii/image_to_ascii.rb +187 -0
  575. data/lib/image_paradise/image_to_pdf/image_to_pdf.rb +99 -0
  576. data/lib/image_paradise/label/README.md +2 -0
  577. data/lib/image_paradise/label/simple_label.rb +206 -0
  578. data/lib/image_paradise/logo/IMGUR_LOGO.png +0 -0
  579. data/lib/image_paradise/project/project.rb +30 -0
  580. data/lib/image_paradise/requires/common_base_requires.rb +17 -0
  581. data/lib/image_paradise/requires/require_colours.rb +9 -0
  582. data/lib/image_paradise/requires/require_gtk_components.rb +8 -0
  583. data/lib/image_paradise/requires/require_image_to_ascii.rb +7 -0
  584. data/lib/image_paradise/requires/require_the_image_paradise_project.rb +42 -0
  585. data/lib/image_paradise/requires/require_toplevel_methods.rb +21 -0
  586. data/lib/image_paradise/rotate/README.md +2 -0
  587. data/lib/image_paradise/rotate/rotate.rb +124 -0
  588. data/lib/image_paradise/shell/interactive.rb +156 -0
  589. data/lib/image_paradise/svg/README.md +5 -0
  590. data/lib/image_paradise/svg/circle.rb +106 -0
  591. data/lib/image_paradise/svg/feature.rb +48 -0
  592. data/lib/image_paradise/svg/rectangle.rb +154 -0
  593. data/lib/image_paradise/svg/svg.rb +102 -0
  594. data/lib/image_paradise/toplevel_methods/add_black_border_to_this_image.rb +94 -0
  595. data/lib/image_paradise/toplevel_methods/create_animated_gif.rb +49 -0
  596. data/lib/image_paradise/toplevel_methods/crop.rb +29 -0
  597. data/lib/image_paradise/toplevel_methods/e.rb +16 -0
  598. data/lib/image_paradise/toplevel_methods/esystem.rb +19 -0
  599. data/lib/image_paradise/toplevel_methods/extract_text_from_this_image.rb +56 -0
  600. data/lib/image_paradise/toplevel_methods/file_related_code.rb +110 -0
  601. data/lib/image_paradise/toplevel_methods/flip_image_left_right.rb +59 -0
  602. data/lib/image_paradise/toplevel_methods/font_related_methods.rb +62 -0
  603. data/lib/image_paradise/toplevel_methods/greyscale_this_image.rb +76 -0
  604. data/lib/image_paradise/toplevel_methods/gui.rb +19 -0
  605. data/lib/image_paradise/toplevel_methods/help.rb +30 -0
  606. data/lib/image_paradise/toplevel_methods/interlace.rb +33 -0
  607. data/lib/image_paradise/toplevel_methods/is_an_image_file.rb +18 -0
  608. data/lib/image_paradise/toplevel_methods/make_this_image_transparent.rb +40 -0
  609. data/lib/image_paradise/toplevel_methods/menu.rb +110 -0
  610. data/lib/image_paradise/toplevel_methods/merge_these_images.rb +49 -0
  611. data/lib/image_paradise/toplevel_methods/mirror_image.rb +28 -0
  612. data/lib/image_paradise/toplevel_methods/misc.rb +1603 -0
  613. data/lib/image_paradise/toplevel_methods/negate.rb +36 -0
  614. data/lib/image_paradise/toplevel_methods/png_to_svg.rb +38 -0
  615. data/lib/image_paradise/toplevel_methods/quality.rb +34 -0
  616. data/lib/image_paradise/toplevel_methods/resized.rb +43 -0
  617. data/lib/image_paradise/toplevel_methods/roebe.rb +440 -0
  618. data/lib/image_paradise/toplevel_methods/thumbnail.rb +54 -0
  619. data/lib/image_paradise/toplevel_methods/to_png.rb +106 -0
  620. data/lib/image_paradise/toplevel_methods/wallpaper.rb +51 -0
  621. data/lib/image_paradise/toplevel_methods/write_this_text.rb +89 -0
  622. data/lib/image_paradise/utility_scripts/black_white.rb +92 -0
  623. data/lib/image_paradise/utility_scripts/create_new_image.rb +110 -0
  624. data/lib/image_paradise/utility_scripts/image_border.rb +226 -0
  625. data/lib/image_paradise/utility_scripts/image_gallery/image_gallery.rb +305 -0
  626. data/lib/image_paradise/utility_scripts/image_manipulations.rb +316 -0
  627. data/lib/image_paradise/utility_scripts/magic_card_border.rb +215 -0
  628. data/lib/image_paradise/utility_scripts/optimizer.rb +444 -0
  629. data/lib/image_paradise/utility_scripts/random_text_to_image.rb +364 -0
  630. data/lib/image_paradise/utility_scripts/text_on_image.rb +311 -0
  631. data/lib/image_paradise/utility_scripts/to_gif.rb +93 -0
  632. data/lib/image_paradise/utility_scripts/to_jpg.rb +82 -0
  633. data/lib/image_paradise/version/version.rb +19 -0
  634. data/lib/image_paradise/www/cfdg.cgi +25 -0
  635. data/lib/image_paradise/www/imagemagick/imagemagick.cgi +266 -0
  636. data/lib/image_paradise/yaml/README.md +2 -0
  637. data/lib/image_paradise/yaml/arc.yml +0 -0
  638. data/lib/image_paradise/yaml/circle.yml +6 -0
  639. data/lib/image_paradise/yaml/rectangle.yml +6 -0
  640. data/lib/image_paradise.rb +5 -0
  641. data/test/16x16_red_square_image_for_testing.png +0 -0
  642. data/test/misc/README.md +3 -0
  643. data/test/misc/testing_filling_up_with_circles.rb +65 -0
  644. data/test/testing_confree_generator.rb +8 -0
  645. data/test/testing_crop.rb +19 -0
  646. data/test/testing_image_magick_commands.rb +39 -0
  647. data/test/testing_image_paradise.rb +49 -0
  648. data/test/testing_the_svg_component.html +261 -0
  649. data/test/testing_the_svg_component.rb +106 -0
  650. metadata +762 -0
@@ -0,0 +1,1603 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # require 'image_paradise/toplevel_methods/misc.rb'
6
+ # ImageParadise.resize_by_percent
7
+ # ImageParadise.draw_as_specified_from_the_yaml_file
8
+ # ImageParadise.magic_card_border
9
+ # ImageParadise.rounded_corner(ARGV)
10
+ # ImageParadise.img2pdf(ARGV)
11
+ # =========================================================================== #
12
+ module ImageParadise
13
+
14
+ require 'fileutils'
15
+ require 'image_paradise/project/project.rb'
16
+ require 'image_paradise/toplevel_methods/esystem.rb'
17
+ require 'image_paradise/toplevel_methods/is_an_image_file.rb'
18
+
19
+ # ========================================================================= #
20
+ # === @hash
21
+ # ========================================================================= #
22
+ @hash = {}
23
+
24
+ # ========================================================================= #
25
+ # === :store_image_files_in_this_directory
26
+ # ========================================================================= #
27
+ @hash[:store_image_files_in_this_directory] = nil
28
+
29
+ # ========================================================================= #
30
+ # === ImageParadise.shrink_the_width_of_this_image_to_that_width
31
+ #
32
+ # This method can be used to shrink an image to a specified width,
33
+ # in n px.
34
+ # ========================================================================= #
35
+ def self.shrink_the_width_of_this_image_to_that_width(
36
+ this_image,
37
+ that_width = 150,
38
+ overwrite_the_old_image = false,
39
+ &block
40
+ )
41
+ if this_image.is_a? Array
42
+ this_image = this_image.first
43
+ end
44
+ # ======================================================================= #
45
+ # === Handle blocks given to this method
46
+ # ======================================================================= #
47
+ if block_given?
48
+ yielded = yield
49
+ case yielded
50
+ # === :overwrite_the_old_image
51
+ when :overwrite_the_old_image
52
+ overwrite_the_old_image = true
53
+ end
54
+ end
55
+ output_file = File.dirname(this_image)+
56
+ '/output_'+File.basename(this_image)
57
+ _ = "convert #{this_image} -resize #{that_width} #{output_file}"
58
+ e
59
+ esystem(_)
60
+ e
61
+ if overwrite_the_old_image and File.exist?(output_file)
62
+ FileUtils.mv(output_file, this_image)
63
+ end
64
+ return output_file
65
+ end
66
+
67
+ # ========================================================================= #
68
+ # === ImageParadise.size_of?
69
+ #
70
+ # This method will determine the size of an image file (aka width and
71
+ # height).
72
+ #
73
+ # Usage examples:
74
+ #
75
+ # ImageParadise.size_of?('/home/x/video/reallife/family/thumbnails/thumbnail_for_etwa_04.04.2005_Timba_in_irgendeinem_Zimmer.png')
76
+ # ImageParadise.size_of? "Susanne_03.jpg" # => "474x631"
77
+ #
78
+ # ========================================================================= #
79
+ def self.size_of?(i)
80
+ if i.is_a? Array
81
+ i = i.first
82
+ end
83
+ result = `identify -format "%wx%h" #{i}`
84
+ return result
85
+ end
86
+
87
+ # ========================================================================= #
88
+ # === ImageParadise.create_julia_set
89
+ # ========================================================================= #
90
+ def self.create_julia_set
91
+ output_file = 'julia_set.png'
92
+ _ = 'magick -size 400x400 xc:gray -fx " \
93
+ Xi=2.4*i/w-1.2; \
94
+ Yj=2.4*j/h-1.2; \
95
+ for (pixel=0.0, (hypot(Xi,Yj) < 2.0) && (pixel < 1.0), \
96
+ delta=Xi^2-Yj^2; \
97
+ Yj=2.0*Xi*Yj+0.2; \
98
+ Xi=delta+0.4; \
99
+ pixel+=0.00390625 \
100
+ ); \
101
+ pixel == 1.0 ? 0.0 : pixel" \
102
+ \( -size 1x1 xc:white xc:red xc:orange xc:yellow xc:green1 xc:cyan xc:blue \
103
+ xc:blueviolet xc:white -reverse +append -filter Cubic -resize 1024x1! \) \
104
+ -clut -rotate -90 '+output_file
105
+ esystem(_)
106
+ return File.absolute_path(output_file)
107
+ end
108
+
109
+ # ========================================================================= #
110
+ # === ImageParadise.charcoal
111
+ #
112
+ # The ‑charcoal variable of convert needs an associated factor. It should
113
+ # ideally be a small number, even less than 1, in order to achieve
114
+ # something that resembles a charcoal drawing - otherwise you may get
115
+ # heavy blobs of black.
116
+ #
117
+ # Invocation example:
118
+ #
119
+ # ImageParadise.charcoal "Water.jpg"
120
+ # x = ImageParadise.charcoal('/Depot/j/girl.jpg')
121
+ #
122
+ # ========================================================================= #
123
+ def self.charcoal(
124
+ i = 'foobar.png',
125
+ radius_to_apply = 1.2, # or 4px or 5px
126
+ output_file = :infer_from_the_input_filename
127
+ )
128
+ case output_file
129
+ # ======================================================================= #
130
+ # === :infer_from_the_input_filename
131
+ # ======================================================================= #
132
+ when :infer_from_the_input_filename
133
+ output_file = File.absolute_path('output_'+File.basename(i))
134
+ end
135
+ esystem "convert "\
136
+ "-charcoal #{radius_to_apply} "\
137
+ "#{i} "\
138
+ "#{output_file}"
139
+ return output_file # Return the output-file here.
140
+ end
141
+
142
+ # ========================================================================= #
143
+ # === ImageParadise.create_gradient
144
+ #
145
+ # Usage example:
146
+ #
147
+ # ImageParadise.create_gradient(:venetian, '500x500', 'gray50')
148
+ #
149
+ # ========================================================================= #
150
+ def self.create_gradient(
151
+ how = :venetian,
152
+ width_and_height = '500x500',
153
+ colour_to_use_for_the_background = 'gray50'
154
+ )
155
+ output_file = "gradient_#{how}.png"
156
+ esystem "convert "\
157
+ "-size #{width_and_height} "\
158
+ "gradient: \\( +clone +clone \\) "\
159
+ "-background #{colour_to_use_for_the_background} "\
160
+ "-compose Modulusadd "\
161
+ "-flatten "\
162
+ "#{output_file}"
163
+ return File.absolute_path(output_file) # Return the output-file here.
164
+ end
165
+
166
+ # ========================================================================= #
167
+ # === ImageParadise.monochrome
168
+ #
169
+ # Usage example:
170
+ #
171
+ # x = ImageParadise.monochrome('/Depot/j/NJOY/VidaGuerra.jpg')
172
+ #
173
+ # ========================================================================= #
174
+ def self.monochrome(
175
+ path_to_the_input_image = ARGV
176
+ )
177
+ if path_to_the_input_image.is_a? Array
178
+ path_to_the_input_image = path_to_the_input_image.first
179
+ end
180
+ output_filename = 'output_monochrome_'+
181
+ File.basename(path_to_the_input_image)
182
+ cmd = "convert #{path_to_the_input_image} -monochrome #{output_filename}"
183
+ esystem(cmd)
184
+ return File.absolute_path(output_filename)
185
+ end
186
+
187
+ # ========================================================================= #
188
+ # === ImageParadise.canny
189
+ #
190
+ # Usage example:
191
+ #
192
+ # x = ImageParadise.canny('/Depot/j/NJOY/VidaGuerra.jpg')
193
+ #
194
+ # ========================================================================= #
195
+ def self.canny(
196
+ path_to_the_input_image = ARGV,
197
+ value_to_use = '0x1'
198
+ )
199
+ if path_to_the_input_image.is_a? Array
200
+ path_to_the_input_image = path_to_the_input_image.first
201
+ end
202
+ output_filename = 'output_monochrome_'+
203
+ File.basename(path_to_the_input_image)
204
+ cmd = "convert #{path_to_the_input_image} -canny #{value_to_use} #{output_filename}"
205
+ esystem(cmd)
206
+ return File.absolute_path(output_filename)
207
+ end
208
+
209
+ # ========================================================================= #
210
+ # === ImageParadise.resize_by_percent
211
+ #
212
+ # This method will make use of ImageMagick to resize an image. So,
213
+ # naturally, in order to use this functionality the user has to
214
+ # have the "convert" binary which is part of ImageMagick.
215
+ #
216
+ # The direct API would be like this:
217
+ #
218
+ # convert -resize <new size in %> <name of existing image> <name of new image>
219
+ # convert -resize 40% image1.jpg output.jpg
220
+ #
221
+ # Usage example for the API in ImageParadise:
222
+ #
223
+ # ImageParadise.resize('/Depot/j/foobar.jpg','20%')
224
+ #
225
+ # ========================================================================= #
226
+ def self.resize_by_percent(
227
+ path_to_the_image = '',
228
+ by_how_much = :default # 75% percent is default.
229
+ )
230
+ result = []
231
+ case path_to_the_image
232
+ when /^-?-?help$/i
233
+ e 'The general syntax is:'
234
+ e
235
+ e ' shrink foobar.jpg 40%'
236
+ e ' shrink /Depot/jj/LEGO_COP.png 40%'
237
+ exit
238
+ end
239
+ by_how_much = by_how_much.first if by_how_much.is_a? Array
240
+ case by_how_much
241
+ when nil, :default
242
+ by_how_much = 75
243
+ end
244
+ by_how_much = by_how_much.to_s # Must be a String past this point.
245
+ by_how_much = by_how_much.dup if by_how_much.frozen?
246
+ # ======================================================================= #
247
+ # Work on the input as Array next:
248
+ # ======================================================================= #
249
+ [path_to_the_image].flatten.compact.each {|path_to_this_image|
250
+ if File.exist? path_to_this_image
251
+ by_how_much << '%' unless by_how_much.end_with?('%')
252
+ output_filename = File.absolute_path(
253
+ 'output_'+
254
+ File.basename(path_to_this_image)
255
+ )
256
+ # =================================================================== #
257
+ # Build up the command next:
258
+ # =================================================================== #
259
+ cmd = "convert -resize #{by_how_much} #{path_to_this_image} #{output_filename}"
260
+ esystem(cmd)
261
+ result << output_filename # Build up our return-value here.
262
+ else
263
+ e "No file exists at #{path_to_this_image}."
264
+ end
265
+ }
266
+ return result
267
+ end; self.instance_eval { alias resize_by_percentage resize_by_percent } # === ImageParadise.resize_by_percentage
268
+ self.instance_eval { alias percent resize_by_percent } # === ImageParadise.percent
269
+ self.instance_eval { alias resize resize_by_percent } # === ImageParadise.resize
270
+
271
+ # ========================================================================= #
272
+ # === ImageParadise.remove_comment
273
+ # ========================================================================= #
274
+ def self.remove_comment(i)
275
+ i = i.to_s
276
+ esystem 'convert '+i+' -strip -set comment "" new_'+i
277
+ end
278
+
279
+ # ========================================================================= #
280
+ # === ImageParadise.lighten_this_image
281
+ #
282
+ # This method can be used to "lighten" an image, that is, to
283
+ # improve its brightness and contrast at the same time.
284
+ #
285
+ # The second argument tells convert by how much it should change.
286
+ #
287
+ # Usage examples:
288
+ #
289
+ # require 'image_paradise'; ImageParadise.lighten_this_image('circle_of_fire.png')
290
+ # require 'image_paradise'; ImageParadise.lighten_this_image('circle_of_light.png')
291
+ #
292
+ # ========================================================================= #
293
+ def self.lighten_this_image(
294
+ i,
295
+ by = '15x15'
296
+ )
297
+ i = i.to_s
298
+ esystem 'convert -brightness-contrast '+by.to_s+' '+i+' out_'+i
299
+ end
300
+
301
+ # ========================================================================= #
302
+ # === ImageParadise.remove_metadata_from_this_image
303
+ #
304
+ # This method will strip meta-data from an image.
305
+ # ========================================================================= #
306
+ def self.remove_metadata_from_this_image(
307
+ i, output_file = :default
308
+ )
309
+ case output_file
310
+ # ======================================================================= #
311
+ # === :default
312
+ # ======================================================================= #
313
+ when :default
314
+ output_file = "output_#{i}"
315
+ end
316
+ _ = "convert -strip #{i} #{output_file}"
317
+ esystem _
318
+ end
319
+
320
+ # ========================================================================= #
321
+ # === ImageParadise.store_image_files_in_this_directory=
322
+ # ========================================================================= #
323
+ def self.store_image_files_in_this_directory=(
324
+ i = '/home/x/data/images/STUDIUM/'
325
+ )
326
+ i << '/' unless i.end_with? '/' # Directories must have a trailing '/' token.
327
+ @hash[:store_image_files_in_this_directory] = i
328
+ end
329
+
330
+ # ========================================================================= #
331
+ # === ImageParadise.store_image_files_in_this_directory?
332
+ # ========================================================================= #
333
+ def self.store_image_files_in_this_directory?
334
+ @hash[:store_image_files_in_this_directory]
335
+ end
336
+
337
+ # ========================================================================= #
338
+ # === ImageParadise.log_dir?
339
+ # ========================================================================= #
340
+ def self.log_dir?
341
+ '/tmp/image_paradise/'
342
+ end; self.instance_eval { alias log_directory? log_dir? } # === ImageParadise.log_directory?
343
+
344
+ # ========================================================================= #
345
+ # === ImageParadise.increment_this_number_by_one
346
+ # ========================================================================= #
347
+ def self.increment_this_number_by_one(basename)
348
+ basename = basename.dup
349
+ scanned = basename.scan(/\d+$/).flatten.first.to_s
350
+ # ======================================================================= #
351
+ # scanned may now be '019'.
352
+ # ======================================================================= #
353
+ new_number = scanned.to_i + 1
354
+ # ======================================================================= #
355
+ # We must also look to expand to its original size again.
356
+ # ======================================================================= #
357
+ new_number = new_number.to_s.rjust(scanned.size, '0')
358
+ basename.sub!(/\d+$/, new_number)
359
+ basename
360
+ end
361
+
362
+ # ========================================================================= #
363
+ # === ImageParadise.return_draw_rectangle
364
+ #
365
+ # This method will return the commandline option to use for drawing
366
+ # a rectangle via the commandline.
367
+ # ========================================================================= #
368
+ def self.return_draw_rectangle(
369
+ start_position = [10, 10], # This is the x,y start position.
370
+ end_position = [70, 90], # This is width, then height.
371
+ use_this_colour = :black
372
+ )
373
+ "-fill #{use_this_colour} "\
374
+ "-draw "\
375
+ "'rectangle #{start_position[0]},#{start_position[1]} "\
376
+ "#{end_position[0]},#{end_position[1]}'" # Width.
377
+ end
378
+
379
+ # ========================================================================= #
380
+ # === ImageParadise.add_this_comment_to_that_image
381
+ #
382
+ # This method can be used to add a comment to an image.
383
+ #
384
+ # The first argument is the comment that the user wants to add to a
385
+ # particular image.
386
+ # ========================================================================= #
387
+ def self.add_this_comment_to_that_image(
388
+ comment,
389
+ image = 'foobar.png',
390
+ output_file = :default
391
+ )
392
+ case output_file
393
+ # ======================================================================= #
394
+ # === :default
395
+ # ======================================================================= #
396
+ when :default
397
+ output_file = "output_#{File.basename(image)}"
398
+ end
399
+ _ = 'convert -comment "'+comment.to_s+'" '+image+' '+
400
+ output_file
401
+ esystem _
402
+ end
403
+
404
+ # ========================================================================= #
405
+ # === ImageParadise.gamma_correct_this_image
406
+ #
407
+ # Note that red, green and blue specifiy the gamma correction for each
408
+ # colour channel in the image.
409
+ # ========================================================================= #
410
+ def self.gamma_correct_this_image(
411
+ i,
412
+ red = :default,
413
+ green = :default,
414
+ blue = :default
415
+ )
416
+ case red
417
+ # ======================================================================= #
418
+ # === :default
419
+ # ======================================================================= #
420
+ when :default
421
+ red = 0.7
422
+ end
423
+ case green
424
+ # ======================================================================= #
425
+ # === :default
426
+ # ======================================================================= #
427
+ when :default
428
+ green = red
429
+ end
430
+ case blue
431
+ # ======================================================================= #
432
+ # === :default
433
+ # ======================================================================= #
434
+ when :default
435
+ blue = red
436
+ end
437
+ _ = 'convert -gamma '+red.to_s+
438
+ ','+green.to_s+','+
439
+ blue.to_s+' '+i+' '+
440
+ 'output_'+File.basename(i)
441
+ esystem _
442
+ end
443
+
444
+ # ========================================================================= #
445
+ # === ImageParadise.morph_these_images
446
+ #
447
+ # This method can be used to morph together two images.
448
+ #
449
+ # This is currently hardcoded/set to two images as input.
450
+ #
451
+ # Any files that will be newly created OTHER than the main
452
+ # output file will be deleted.
453
+ # ========================================================================= #
454
+ def self.morph_these_images(
455
+ image1,
456
+ image2,
457
+ output_file = :default
458
+ )
459
+ case output_file
460
+ # ======================================================================= #
461
+ # === :default
462
+ # ======================================================================= #
463
+ when :default
464
+ output_file = 'output.png'
465
+ end
466
+ _ = 'convert -morph 1,2 '+image1.to_s+' '+image2.to_s+' '+
467
+ output_file
468
+ esystem _
469
+ modified_output_filename = output_file.sub(/\./,'-1.')
470
+ if File.exist? modified_output_filename
471
+ FileUtils.mv(modified_output_filename, output_file)
472
+ end
473
+ # ======================================================================= #
474
+ # Next, clean up a bit.
475
+ # ======================================================================= #
476
+ if File.exist? output_file.sub(/\./,'-0.')
477
+ File.delete(output_file.sub(/\./,'-0.'))
478
+ end
479
+ if File.exist? output_file.sub(/\./,'-2.')
480
+ File.delete(output_file.sub(/\./,'-2.'))
481
+ end
482
+ return output_file
483
+ end
484
+
485
+ # ========================================================================= #
486
+ # === ImageParadise.circle_masked
487
+ #
488
+ # This will "paint" a circle over the main image in use.
489
+ #
490
+ # Usage example:
491
+ #
492
+ # ImageParadise.circle_masked('SANDRA.jpg')
493
+ # ImageParadise.circle_masked('SANDRA.jpg', 'output.png')
494
+ #
495
+ # ========================================================================= #
496
+ def self.circle_masked(
497
+ i = '*.jpg',
498
+ output_file = 'output.png'
499
+ )
500
+ _ = 'convert '+i.to_s+' -alpha set \( +clone -distort DePolar 0 '\
501
+ '-virtual-pixel HorizontalTile -background None -distort Polar '\
502
+ '0 \) -compose Dst_In -composite -trim +repage '+
503
+ output_file.to_s
504
+ esystem _
505
+ end
506
+
507
+ # ========================================================================= #
508
+ # === ImageParadise.torn_paper
509
+ #
510
+ # This will create a torn-paper effect.
511
+ #
512
+ # Usage example:
513
+ #
514
+ # ImageParadise.torn_paper('SANDRA.jpg')
515
+ # ImageParadise.torn_paper('SANDRA.jpg', 'output.png')
516
+ #
517
+ # ========================================================================= #
518
+ def self.torn_paper(
519
+ i = '*.jpg',
520
+ threshold = :default, # This means 50, basically.
521
+ output_file = :default
522
+ )
523
+ case output_file
524
+ # ======================================================================= #
525
+ # === :default
526
+ # ======================================================================= #
527
+ when :default
528
+ output_file = 'output.png'
529
+ end
530
+ case threshold
531
+ # ======================================================================= #
532
+ # === :default
533
+ # ======================================================================= #
534
+ when :default
535
+ threshold = 50
536
+ end
537
+ _ = 'convert '+i.to_s+' \( +clone -alpha extract -virtual-pixel '\
538
+ 'black -spread 10 -blur 0x3 -threshold '+threshold.to_s+
539
+ '% -spread 1 -blur 0x.7 \) '\
540
+ ' -alpha off -compose Copy_Opacity -composite '+
541
+ output_file.to_s
542
+ esystem _
543
+ end
544
+
545
+ # ========================================================================= #
546
+ # === ImageParadise.shadow
547
+ #
548
+ # This will create a shadow effect. The second argument is the colour
549
+ # that can be used, defaulting to :steelblue if omitted.
550
+ #
551
+ # Usage example:
552
+ #
553
+ # ImageParadise.shadow('Leeann_Tweeden.png', :blue)
554
+ #
555
+ # ========================================================================= #
556
+ def self.shadow(
557
+ i = '*.jpg',
558
+ colour_to_use = :default, # This means 50, basically.
559
+ output_file = :default,
560
+ width = 3 # 3px width.
561
+ )
562
+ case output_file
563
+ # ======================================================================= #
564
+ # === :default
565
+ # ======================================================================= #
566
+ when :default
567
+ output_file = 'output.png'
568
+ end
569
+ case colour_to_use
570
+ when :default
571
+ colour_to_use = :steelblue
572
+ end
573
+ _ = 'convert '+i.to_s+' -alpha set '\
574
+ '\( +clone -background '+
575
+ colour_to_use.to_s+' -shadow 60x0+'+width.to_s+'+'+width.to_s+' \) '\
576
+ '+swap -background none -mosaic '+
577
+ output_file.to_s
578
+ esystem _
579
+ end
580
+
581
+ # ========================================================================= #
582
+ # === ImageParadise.add_this_text_to_the_image
583
+ #
584
+ # This method can be used to add text to a given image.
585
+ #
586
+ # Usage examples:
587
+ #
588
+ # ImageParadise.add_this_text_to_the_image('fun inside','Susanne_03.jpg')
589
+ # ImageParadise.add_this_text_to_the_image('fun inside','Susanne_03.jpg', :lightgreen)
590
+ #
591
+ # ========================================================================= #
592
+ def self.add_this_text_to_the_image(
593
+ this_text = 'Foobar and Hello World!',
594
+ image = 'foobar.png',
595
+ use_this_background_colour = :white, # :khaki
596
+ output_image = 'output.png',
597
+ append_or_prepend = :append
598
+ )
599
+ _ = 'convert '+image.to_s+
600
+ ' -background '+use_this_background_colour.to_s+' '
601
+ _ << '-font Times-New-Roman -pointsize 25 '
602
+ _ << " label:'#{this_text}' ".dup
603
+ _ << '+swap ' if append_or_prepend == :prepend
604
+ _ << '-gravity center '\
605
+ '-append '+ # -append means "add to the bottom of the image.
606
+ output_image
607
+ esystem _
608
+ end
609
+
610
+ # ========================================================================= #
611
+ # === ImageParadise.montage
612
+ #
613
+ # This will aggregate the images together into one big image, the
614
+ # "montage".
615
+ #
616
+ # By default this method will pick up all .jpg files from the current
617
+ # working directory.
618
+ # ========================================================================= #
619
+ def self.montage(
620
+ i = '*.jpg',
621
+ output_file = :default,
622
+ shall_we_autolabel_the_images = false,
623
+ frame_value_to_use = '-frame 2'
624
+ )
625
+ case shall_we_autolabel_the_images
626
+ when :do_autolabel
627
+ shall_we_autolabel_the_images = true
628
+ end
629
+ case output_file
630
+ # ======================================================================= #
631
+ # === :default
632
+ # ======================================================================= #
633
+ when :default
634
+ output_file = 'output.png'
635
+ end
636
+ cmd = "montage".dup
637
+ if shall_we_autolabel_the_images
638
+ cmd << ' -label %f'
639
+ end
640
+ cmd << " #{frame_value_to_use}"
641
+ cmd << " #{i}"
642
+ cmd << " #{output_file}"
643
+ esystem cmd
644
+ end
645
+
646
+ # ========================================================================= #
647
+ # === ImageParadise.chop_away_outer_pixels
648
+ #
649
+ # This method will chop away outer pixels from a given image.
650
+ # ========================================================================= #
651
+ def self.chop_away_outer_pixels(
652
+ i = 'foobar.png',
653
+ chop_away_n_pixels = 5, # 5px
654
+ output_file = 'output.png'
655
+ )
656
+ esystem "convert -gravity NorthWest -chop "\
657
+ "#{chop_away_n_pixels}x#{chop_away_n_pixels} "\
658
+ "-trim #{i} "\
659
+ "#{output_file}"
660
+ end
661
+
662
+ # ========================================================================= #
663
+ # === ImageParadise.blur
664
+ #
665
+ # The blur command-line option of ImageMagick applies a Gaussian-based
666
+ # blurring operation to the given image at hand. It is also called
667
+ # "gaussian".
668
+ #
669
+ # The argument that has to be provided is the radius of the blur,
670
+ # with an optional standard deviation.
671
+ #
672
+ # The default for this method is to specify just a radius, without
673
+ # a standard deviation. If you want to specify a standard deviation
674
+ # as well, use something like "12x2" rather than e. g. "12" for the
675
+ # radius_to_apply argument.
676
+ #
677
+ # Invocation example:
678
+ #
679
+ # ImageParadise.blur "Water.jpg"
680
+ #
681
+ # ========================================================================= #
682
+ def self.blur(
683
+ i = 'foobar.png',
684
+ radius_to_apply = 12, # 5px
685
+ output_file = 'output.png'
686
+ )
687
+ esystem "convert "\
688
+ "-blur #{radius_to_apply} "\
689
+ "#{i} "\
690
+ "#{output_file}"
691
+ return output_file
692
+ end
693
+
694
+ # ========================================================================= #
695
+ # === ImageParadise.colour_fill_this_image
696
+ #
697
+ # This method can be used to fill an image with a specific colour,
698
+ # such as blue or green. It's like you overlay that colour over
699
+ # the given image at hand.
700
+ #
701
+ # Invocation example:
702
+ #
703
+ # ImageParadise.colour_fill_this_image("Water.jpg", :blue, '33%', 'output.png')
704
+ #
705
+ # ========================================================================= #
706
+ def self.colour_fill_this_image(
707
+ i = 'foobar.png',
708
+ colour_to_use = :steelblue,
709
+ n_percent = '10%',
710
+ output_file = 'output.png'
711
+ )
712
+ esystem "convert "\
713
+ "-fill #{colour_to_use} "\
714
+ "-colorize #{n_percent.to_s.delete('%')} "\
715
+ "#{i} "\
716
+ "#{output_file}"
717
+ return output_file
718
+ end
719
+
720
+ # ========================================================================= #
721
+ # === ImageParadise.black_hole
722
+ #
723
+ # This method, alias aliased onto ImageParadise.implode, can transform
724
+ # an image starting from the center of said image, to look as if a black
725
+ # hole emerged. It will thus distort the image as if it is sucking the
726
+ # pixels into it.
727
+ #
728
+ # The implode command takes only one argument, which is the factor by
729
+ # which to apply the effect. The size of the effect on the image is
730
+ # that factor argument.
731
+ #
732
+ # Invocation example:
733
+ #
734
+ # ImageParadise.implode("foobar.jpg", 2, 'output.png')
735
+ #
736
+ # ========================================================================= #
737
+ def self.black_hole(
738
+ i = 'foobar.png',
739
+ implode_by_n = 1,
740
+ output_file = 'output.png'
741
+ )
742
+ esystem "convert "\
743
+ "-implode #{implode_by_n} "\
744
+ "#{i} "\
745
+ "#{output_file}"
746
+ return output_file
747
+ end; self.instance_eval { alias implode black_hole } # === ImageParadise.implode
748
+
749
+ # ========================================================================= #
750
+ # === ImageParadise.noise
751
+ #
752
+ # Invocation example:
753
+ #
754
+ # ImageParadise.noise("foobar.jpg", 2, 'output.png')
755
+ #
756
+ # ========================================================================= #
757
+ def self.noise(
758
+ i = 'foobar.png',
759
+ by_n = 1,
760
+ output_file = 'output.png'
761
+ )
762
+ esystem "convert "\
763
+ "-noise #{by_n} "\
764
+ "#{i} "\
765
+ "#{output_file}"
766
+ return output_file
767
+ end
768
+
769
+ # ========================================================================= #
770
+ # === ImageParadise.raise
771
+ #
772
+ # The raise effect provides beveled edges for an image. You can
773
+ # specify the height and width for this bevel, as well as a
774
+ # direction for the bevel.
775
+ #
776
+ # 2x3 here means a horizontal bevel of 2 pixels and a
777
+ # vertical bevel size of 3 pixels.
778
+ #
779
+ # Invocation example:
780
+ #
781
+ # ImageParadise.raise("foobar.jpg", '2x3', 'output.png')
782
+ #
783
+ # ========================================================================= #
784
+ def self.raise(
785
+ i = 'foobar.png',
786
+ raise_by = '2x2',
787
+ output_file = 'output.png'
788
+ )
789
+ esystem "convert "\
790
+ "-raise #{raise_by} "\
791
+ "#{i} "\
792
+ "#{output_file}"
793
+ return output_file
794
+ end
795
+
796
+ # ========================================================================= #
797
+ # === ImageParadise.sepia_tone
798
+ #
799
+ # Invocation example:
800
+ #
801
+ # ImageParadise.sepia_tone("foobar.jpg", '80', 'output.png')
802
+ #
803
+ # ========================================================================= #
804
+ def self.sepia_tone(
805
+ i = 'foobar.png',
806
+ n_percent = '80',
807
+ output_file = 'output.png'
808
+ )
809
+ esystem "convert "\
810
+ "-sepia-tone #{n_percent.to_s.delete('%')}% "\
811
+ "#{i} "\
812
+ "#{output_file}"
813
+ return output_file
814
+ end; self.instance_eval { alias sepia_filter sepia_tone } # === ImageParadise.sepia_filter
815
+
816
+ # ========================================================================= #
817
+ # === ImageParadise.shade_transformation
818
+ #
819
+ # This will apply a shade onto the main image.
820
+ #
821
+ # A shade effect in this context refers to simulating having a distant
822
+ # light source cast a shadow on the image.
823
+ #
824
+ # This effect can be created by specifying an azimuth and elevation
825
+ # for the light source. The azimuth is the angle of the light source,
826
+ # with the following values:
827
+ #
828
+ # 0 degrees: north
829
+ # 90 degrees: east
830
+ # 180 degrees: south
831
+ # 270 degrees: west
832
+ #
833
+ # The elevation is the height of the light source. For example, to
834
+ # specify light from the east at height of 100, the following
835
+ # commandline can be used:
836
+ #
837
+ # convert -shade 90x100 input.jpg output.jpg
838
+ #
839
+ # Invocation example:
840
+ #
841
+ # ImageParadise.shade_transformation("foobar.jpg", '80', 'output.png')
842
+ #
843
+ # ========================================================================= #
844
+ def self.shade_transformation(
845
+ i = 'foobar.png',
846
+ modify_how = '90x100',
847
+ output_file = 'output.png'
848
+ )
849
+ esystem "convert "\
850
+ "-shade #{modify_how.to_s.delete('%')} "\
851
+ "#{i} "\
852
+ "#{output_file}"
853
+ return output_file
854
+ end; self.instance_eval { alias shade shade_transformation } # === ImageParadise.shade
855
+ self.instance_eval { alias shade_effect shade_transformation } # === ImageParadise.shade_effect
856
+
857
+ # ========================================================================= #
858
+ # === ImageParadise.threshold
859
+ # ========================================================================= #
860
+ def self.threshold(
861
+ i = 'foobar.png',
862
+ modify_how = '90%',
863
+ output_file = 'output.png'
864
+ )
865
+ esystem "convert "\
866
+ "-threshold #{modify_how.to_s} "\
867
+ "#{i} "\
868
+ "#{output_file}"
869
+ return output_file
870
+ end
871
+
872
+ # ========================================================================= #
873
+ # === ImageParadise.sharpen
874
+ #
875
+ # This method can be used to sharpen an existing image.
876
+ #
877
+ # Invocation example:
878
+ #
879
+ # ImageParadise.sharpen("foobar.jpg", '3', 'output.png')
880
+ #
881
+ # ========================================================================= #
882
+ def self.sharpen(
883
+ i = 'foobar.png',
884
+ modify_how = '1',
885
+ output_file = 'output.png'
886
+ )
887
+ esystem "convert "\
888
+ "-sharpen #{modify_how.to_s} "\
889
+ "#{i} "\
890
+ "#{output_file}"
891
+ return output_file
892
+ end
893
+
894
+ # ========================================================================= #
895
+ # === ImageParadise.wave
896
+ # ========================================================================= #
897
+ def self.wave(
898
+ i = 'foobar.png',
899
+ modify_how = '8x90%',
900
+ output_file = 'output.png'
901
+ )
902
+ esystem "convert "\
903
+ "-wave #{modify_how.to_s} "\
904
+ "#{i} "\
905
+ "#{output_file}"
906
+ return output_file
907
+ end
908
+
909
+ # ========================================================================= #
910
+ # === ImageParadise.contrast
911
+ #
912
+ # Invocation example:
913
+ #
914
+ # ImageParadise.contrast("foobar.jpg", '1', 'output.png')
915
+ #
916
+ # ========================================================================= #
917
+ def self.contrast(
918
+ i = 'foobar.png',
919
+ n_times = '1',
920
+ output_file = 'output.png'
921
+ )
922
+ plus_or_minus = '-'
923
+ if n_times.is_a?(String) and n_times.start_with?('-')
924
+ plus_or_minus = '+'
925
+ end
926
+ contrast_string = "#{plus_or_minus}contrast " * n_times.to_i
927
+ esystem "convert "\
928
+ "#{contrast_string} "\
929
+ "#{i} "\
930
+ "#{output_file}"
931
+ return output_file
932
+ end
933
+
934
+ # ========================================================================= #
935
+ # === ImageParadise.reduce_contrast
936
+ # ========================================================================= #
937
+ def self.reduce_contrast(
938
+ i = 'foobar.png',
939
+ n_times = '-1',
940
+ output_file = 'output.png'
941
+ )
942
+ ImageParadise.contrast(i, n_times, output_file)
943
+ end
944
+
945
+ # ========================================================================= #
946
+ # === ImageParadise.flip_this_image_up_to_bottom
947
+ #
948
+ # Invocation example:
949
+ #
950
+ # ImageParadise.flip_this_image_up_to_bottom("/Depot/NJOY/WaterGirl.png", 'output.png')
951
+ #
952
+ # ========================================================================= #
953
+ def self.flip_this_image_up_to_bottom(
954
+ i = 'foobar.png',
955
+ output_file = 'output.png'
956
+ )
957
+ esystem "convert "\
958
+ "-flip "\
959
+ "#{i} "\
960
+ "#{output_file}"
961
+ return output_file
962
+ end; self.instance_eval { alias flip_image_up_to_bottom flip_this_image_up_to_bottom } # === ImageParadise.flip_image_up_to_bottom
963
+
964
+ # ========================================================================= #
965
+ # === ImageParadise.solarize
966
+ #
967
+ # This method can be used to lighten-up an existing image.
968
+ #
969
+ # Invocation example:
970
+ #
971
+ # ImageParadise.solarize("foobar.jpg", '3', 'output.png')
972
+ #
973
+ # ========================================================================= #
974
+ def self.solarize(
975
+ i = 'foobar.png',
976
+ modify_how = '90',
977
+ output_file = 'output.png'
978
+ )
979
+ esystem "convert "\
980
+ "-solarize #{modify_how.to_s} "\
981
+ "#{i} "\
982
+ "#{output_file}"
983
+ return output_file
984
+ end
985
+
986
+ # ========================================================================= #
987
+ # === ImageParadise.normalize
988
+ #
989
+ # Normalization is the process of improving the contrast in an image
990
+ # so that it uses all the available color range.
991
+ #
992
+ # Invocation example:
993
+ #
994
+ # ImageParadise.normalize("foobar.jpg", 'output.png')
995
+ #
996
+ # ========================================================================= #
997
+ def self.normalize(
998
+ i = 'foobar.png',
999
+ output_file = 'output.png'
1000
+ )
1001
+ esystem "convert "\
1002
+ "-normalize "\
1003
+ "#{i} "\
1004
+ "#{output_file}"
1005
+ return output_file
1006
+ end
1007
+
1008
+ # ========================================================================= #
1009
+ # === ImageParadise.shear
1010
+ #
1011
+ # The shear effect puts the input image at an angle. You can tilt
1012
+ # the image horizontally and vertically in both directions (in other
1013
+ # words, from left to right, from right to left, from top to bottom,
1014
+ # and from bottom to top).
1015
+ #
1016
+ # The tilt is specified as an angle; for example, in the
1017
+ # horizontal direction, a negative tilt is a tilt to the left,
1018
+ # and a positive tilt is a tilt to the right.
1019
+ #
1020
+ # Invocation example:
1021
+ #
1022
+ # ImageParadise.shear("foobar.jpg", 'output.png')
1023
+ #
1024
+ # ========================================================================= #
1025
+ def self.shear(
1026
+ i = 'foobar.png',
1027
+ modify_how = '45',
1028
+ output_file = 'output.png'
1029
+ )
1030
+ esystem "convert "\
1031
+ "-shear #{modify_how.to_s} "\
1032
+ "#{i} "\
1033
+ "#{output_file}"
1034
+ return output_file
1035
+ end
1036
+
1037
+ # ========================================================================= #
1038
+ # === ImageParadise.horizontal_append
1039
+ #
1040
+ # This will append images together, in a vertical manner.
1041
+ #
1042
+ # Invocation example:
1043
+ #
1044
+ # ImageParadise.horizontal_append(["foobar1.jpg", "foobar2.jpg"], 'output.png')
1045
+ #
1046
+ # ========================================================================= #
1047
+ def self.horizontal_append(
1048
+ these_images = ARGV,
1049
+ output_file = 'output.png',
1050
+ use_this_as_border = nil
1051
+ )
1052
+ cmd = "convert +append #{these_images.join(' ')}".dup
1053
+ cmd << " #{output_file}"
1054
+ if use_this_as_border
1055
+ cmd << "-border #{use_this_as_border}"
1056
+ end
1057
+ esystem cmd
1058
+ return output_file
1059
+ end
1060
+
1061
+ # ========================================================================= #
1062
+ # === ImageParadise.vertical_append
1063
+ #
1064
+ # This will append images together, in a vertical manner.
1065
+ #
1066
+ # Invocation example:
1067
+ #
1068
+ # ImageParadise.vertical_append(["foobar1.jpg", "foobar2.jpg"], 'output.png')
1069
+ #
1070
+ # ========================================================================= #
1071
+ def self.vertical_append(
1072
+ these_images = ARGV,
1073
+ output_file = 'output.png',
1074
+ use_this_as_border = nil
1075
+ )
1076
+ cmd = "convert -append #{these_images.join(' ')}".dup
1077
+ cmd << " #{output_file}"
1078
+ if use_this_as_border
1079
+ cmd << "-border #{use_this_as_border}"
1080
+ end
1081
+ esystem cmd
1082
+ return output_file
1083
+ end
1084
+
1085
+ # ========================================================================= #
1086
+ # === ImageParadise.to_webp
1087
+ #
1088
+ # This will convert the given image to the WebP format.
1089
+ # ========================================================================= #
1090
+ def self.to_webp(
1091
+ this_image,
1092
+ output_file = :append,
1093
+ quality_to_use = 80
1094
+ )
1095
+ case output_file
1096
+ # ======================================================================= #
1097
+ # === :append
1098
+ # ======================================================================= #
1099
+ when :append,
1100
+ :default
1101
+ output_file = this_image.dup.delete_suffix(
1102
+ File.extname(this_image)
1103
+ )+'.webp'
1104
+ end
1105
+ esystem 'magick '+this_image+
1106
+ ' -quality '+quality_to_use.to_s+
1107
+ ' -define webp:lossless=true '+
1108
+ output_file
1109
+ end
1110
+
1111
+ # ========================================================================= #
1112
+ # === ImageParadise.rounded_corner_for_jpg_files
1113
+ #
1114
+ # This method is specifically for .jpg files.
1115
+ # ========================================================================= #
1116
+ def self.rounded_corner_for_jpg_files(i = '*jpg')
1117
+ _ = 'convert '+i.to_s+' \
1118
+ \( +clone -crop 16x16+0+0 -fill white -colorize 100% \
1119
+ -draw \'fill black circle 15,15 15,0\' \
1120
+ -background White -alpha shape \
1121
+ \( +clone -flip \) \( +clone -flop \) \( +clone -flip \) \
1122
+ \) -flatten rounded_corners_white.jpg'
1123
+ end
1124
+
1125
+ # ========================================================================= #
1126
+ # === ImageParadise.rounded_corner
1127
+ #
1128
+ # This method can create a rounded corner to an existing image.
1129
+ #
1130
+ # The polygon value allows one to create ellipsoid areas, which
1131
+ # ultimately is the effect that you can see in a "rounded corner"
1132
+ # image.
1133
+ #
1134
+ # Usage example:
1135
+ #
1136
+ # ImageParadise.rounded_corner 'RandomBeachGal.jpg'
1137
+ #
1138
+ # ========================================================================= #
1139
+ def self.rounded_corner(
1140
+ i = 'input_image.png',
1141
+ output_file = :default,
1142
+ black_polygon = '0,0 0,15 15,0'
1143
+ )
1144
+ if i.is_a? Array
1145
+ i = i.join(' ').strip
1146
+ end
1147
+ i = i.to_s
1148
+ case output_file
1149
+ # ======================================================================= #
1150
+ # === :default
1151
+ # ======================================================================= #
1152
+ when :default
1153
+ output_file = File.absolute_path(File.basename("output_#{i}"))
1154
+ end
1155
+ _ = 'convert '+i+' '+
1156
+ '\( +clone -alpha extract '+
1157
+ '-draw \'fill black polygon '+black_polygon.to_s+
1158
+ ' fill white circle 15,15 15,0\' '+
1159
+ '\( +clone -flip \) -compose Multiply -composite '+
1160
+ '\( +clone -flop \) -compose Multiply -composite '+
1161
+ '\) -alpha off -compose CopyOpacity -composite '+
1162
+ output_file.to_s
1163
+ esystem _
1164
+ return output_file
1165
+ end
1166
+
1167
+ # ========================================================================= #
1168
+ # === ImageParadise.return_draw_line
1169
+ #
1170
+ # We name the start point "Point A" and the end point "Point B".
1171
+ # ========================================================================= #
1172
+ def self.return_draw_line(
1173
+ start_position = [10, 10], # This is the x,y start position. Point A.
1174
+ end_position = [70, 90], # This is the x,y end position. Point B.
1175
+ use_this_colour = :black,
1176
+ optional_hash = {}
1177
+ )
1178
+ _ = ''.dup
1179
+ _ << "-fill #{use_this_colour} "
1180
+ if optional_hash.has_key? :strokewidth
1181
+ _ << "-stroke #{use_this_colour} "
1182
+ _ << "-strokewidth #{optional_hash[:strokewidth].to_s} "
1183
+ end
1184
+ _ << '-draw '
1185
+ _ << "'line #{start_position[0]},#{start_position[1]} "\
1186
+ "#{end_position[0]},#{end_position[1]}'"
1187
+ return _
1188
+ end
1189
+
1190
+ # ========================================================================= #
1191
+ # === ImageParadise.draw_as_specified_from_the_yaml_file
1192
+ # ========================================================================= #
1193
+ def self.draw_as_specified_from_the_yaml_file(
1194
+ target_file =
1195
+ # ::ImageParadise.project_base_directory?+'yaml/rectangle.yml',
1196
+ ::ImageParadise.project_base_directory?+'yaml/circle.yml',
1197
+ output_file = 'output.png'
1198
+ )
1199
+ require 'yaml'
1200
+ if File.exist? target_file
1201
+ key = 'circle'
1202
+ dataset = YAML.load_file(target_file)
1203
+ if dataset[key].has_key? 'resolution'
1204
+ width, height = dataset[key]['resolution'].split('x')
1205
+ else
1206
+ e 'A key called `resolution` is mandatory.'
1207
+ exit
1208
+ end
1209
+ _ = ''.dup
1210
+ _ << 'convert'
1211
+ if dataset[key].has_key? 'total_size'
1212
+ _ << " -size #{dataset[key]['total_size']}"
1213
+ else
1214
+ _ << " -size #{500}x#{500}"
1215
+ end
1216
+ _ << ' -stroke '+dataset[key]['strokecolour'].to_s
1217
+ _ << ' -strokewidth '+dataset[key]['strokewidth'].to_s
1218
+ _ << ' -fill '+dataset[key]['fill_colour']
1219
+ case key
1220
+ when 'circle'
1221
+ # The 250,250 part should be half the total size.
1222
+ _ << ' -draw "circle 250,250 '+width.to_s+','+width.to_s+'"'
1223
+ when 'rectangle'
1224
+ if dataset[key]['round_rectangle'] == true
1225
+ _ << ' -draw "roundRectangle 0,0 '+width.to_s+','+height.to_s+' 12,12"'
1226
+ else
1227
+ _ << ' -draw "rectangle 0,0 '+width.to_s+','+height.to_s+'"'
1228
+ end
1229
+ end
1230
+ _ << ' xc:white'
1231
+ _ << " #{output_file}"
1232
+ end
1233
+ esystem _
1234
+ end
1235
+
1236
+ # ========================================================================= #
1237
+ # === ImageParadise.drop_shadow_effect
1238
+ #
1239
+ # Note that this will create a border that is currently invariant.
1240
+ # In the long run this may be different, allowing us to pick a
1241
+ # border width, but for now, this is the way it is.
1242
+ #
1243
+ # Usage example:
1244
+ #
1245
+ # ImageParadise.drop_shadow_effect 'RandomBeachGal.jpg'
1246
+ #
1247
+ # ========================================================================= #
1248
+ def self.drop_shadow_effect(
1249
+ i = 'input_image.png',
1250
+ use_this_colour = :black,
1251
+ output_file = :default
1252
+ )
1253
+ if i.is_a? Array
1254
+ i = i.join(' ').strip
1255
+ end
1256
+ i = i.to_s
1257
+ case output_file
1258
+ when :default
1259
+ output_file = File.absolute_path(File.basename("output_#{i}"))
1260
+ end
1261
+ _ = 'convert '+i+' '+
1262
+ '\( -clone 0 -background '+use_this_colour.to_s+
1263
+ ' -shadow 80x3+12+12 \) \( -clone 0 -background '+use_this_colour+
1264
+ ' -shadow 80x3-12-12 \) -reverse -background none '\
1265
+ '-layers merge +repage '+
1266
+ output_file.to_s
1267
+ esystem _
1268
+ return output_file
1269
+ end
1270
+
1271
+ # =========================================================================== #
1272
+ # === ImageParadise.find_image_center
1273
+ #
1274
+ # gives back the image center
1275
+ # =========================================================================== #
1276
+ def self.find_image_center(image)
1277
+ return [ (image.columns/2), (image.rows/2) ]
1278
+ end
1279
+
1280
+ # =========================================================================== #
1281
+ # === ImageParadise.create_shape
1282
+ #
1283
+ # This method can be used to create various pre-determined shapes,
1284
+ # such as a gel.
1285
+ # =========================================================================== #
1286
+ def self.create_shape(
1287
+ which_shape = :gel
1288
+ )
1289
+ case which_shape
1290
+ # ========================================================================= #
1291
+ # === :gel
1292
+ #
1293
+ # This will create a gel-shape - a fat ellipse.
1294
+ # ========================================================================= #
1295
+ when :gel,
1296
+ :default
1297
+ _ = "convert -size 100x60 xc:none
1298
+ -fill red -draw 'circle 25,30 10,30'
1299
+ -draw 'circle 75,30 90,30'
1300
+ -draw 'rectangle 25,15 75,45'
1301
+ gel_shape.png".tr("\n", ' ').squeeze(' ')
1302
+ esystem _
1303
+ end
1304
+ end
1305
+
1306
+ # =========================================================================== #
1307
+ # === ImageParadise.darken_the_borders
1308
+ # =========================================================================== #
1309
+ def self.darken_the_borders(
1310
+ of_this_image = 'gel_shape.png'
1311
+ )
1312
+ _ = "convert "+of_this_image+"
1313
+ \( +clone -alpha extract -blur 0x2 -shade 0x90 -normalize
1314
+ -blur 0x2 +level 60,100% -alpha On \)
1315
+ -compose Multiply -composite "\
1316
+ "gel_border.png".
1317
+ tr("\n", ' ').squeeze(' ')
1318
+ esystem _
1319
+ end
1320
+
1321
+ # ========================================================================= #
1322
+ # === ImageParadise.return_random_image
1323
+ #
1324
+ # This method will return a random image from the given argument, which
1325
+ # is assumed to be a directory. It defaults to my home setup.
1326
+ #
1327
+ # A random image will then be returned, if there is at the least one
1328
+ # image in that directory.
1329
+ #
1330
+ # Usage example for my home setup:
1331
+ #
1332
+ # ImageParadise.return_random_image(:njoy)
1333
+ #
1334
+ # ========================================================================= #
1335
+ def self.return_random_image(
1336
+ i = Dir.pwd
1337
+ )
1338
+ # ======================================================================= #
1339
+ # Handle special cases first.
1340
+ # ======================================================================= #
1341
+ case i
1342
+ when 0, :adoptopn
1343
+ i = ENV['IMG_RPG'].to_s+'/ADOPTION/'
1344
+ # ======================================================================= #
1345
+ # === njoy
1346
+ # ======================================================================= #
1347
+ when 1, :njoy
1348
+ i = ENV['IMG'].to_s+'/NJOY/'
1349
+ end
1350
+ i = i.to_s.dup
1351
+ unless i.end_with? '/'
1352
+ i << '/'
1353
+ end
1354
+ if File.directory? i
1355
+ all_entries = Dir["#{i}*"]
1356
+ return all_entries.sample
1357
+ else
1358
+ raise 'This method (.return_random_image()) '\
1359
+ 'requires a valid directory as argument.'
1360
+ end
1361
+ end
1362
+
1363
+ # ========================================================================= #
1364
+ # === ImageParadise.identify_this_image
1365
+ # ========================================================================= #
1366
+ def self.identify_this_image(i)
1367
+ result = `magick identify -format "%wx%h %xx%y" #{i}` # width-height and DPI
1368
+ return result
1369
+ end
1370
+
1371
+ # ========================================================================= #
1372
+ # === ImageParadise.default_position=
1373
+ # ========================================================================= #
1374
+ def self.default_position=(i = :default)
1375
+ case i
1376
+ # ======================================================================= #
1377
+ # === :default
1378
+ #
1379
+ # This value can be changed to other values.
1380
+ # ======================================================================= #
1381
+ when :default
1382
+ i = '35,125'
1383
+ end
1384
+ @hash[:default_position] = i
1385
+ end
1386
+
1387
+ # ========================================================================= #
1388
+ # === ImageParadise.default_position?
1389
+ # ========================================================================= #
1390
+ def self.default_position?
1391
+ @hash[:default_position]
1392
+ end
1393
+
1394
+ # ========================================================================= #
1395
+ # === ImageParadise.default_colour=
1396
+ #
1397
+ # This method can be used to set (assign) a default colour. Curiously
1398
+ # enough, ImageMagick appears to default to black colour for text
1399
+ # when writing something.
1400
+ # ========================================================================= #
1401
+ def self.default_colour=(i = :default) # :steelblue is the default colour
1402
+ case i
1403
+ # ======================================================================= #
1404
+ # === :default
1405
+ # ======================================================================= #
1406
+ when :default
1407
+ i = :steelblue
1408
+ end
1409
+ @hash[:default_colour] = i
1410
+ end
1411
+
1412
+ # ========================================================================= #
1413
+ # === ImageParadise.default_colour?
1414
+ # ========================================================================= #
1415
+ def self.default_colour?
1416
+ @hash[:default_colour]
1417
+ end
1418
+
1419
+ # ========================================================================= #
1420
+ # === ImageParadise.is_this_image_animated?
1421
+ #
1422
+ # Usage examples:
1423
+ #
1424
+ # ImageParadise.is_this_image_animated?('/Depot/jjjj/NJOY/SneezAndPop.gif') # => true
1425
+ # ImageParadise.is_this_image_animated?("TANAKA.jpg") # => false
1426
+ #
1427
+ # ========================================================================= #
1428
+ def self.is_this_image_animated?(i)
1429
+ if i.is_a? Array
1430
+ i = i.first
1431
+ end
1432
+ result = `identify -format "%n" #{i}`.to_i
1433
+ result > 1
1434
+ end
1435
+
1436
+ # ========================================================================= #
1437
+ # === ImageParadise.img2pdf
1438
+ #
1439
+ # This method depends on the external software (written in python)
1440
+ # called img2pdf.
1441
+ #
1442
+ # This method will return the output-file that is generated.
1443
+ # ========================================================================= #
1444
+ def self.img2pdf(
1445
+ work_on_these_files = '*.jpg'
1446
+ )
1447
+ if work_on_these_files.is_a?(Array) and work_on_these_files.empty?
1448
+ work_on_these_files = '*.jpg'
1449
+ end
1450
+ if work_on_these_files.is_a?(String) and work_on_these_files.include?('*')
1451
+ work_on_these_files = Dir[work_on_these_files] # Assume input such as '*.jpg'
1452
+ end
1453
+ work_on_these_files = work_on_these_files.join(' ').strip if work_on_these_files.is_a?(Array)
1454
+ work_on_these_files_as_string = work_on_these_files
1455
+ # ======================================================================= #
1456
+ # Next we will determine the output-filename to use. This is important
1457
+ # because if we use this method in a batch-manner then we do not want
1458
+ # to overwrite the same output name - thus we need to make this a
1459
+ # little bit more dynamic in its behaviour.
1460
+ # ======================================================================= #
1461
+ use_this_name = work_on_these_files_as_string
1462
+ if use_this_name.include? ' '
1463
+ use_this_name = 'aggregated_name'
1464
+ end
1465
+ # ======================================================================= #
1466
+ # Next build the output-file. This needs to take the absolute
1467
+ # path into consideration if the input contains a '/' token.
1468
+ # ======================================================================= #
1469
+ output_file = File.absolute_path(File.dirname(use_this_name))+
1470
+ '/output_aggregated_document_'+
1471
+ 'taken_from_'+
1472
+ File.basename(
1473
+ use_this_name.delete_suffix(
1474
+ File.extname(use_this_name)
1475
+ )
1476
+ )+
1477
+ '.pdf'
1478
+ cmd = 'img2pdf -o '+output_file+' '+
1479
+ work_on_these_files_as_string
1480
+ esystem(cmd)
1481
+ return output_file
1482
+ end
1483
+
1484
+ # ========================================================================= #
1485
+ # === ImageParadise.width_of_this_image?
1486
+ # ========================================================================= #
1487
+ def self.width_of_this_image?(i)
1488
+ return `convert #{i} -print "%w" /dev/null`.to_i
1489
+ end
1490
+
1491
+ # ========================================================================= #
1492
+ # === ImageParadise.height_of_this_image?
1493
+ #
1494
+ # Usage example:
1495
+ #
1496
+ # ImageParadise.height_of_this_image?("/home/x/data/images/fotos/urlaub/10.10.2004_Trieste_Miramare_Teich.jpg")
1497
+ #
1498
+ # ========================================================================= #
1499
+ def self.height_of_this_image?(i)
1500
+ if File.exist? i
1501
+ return `convert #{i} -print "%h" /dev/null`.to_i
1502
+ else
1503
+ puts 'The file at '+i.to_s+' could not be found.'
1504
+ return 0
1505
+ end
1506
+ end
1507
+
1508
+ # ========================================================================= #
1509
+ # === ImageParadise.width_height_of_this_image?
1510
+ #
1511
+ # Usage example:
1512
+ #
1513
+ # ImageParadise.width_height_of_this_image?("/home/x/data/images/fotos/urlaub/10.10.2004_Trieste_Miramare_Teich.jpg")
1514
+ #
1515
+ # ========================================================================= #
1516
+ def self.width_height_of_this_image?(i)
1517
+ return `convert #{i} -print "%wx%h" /dev/null`
1518
+ end
1519
+
1520
+ # ========================================================================= #
1521
+ # === ImageParadise.embed_the_filename_into_this_image
1522
+ #
1523
+ # This method will automatically attach the filename onto a
1524
+ # particular images. So if the filename is "foobar.jpg" then
1525
+ # the method will attach the word "foobar" to the image.
1526
+ #
1527
+ # The gravity-argument determines <b>where</b> the text will
1528
+ # appear.
1529
+ #
1530
+ # The second argument to this method is the Hash that determines
1531
+ # various options, such as font-size, which font to use and so
1532
+ # forth.
1533
+ #
1534
+ # Usage examples:
1535
+ #
1536
+ # ImageParadise.embed_the_filename_into_this_image('TANAKA.jpg')
1537
+ # ImageParadise.embed_the_filename_into_this_image('/foo/bar/')
1538
+ # ImageParadise.embed_the_filename_into_this_image('/Depot/jjj/NJOY/')
1539
+ #
1540
+ # ========================================================================= #
1541
+ def self.embed_the_filename_into_this_image(
1542
+ this_image = 'foobar.jpg',
1543
+ hash_options = {
1544
+ font_size: 30,
1545
+ font_to_use: 'Luxi-Mono',
1546
+ colour_to_use: :orangered # Or :white.
1547
+ }
1548
+ )
1549
+ # ======================================================================= #
1550
+ # Obtain the font size to use next:
1551
+ # ======================================================================= #
1552
+ font_size_to_use = hash_options[:font_size]
1553
+ use_this_font = hash_options[:font_to_use]
1554
+ colour_to_use = hash_options[:colour_to_use]
1555
+ this_image = [this_image].flatten.compact
1556
+ if this_image and this_image.first and
1557
+ File.directory?(this_image.first)
1558
+ # ===================================================================== #
1559
+ # Working on a directory instead.
1560
+ # ===================================================================== #
1561
+ _ = "#{this_image.first}/".squeeze('/')
1562
+ array = Dir[_+'*.jpg']+
1563
+ Dir[_+'*.png']+
1564
+ Dir[_+'*.gif']
1565
+ array.flatten!
1566
+ array.reject! {|entry| # Exclude animated .gif files.
1567
+ entry.end_with?('.gif') and
1568
+ ::ImageParadise.is_this_image_animated?(entry)
1569
+ }
1570
+ this_image = array
1571
+ end
1572
+ # ======================================================================= #
1573
+ # Batch process this next - treat it as an Array:
1574
+ # ======================================================================= #
1575
+ this_image.each {|this_image_specifically|
1576
+ output_filename = 'output_'+File.basename(this_image_specifically).
1577
+ delete_suffix(
1578
+ File.extname(this_image_specifically)
1579
+ )
1580
+ extname = File.extname(this_image_specifically)
1581
+ filename_to_use = File.basename(this_image_specifically).
1582
+ delete_suffix(
1583
+ File.extname(this_image_specifically)
1584
+ ).tr('_', ' ')
1585
+ cmd_to_use = "convert #{this_image_specifically} "\
1586
+ "-font #{use_this_font} "\
1587
+ "-pointsize #{font_size_to_use} "\
1588
+ "-draw \"gravity northwest fill #{colour_to_use} text 0,15 '#{filename_to_use}' \" "\
1589
+ "#{output_filename}"+extname
1590
+ e
1591
+ esystem(cmd_to_use)
1592
+ e
1593
+ }
1594
+ end
1595
+
1596
+ end
1597
+
1598
+ if __FILE__ == $PROGRAM_NAME
1599
+ ImageParadise.add_this_comment_to_that_image(
1600
+ 'Hello world!',
1601
+ '/Depot/NJOY/Vratinaka_01.jpg'
1602
+ )
1603
+ end