image_paradise 0.4.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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