image_paradise 0.4.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of image_paradise might be problematic. Click here for more details.

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