1/* 2 3 ImageMagick operations edited by Alan Gibson (aka "snibgo"; snibgo at earthling dot net). 4 1-Apr-2014 5 Minor corrections to Geometry_widget and Alpha. 6 Added loads of widgets and Menuactions. 7 Not fully tested. 8 5-Apr-2014 9 Many more menu actions. 10 Reorganised Magick menu. 11 10-Apr-2014 12 Many more menu actions. 13 11-Apr-2014 jcupitt 14 Split to separate Magick.def 15 13-Apr-2014 snibgo 16 Put "new image" items into sub-menu. 17 New class VirtualPixlBack. 18 17-Apr-2014 snibgo 19 Many small changes. 20 A few new menu options. 21 Created sub-menu for multi-input operations. 22 3-May-2014 jcupitt 23 Put quotes around ( in shadow to help unix 24 25 Last update: 17-Apr-2014. 26 27 For details of ImageMagick operations, see http://www.imagemagick.org/script/command-line-options.php etc. 28*/ 29 30// We don't need Noop. 31/*=== 32Magick_noop_item = class 33 Menuaction "_Noop" "no operation" { 34 action x = class 35 _result { 36 _vislevel = 3; 37 38 command = Magick.command [ 39 "\"%s\"", 40 "\"%s\"" 41 ]; 42 43 _result = Magick.system command x; 44 } 45} 46===*/ 47 48Magick_testPar_item = class 49 Menuaction "_TestPar" "no operation" { 50 action x = class 51 _result { 52 _vislevel = 3; 53 54 command = Magick.command [ 55 "\"%s\"", 56 "( +clone ) +append ", 57 "\"%s\"" 58 ]; 59 60 _result = Magick.system command x; 61 } 62} 63 64/* Removed Read_item and Write_item, much better to use nip2 load/save image. 65 * Plus they can load all libMagick formats anyway. 66 */ 67 68 69// Put "new image" items into sub-menu 70Magick_NewImageMenu_item = class 71 Menupullright "_New image" "make a new image" { 72 73 Magick_newcanvas_item = class 74 Menuaction "_Solid colour" "make image of solid colour" { 75 action = class 76 _result { 77 _vislevel = 3; 78 79 size = Magick.Size_widget; 80 colour = Magick.generalcol_widget; 81 command = Magick.command [ 82 size._flag, 83 "\"canvas:" ++ colour._flag ++ "\"", 84 "\"%s\"" 85 ]; 86 87 _result = Magick.system0 command; 88 } 89 } 90 91 Magick_builtin_item = class 92 Menuaction "_Built-in image" "create a built-in image" { 93 action = class 94 _result { 95 _vislevel = 3; 96 97 builtin = Magick.builtin_widget; 98 command = Magick.command [ 99 builtin._flag, 100 "\"%s\"" 101 ]; 102 103 _result = Magick.system0 command; 104 } 105 } 106 107 Magick_gradient_item = class 108 Menuaction "_Gradient" "make a linear gradient between two colours" { 109 action = class 110 _result { 111 _vislevel = 3; 112 113 size = Magick.Size_widget; 114 topColour = Magick.generalcol_widget; 115 bottomColour = Magick.generalcol_widget; 116 117 command = Magick.command [ 118 size._flag, 119 concat ["\"gradient:", 120 topColour._flag, "-", bottomColour._flag, "\""], 121 "\"%s\"" 122 ]; 123 124 _result = Magick.system0 command; 125 } 126 } 127 128 Magick_hald_item = class 129 Menuaction "_Hald-clut image" "create an identity hald-clut image" { 130 action = class 131 _result { 132 _vislevel = 3; 133 134 order = Expression "order" 8; 135 command = Magick.command [ 136 "hald:" ++ print order.expr, 137 "\"%s\"" 138 ]; 139 140 _result = Magick.system0 command; 141 } 142 } 143 144 Magick_pattern_item = class 145 Menuaction "_Pattern" "create pattern" { 146 action = class 147 _result { 148 _vislevel = 3; 149 150 size = Magick.Size_widget; 151 pattern = Magick.pattern_widget; 152 command = Magick.command [ 153 size._flag, 154 pattern._flag, 155 "\"%s\"" 156 ]; 157 158 _result = Magick.system0 command; 159 } 160 } 161 162 Magick_plasma_item = class 163 Menuaction "_Plasma image" "create plasma image" { 164 action = class 165 _result { 166 _vislevel = 3; 167 168 size = Magick.Size_widget; 169 // FIXME? ColourA-ColourB. 170 // FIXME? Allow plasma:fractal? 171 172 command = Magick.command [ 173 size._flag, 174 "plasma:", 175 "\"%s\"" 176 ]; 177 178 _result = Magick.system0 command; 179 } 180 } 181 182 Magick_radialgradient_item = class 183 Menuaction "_Radial gradient" 184 "make a radial gradient between two colours" { 185 action = class 186 _result { 187 _vislevel = 3; 188 189 size = Magick.Size_widget; 190 innerColour = Magick.generalcol_widget; 191 outerColour = Magick.generalcol_widget; 192 193 command = Magick.command [ 194 size._flag, 195 concat ["\"radial-gradient:", 196 innerColour._flag, "-", outerColour._flag, "\""], 197 "\"%s\"" 198 ]; 199 200 _result = Magick.system0 command; 201 } 202 } 203} // end Magick_NewImageMenu_item 204 205 206Magick_MultiMenu_item = class 207 Menupullright "_Multiple inputs" "make an image from multiple images" { 208 209 Magick_composite_item = class 210 Menuaction "_Composite" "composite two images (without mask)" { 211 action x y = class 212 _result { 213 _vislevel = 3; 214 215 method = Magick.compose_widget; 216 offsets = Magick.OffsetGeometry_widget; 217 gravity = Magick.gravity_widget; 218 219 command = Magick.command [ 220 "\"%s\"", 221 "\"%s\"", 222 "-geometry", offsets._flag, 223 gravity._flag, 224 method._flag, 225 "-composite", 226 "\"%s\"" 227 ]; 228 229 _result = Magick.system2 command x y; 230 } 231 } 232 233 Magick_compositeMask_item = class 234 Menuaction "_Composite masked" "composite two images (with mask)" { 235 action x y z = class 236 _result { 237 _vislevel = 3; 238 239 method = Magick.compose_widget; 240 offsets = Magick.OffsetGeometry_widget; 241 gravity = Magick.gravity_widget; 242 243 command = Magick.command [ 244 "\"%s\"", 245 "\"%s\"", 246 "\"%s\"", 247 "-geometry", offsets._flag, 248 gravity._flag, 249 method._flag, 250 "-composite", 251 "\"%s\"" 252 ]; 253 254 _result = Magick.system3 command x y z; 255 } 256 } 257 258 // FIXME: other operations like remap that take another image as arguments are: 259 // mask (pointless?), texture, tile (pointless?) 260 261 // FIXME: operations that take a filename that isn't an image: 262 // cdl, profile 263 264 Magick_clut_item = class 265 Menuaction "_Clut" "replace values using second image as colour look-up table" { 266 action x y = class 267 _result { 268 _vislevel = 3; 269 270 // FIXME: uses -intensity "when mapping greyscale CLUT image to alpha channel if set by -channels" 271 272 command = Magick.command [ 273 "\"%s\"", 274 "\"%s\"", 275 "-clut", 276 "\"%s\"" 277 ]; 278 279 _result = Magick.system2 command x y; 280 } 281 } 282 283 Magick_haldclut_item = class 284 Menuaction "_Hald clut" "replace values using second image as Hald colour look-up table" { 285 action x y = class 286 _result { 287 _vislevel = 3; 288 289 command = Magick.command [ 290 "\"%s\"", 291 "\"%s\"", 292 "-hald-clut", 293 "\"%s\"" 294 ]; 295 296 _result = Magick.system2 command x y; 297 } 298 } 299 300 301 // Encipher and decipher: key files can be text or image files. 302 303 Magick_encipher_item = class 304 Menuaction "_Encipher/Decipher" "encipher or decipher an image image" { 305 action x = class 306 _result { 307 _vislevel = 3; 308 309 pathname = Pathname "Read key file" ""; 310 isDecipher = Toggle "Decipher" false; 311 312 command = Magick.command [ 313 "\"%s\"", 314 if pathname.value == "" then "" else ( 315 ( if isDecipher then "-decipher " else "-encipher ") ++ 316 ( "\"" ++ pathname.value ++ "\"" ) 317 ), 318 "\"%s\"" 319 ]; 320 321 _result = Magick.system command x; 322 } 323 } 324 325 Magick_profile_item = class 326 Menuaction "_Profile" "assigns/applies an ICC profile" { 327 action x = class 328 _result { 329 _vislevel = 3; 330 331 pathname1 = Pathname "Read profile file" ""; 332 pathname2 = Pathname "Read profile file" ""; 333 334 command = Magick.command [ 335 "\"%s\"", 336 if pathname1.value == "" then "" else ( 337 "-profile " ++ 338 "\"" ++ pathname1.value ++ "\""), 339 if pathname2.value == "" then "" else ( 340 "-profile " ++ 341 "\"" ++ pathname2.value ++ "\""), 342 "\"%s\"" 343 ]; 344 345 _result = Magick.system command x; 346 } 347 } 348 349 Magick_remap_item = class 350 Menuaction "_Remap" "reduce colours to those in another image" { 351 action x y = class 352 _result { 353 _vislevel = 3; 354 355 command = Magick.command [ 356 "\"%s\"", 357 "-remap", 358 "\"%s\"", 359 "\"%s\"" 360 ]; 361 362 _result = Magick.system2 command x y; 363 } 364 } 365 366} // end Magick_MultiMenu_item 367 368 369Magick_image_type_item = class 370 Menuaction "_Image Type" "change image type" { 371 action x = class 372 _result { 373 _vislevel = 3; 374 375 imagetype = Magick.imagetype_widget; 376 377 command = Magick.command [ 378 "\"%s\"", 379 imagetype._flag, 380 "\"%s\"" 381 ]; 382 383 _result = Magick.system command x; 384 } 385} 386 387sep2 = Menuseparator; 388 389Magick_alpha_item = class 390 Menuaction "_Alpha" "add/remove alpha channel" { 391 action x = class 392 _result { 393 _vislevel = 3; 394 395 alpha = Magick.alpha_widget; 396 command = Magick.command [ 397 "\"%s\"", 398 alpha._flag, 399 "\"%s\"" 400 ]; 401 402 _result = Magick.system command x; 403 } 404} 405 406Magick_annotate_item = class 407 Menuaction "_Annotate" "add text annotation" { 408 action x = class 409 _result { 410 _vislevel = 3; 411 412 text = Magick.text_widget; 413 font = Magick.Font_widget; 414 geometry = Magick.AnnotGeometry_widget; 415 gravity = Magick.gravity_widget; 416 foreground = Magick.foreground_widget; 417 undercol = Magick.undercol_widget; 418 antialias = Magick.antialias_widget; 419 command = Magick.command [ 420 "\"%s\"", 421 font._flag, 422 antialias._flag, 423 gravity._flag, 424 foreground._flag, 425 undercol._flag, 426 "-annotate", 427 geometry._flag, 428 "\"" ++ text.value ++ "\"", 429 "\"%s\"" 430 ]; 431 432 _result = Magick.system command x; 433 } 434} 435 436Magick_autoGamma_item = class 437 Menuaction "_AutoGamma" "automatic gamma" { 438 action x = class 439 _result { 440 _vislevel = 3; 441 442 channels = Magick.channels_widget; 443 command = Magick.command [ 444 "\"%s\"", 445 channels._flag, 446 "-auto-gamma", 447 "\"%s\"" 448 ]; 449 450 _result = Magick.system command x; 451 } 452} 453 454Magick_autoLevel_item = class 455 Menuaction "_AutoLevel" "automatic level" { 456 action x = class 457 _result { 458 _vislevel = 3; 459 460 channels = Magick.channels_widget; 461 command = Magick.command [ 462 "\"%s\"", 463 channels._flag, 464 "-auto-level", 465 "\"%s\"" 466 ]; 467 468 _result = Magick.system command x; 469 } 470} 471 472Magick_blurSharpMenu_item = class 473 Menupullright "_Blur/Sharpen" "blur and sharpen" { 474 475 Magick_adaptive_blur_item = class 476 Menuaction "_Adaptive Blur" "blur less near edges" { 477 action x = class 478 _result { 479 _vislevel = 3; 480 481 intensity = Magick.intensity_widget; 482 radius = Magick.blur_rad_widget; 483 sigma = Magick.sigma_widget; 484 channels = Magick.channels_widget; 485 // note: adaptive-blur doesn't regard VP. 486 487 command = Magick.command [ 488 "\"%s\"", 489 intensity._flag, 490 channels._flag, 491 "-adaptive-blur", 492 print radius.value ++ "x" ++ print sigma.value, 493 "\"%s\"" 494 ]; 495 496 _result = Magick.system command x; 497 } 498 } 499 500 Magick_blur_item = class 501 Menuaction "_Blur" "blur" { 502 action x = class 503 _result { 504 _vislevel = 3; 505 506 radius = Magick.blur_rad_widget; 507 sigma = Magick.sigma_widget; 508 channels = Magick.channels_widget; 509 virtpixback = Magick.VirtualPixelBack_widget; 510 command = Magick.command [ 511 "\"%s\"", 512 virtpixback._flag, 513 channels._flag, 514 "-blur", 515 print radius.value ++ "x" ++ print sigma.value, 516 "\"%s\"" 517 ]; 518 519 _result = Magick.system command x; 520 } 521 } 522 523 Magick_gaussianBlur_item = class 524 Menuaction "_Gaussian Blur" "blur with a Gaussian operator" { 525 action x = class 526 _result { 527 _vislevel = 3; 528 529 radius = Magick.blur_rad_widget; 530 sigma = Magick.sigma_widget; 531 channels = Magick.channels_widget; 532 virtpixback = Magick.VirtualPixelBack_widget; 533 command = Magick.command [ 534 "\"%s\"", 535 virtpixback._flag, 536 channels._flag, 537 "-gaussian-blur", 538 print radius.value ++ "x" ++ print sigma.value, 539 "\"%s\"" 540 ]; 541 542 _result = Magick.system command x; 543 } 544 } 545 546 Magick_motionBlur_item = class 547 Menuaction "_Motion Blur" "simulate motion blur" { 548 action x = class 549 _result { 550 _vislevel = 3; 551 552 radius = Magick.blur_rad_widget; 553 sigma = Magick.sigma_widget; 554 angle = Scale "angle" (-360) 360 0; 555 channels = Magick.ch_widget; 556 virtpixback = Magick.VirtualPixelBack_widget; 557 command = Magick.command [ 558 "\"%s\"", 559 virtpixback._flag, 560 channels._flag, 561 "-motion-blur", 562 print radius.value ++ "x" ++ 563 print sigma.value ++ "+" ++ 564 print angle.value, 565 "\"%s\"" 566 ]; 567 568 _result = Magick.system command x; 569 } 570 } 571 572 Magick_rotationalBlur_item = class 573 Menuaction "_RotationalBlur" "blur around the centre" { 574 action x = class 575 _result { 576 _vislevel = 3; 577 578 channels = Magick.channels_widget; 579 virtpixback = Magick.VirtualPixelBack_widget; 580 angle = Scale "angle (degrees)" (-360) 360 20; 581 582 command = Magick.command [ 583 "\"%s\"", 584 virtpixback._flag, 585 channels._flag, 586 "-radial-blur", 587 print angle.value, 588 "\"%s\"" 589 ]; 590 591 _result = Magick.system command x; 592 } 593 } 594 595 Magick_selectiveBlur_item = class 596 Menuaction "_Selective Blur" "blur where contrast is less than or equal to threshold" { 597 action x = class 598 _result { 599 _vislevel = 3; 600 601 intensity = Magick.intensity_widget; 602 radius = Magick.blur_rad_widget; 603 sigma = Magick.sigma_widget; 604 threshold = Scale "Threshold (percent)" 0 100 50; 605 channels = Magick.channels_widget; 606 virtpixback = Magick.VirtualPixelBack_widget; 607 command = Magick.command [ 608 "\"%s\"", 609 intensity._flag, 610 virtpixback._flag, 611 channels._flag, 612 "-selective-blur", 613 print radius.value ++ "x" ++ 614 print sigma.value ++ "+" ++ 615 print threshold.value ++ "%%", 616 "\"%s\"" 617 ]; 618 619 _result = Magick.system command x; 620 } 621 } 622 623 sep1 = Menuseparator; 624 625 Magick_adaptive_sharpen_item = class 626 Menuaction "_Adaptive Sharpen" "sharpen more near edges" { 627 action x = class 628 _result { 629 _vislevel = 3; 630 631 intensity = Magick.intensity_widget; 632 radius = Magick.blur_rad_widget; 633 sigma = Magick.sigma_widget; 634 635 command = Magick.command [ 636 "\"%s\"", 637 intensity._flag, 638 "-adaptive-sharpen", 639 print radius.value ++ "x" ++ print sigma.value, 640 "\"%s\"" 641 ]; 642 643 _result = Magick.system command x; 644 } 645 } 646 647 Magick_sharpen_item = class 648 Menuaction "_Sharpen" "sharpen" { 649 action x = class 650 _result { 651 _vislevel = 3; 652 653 radius = Magick.blur_rad_widget; 654 sigma = Magick.sigma_widget; 655 channels = Magick.channels_widget; 656 virtpixback = Magick.VirtualPixelBack_widget; 657 command = Magick.command [ 658 "\"%s\"", 659 virtpixback._flag, 660 channels._flag, 661 "-sharpen", 662 print radius.value ++ "x" ++ print sigma.value, 663 "\"%s\"" 664 ]; 665 666 _result = Magick.system command x; 667 } 668 } 669 670 Magick_unsharpen_item = class 671 Menuaction "_Unsharp" "sharpen with unsharp mask" { 672 action x = class 673 _result { 674 _vislevel = 3; 675 676 radius = Magick.blur_rad_widget; 677 sigma = Magick.sigma_widget; 678 channels = Magick.channels_widget; 679 gain = Scale "Gain" (-10) 10 1; 680 threshold = Scale "Threshold" 0 1 0.05; 681 virtpixback = Magick.VirtualPixelBack_widget; 682 683 command = Magick.command [ 684 "\"%s\"", 685 virtpixback._flag, 686 channels._flag, 687 "-unsharp", 688 print radius.value ++ "x" ++ 689 print sigma.value ++ "+" ++ 690 print gain.value ++ "+" ++ 691 print threshold.value, 692 "\"%s\"" 693 ]; 694 695 _result = Magick.system command x; 696 } 697 } 698 699} // end BlurSharpMenu_item 700 701 702Magick_border_item = class 703 Menuaction "_Border" "add border of given colour" { 704 action x = class 705 _result { 706 _vislevel = 3; 707 708 compose = Magick.compose_widget; 709 width = Expression "Width" 3; 710 bordercol = Magick.bordercol_widget; 711 712 command = Magick.command [ 713 "\"%s\"", 714 compose._flag, 715 bordercol._flag, 716 "-border", 717 print width.expr, 718 "\"%s\"" 719 ]; 720 721 _result = Magick.system command x; 722 } 723} 724 725Magick_brightCont_item = class 726 Menuaction "_Brightness-contrast" "adjust the brightness and/or contrast" { 727 action x = class 728 _result { 729 _vislevel = 3; 730 731 bri = Scale "brightness" (-100) 100 0; 732 con = Scale "contrast" (-100) 100 0; 733 channels = Magick.channels_widget; 734 735 command = Magick.command [ 736 "\"%s\"", 737 channels._flag, 738 "-brightness-contrast", 739 print bri.value ++ "x" ++ print con.value, 740 "\"%s\"" 741 ]; 742 743 _result = Magick.system command x; 744 } 745} 746 747// Note: canny requires ImageMagick 6.8.9-0 or later. 748 749Magick_canny_item = class 750 Menuaction "_Canny" "detect a wide range of edges" { 751 action x = class 752 _result { 753 _vislevel = 3; 754 755 radius = Magick.blur_rad_widget; 756 sigma = Magick.sigma_widget; 757 lowPc = Scale "lower percent" 0 100 10; 758 highPc = Scale "lower percent" 0 100 10; 759 760 command = Magick.command [ 761 "\"%s\"", 762 "-canny", 763 concat ["\"", 764 print radius.value ++ "x" ++ 765 print sigma.value ++ "+" ++ 766 print lowPc.value ++ "%%+" ++ 767 print highPc.value ++ "%%" ++ "\"" 768 ], 769 "\"%s\"" 770 ]; 771 772 _result = Magick.system command x; 773 } 774} 775 776 777Magick_charcoal_item = class 778 Menuaction "_Charcoal" "simulate a charcoal drawing" { 779 action x = class 780 _result { 781 _vislevel = 3; 782 783 intensity = Magick.intensity_widget; 784 factor = Scale "factor" 0 50 1; 785 786 command = Magick.command [ 787 "\"%s\"", 788 intensity._flag, 789 "-charcoal", 790 print factor.value, 791 "\"%s\"" 792 ]; 793 794 _result = Magick.system command x; 795 } 796} 797 798Magick_chop_item = class 799 Menuaction "_Chop" "remove pixels from the interior" { 800 action x = class 801 _result { 802 _vislevel = 3; 803 804 gravity = Magick.gravity_widget; 805 geometry = Magick.WhxyGeometry_widget; 806 807 command = Magick.command [ 808 "\"%s\"", 809 gravity._flag, 810 "-chop", 811 geometry._flag, 812 "\"%s\"" 813 ]; 814 815 _result = Magick.system command x; 816 } 817} 818 819Magick_colorize_item = class 820 Menuaction "_Colorize" "colorize by given amount" { 821 action x = class 822 _result { 823 _vislevel = 3; 824 825 foreground = Magick.foreground_widget; 826 val = Scale "value" 0 100 100; 827 828 command = Magick.command [ 829 "\"%s\"", 830 foreground._flag, 831 "-colorize", 832 print val.value, 833 "\"%s\"" 834 ]; 835 836 _result = Magick.system command x; 837 } 838} 839 840Magick_colors_item = class 841 Menuaction "_Colors" "reduce number of colors" { 842 action x = class 843 _result { 844 _vislevel = 3; 845 846 treedepth = Expression "Treedepth" 8; 847 dither = Magick.dither_widget; 848 quantize = Magick.colorspace_widget; 849 colors = Expression "Colours" 3; 850 851 command = Magick.command [ 852 "\"%s\"", 853 "-quantize", quantize._flag, 854 "-treedepth", 855 print treedepth.expr, 856 dither._flag, 857 "-colors", 858 print colors.expr, 859 "\"%s\"" 860 ]; 861 862 _result = Magick.system command x; 863 } 864} 865 866// FIXME: color-matrix? 867 868Magick_colorspace_item = class 869 Menuaction "_Colourspace" "convert to arbitrary colourspace" { 870 action x = class 871 _result { 872 _vislevel = 3; 873 874 colsp = Magick.colorspace_widget; 875 876 command = Magick.command [ 877 "\"%s\"", 878 "-colorspace", 879 colsp._flag, 880 "\"%s\"" 881 ]; 882 883 _result = Magick.system command x; 884 } 885} 886 887Magick_colorspaceGray_item = class 888 Menuaction "_Colourspace gray" "convert to gray using given intensity method" { 889 action x = class 890 _result { 891 _vislevel = 3; 892 893 intensity = Magick.intensity_widget; 894 895 command = Magick.command [ 896 "\"%s\"", 897 intensity._flag, 898 "-colorspace gray", 899 "\"%s\"" 900 ]; 901 902 _result = Magick.system command x; 903 } 904} 905 906Magick_contrast_item = class 907 Menuaction "_Contrast" "increase or reduce the contrast" { 908 action x = class 909 _result { 910 _vislevel = 3; 911 912 isReduce = Toggle "reduce contrast" false; 913 914 command = Magick.command [ 915 "\"%s\"", 916 (if isReduce then "+" else "-") ++ "contrast", 917 "\"%s\"" 918 ]; 919 920 _result = Magick.system command x; 921 } 922} 923 924Magick_contrastStretch_item = class 925 Menuaction "_Contrast stretch" "stretches tones, making some black/white" { 926 action x = class 927 _result { 928 _vislevel = 3; 929 930 intensity = Magick.intensity_widget; 931 channels = Magick.channels_widget; 932 blk = Scale "percent to make black" 0 100 0; 933 wht = Scale "percent to make white" 0 100 0; 934 935 command = Magick.command [ 936 "\"%s\"", 937 intensity._flag, 938 channels._flag, 939 "-contrast-stretch", 940 "\"" ++ print blk.value ++ "x" ++ print wht.value ++ "%%\"", 941 "\"%s\"" 942 ]; 943 944 _result = Magick.system command x; 945 } 946} 947 948// FIXME: convolve (bias, kernel) 949 950Magick_crop_item = class 951 Menuaction "_Crop" "cut out a rectangular region" { 952 action x = class 953 _result { 954 _vislevel = 3; 955 956 gravity = Magick.gravity_widget; 957 geometry = Magick.WhxyGeometry_widget; 958 959 command = Magick.command [ 960 "\"%s\"", 961 gravity._flag, 962 "-crop", 963 geometry._flag, 964 "+repage", 965 "\"%s\"" 966 ]; 967 968 _result = Magick.system command x; 969 } 970} 971 972Magick_deskew_item = class 973 Menuaction "_Deskew" "straighten the image" { 974 action x = class 975 _result { 976 _vislevel = 3; 977 978 threshold = Scale "Threshold (percent)" 0 100 80; 979 980 // FIXME: toggle auto-crop? 981 982 command = Magick.command [ 983 "\"%s\"", 984 "-deskew", 985 "\"" ++ print threshold.value ++ "%%\"", 986 "+repage", 987 "\"%s\"" 988 ]; 989 990 _result = Magick.system command x; 991 } 992} 993 994Magick_despeckle_item = class 995 Menuaction "_Despeckle" "reduce the speckles" { 996 action x = class 997 _result { 998 _vislevel = 3; 999 1000 command = Magick.command [ 1001 "\"%s\"", 1002 "-despeckle", 1003 "\"%s\"" 1004 ]; 1005 1006 _result = Magick.system command x; 1007 } 1008} 1009 1010Magick_distort_item = class 1011 Menuaction "_Distort" "distort using a method and arguments" { 1012 action x = class 1013 _result { 1014 _vislevel = 3; 1015 1016 virtpixback = Magick.VirtualPixelBack_widget; 1017 distort = Magick.distort_widget; 1018 args = String "Arguments" "1,0"; 1019 isPlus = Toggle "Extend to show entire image" false; 1020 1021 command = Magick.command [ 1022 "\"%s\"", 1023 virtpixback._flag, 1024 (if isPlus then "+" else "-") ++ "distort", 1025 distort._flag, 1026 args.value, 1027 "+repage", 1028 "\"%s\"" 1029 ]; 1030 1031 _result = Magick.system command x; 1032 } 1033} 1034 1035Magick_draw_item = class 1036 Menuaction "_Draw" "annotate with one or more graphic primitives" { 1037 action x = class 1038 _result { 1039 _vislevel = 3; 1040 1041 foreground = Magick.foreground_widget; 1042 args = String "Arguments" "line 0,0 9,9 rectangle 10,10 20,20"; 1043 1044 command = Magick.command [ 1045 "\"%s\"", 1046 foreground._flag, 1047 "-draw", 1048 concat ["\"", args.value, "\""], 1049 "\"%s\"" 1050 ]; 1051 1052 _result = Magick.system command x; 1053 } 1054} 1055 1056Magick_edge_item = class 1057 Menuaction "_Edge" "detect edges" { 1058 action x = class 1059 _result { 1060 _vislevel = 3; 1061 1062 rad = Expression "Radius" 3; 1063 1064 command = Magick.command [ 1065 "\"%s\"", 1066 "-edge", 1067 print rad.expr, 1068 "\"%s\"" 1069 ]; 1070 1071 _result = Magick.system command x; 1072 } 1073} 1074 1075Magick_emboss_item = class 1076 Menuaction "_Emboss" "emboss" { 1077 action x = class 1078 _result { 1079 _vislevel = 3; 1080 1081 rad = Expression "Radius" 3; 1082 1083 command = Magick.command [ 1084 "\"%s\"", 1085 "-emboss", 1086 print rad.expr, 1087 "\"%s\"" 1088 ]; 1089 1090 _result = Magick.system command x; 1091 } 1092} 1093 1094Magick_enhance_item = class 1095 Menuaction "_Enhance" "enhance a noisy image" { 1096 action x = class 1097 _result { 1098 _vislevel = 3; 1099 1100 command = Magick.command [ 1101 "\"%s\"", 1102 "-enhance", 1103 "\"%s\"" 1104 ]; 1105 1106 _result = Magick.system command x; 1107 } 1108} 1109 1110Magick_equalize_item = class 1111 Menuaction "_Equalize" "equalize the histogram" { 1112 action x = class 1113 _result { 1114 _vislevel = 3; 1115 1116 channels = Magick.channels_widget; 1117 1118 command = Magick.command [ 1119 "\"%s\"", 1120 channels._flag, 1121 "-equalize", 1122 "\"%s\"" 1123 ]; 1124 1125 _result = Magick.system command x; 1126 } 1127} 1128 1129Magick_evaluate_item = class 1130 Menuaction "_Evaluate" "evaluate an expression on each pixel channel" { 1131 action x = class 1132 _result { 1133 _vislevel = 3; 1134 1135 channels = Magick.channels_widget; 1136 operation = Magick.evaluate_widget; 1137 val = Expression "value" 5; 1138 isPc = Toggle "Value is percent" false; 1139 1140 command = Magick.command [ 1141 "\"%s\"", 1142 channels._flag, 1143 operation._flag, 1144 print val.expr ++ if isPc then "%%" else "", 1145 "\"%s\"" 1146 ]; 1147 1148 _result = Magick.system command x; 1149 } 1150} 1151 1152Magick_extent_item = class 1153 Menuaction "_Extent" "set the image size and offset" { 1154 action x = class 1155 _result { 1156 _vislevel = 3; 1157 1158 background = Magick.background_widget; 1159 compose = Magick.compose_widget; 1160 gravity = Magick.gravity_widget; 1161 geometry = Magick.WhxyGeometry_widget; 1162 1163 command = Magick.command [ 1164 "\"%s\"", 1165 compose._flag, 1166 background._flag, 1167 gravity._flag, 1168 "-extent", 1169 geometry._flag, 1170 "\"%s\"" 1171 ]; 1172 1173 _result = Magick.system command x; 1174 } 1175} 1176 1177 1178Magick_FlipFlopMenu_item = class 1179 Menupullright "_Flip/flop" "flip/flop/transverse/transpose" { 1180 1181 Magick_flip_item = class 1182 Menuaction "_Flip vertically" "mirror upside-down" { 1183 action x = class 1184 _result { 1185 _vislevel = 3; 1186 1187 command = Magick.command [ 1188 "\"%s\"", 1189 "-flip", 1190 "\"%s\"" 1191 ]; 1192 1193 _result = Magick.system command x; 1194 } 1195 } 1196 1197 Magick_flop_item = class 1198 Menuaction "_Flop horizontally" "mirror left-right" { 1199 action x = class 1200 _result { 1201 _vislevel = 3; 1202 1203 command = Magick.command [ 1204 "\"%s\"", 1205 "-flop", 1206 "\"%s\"" 1207 ]; 1208 1209 _result = Magick.system command x; 1210 } 1211 } 1212 1213 Magick_transpose_item = class 1214 Menuaction "_Transpose" "mirror along the top-left to bottom-right diagonal" { 1215 action x = class 1216 _result { 1217 _vislevel = 3; 1218 1219 command = Magick.command [ 1220 "\"%s\"", 1221 "-transpose +repage", 1222 "\"%s\"" 1223 ]; 1224 1225 _result = Magick.system command x; 1226 } 1227 } 1228 1229 Magick_transverse_item = class 1230 Menuaction "_Transverse" "mirror along the bottom-left to top-right diagonal" { 1231 action x = class 1232 _result { 1233 _vislevel = 3; 1234 1235 command = Magick.command [ 1236 "\"%s\"", 1237 "-transverse +repage", 1238 "\"%s\"" 1239 ]; 1240 1241 _result = Magick.system command x; 1242 } 1243 } 1244 1245} // end Magick_FlipFlopMenu_item 1246 1247 1248Magick_floodfill_item = class 1249 Menuaction "_Floodfill" "recolour neighbours that match" { 1250 action x = class 1251 _result { 1252 _vislevel = 3; 1253 1254 foreground = Magick.foreground_widget; 1255 fuzz = Magick.fuzz_widget; 1256 coordinate = Magick.coordinate_widget; 1257 1258 // -draw "color x,y floodfill" 1259 command = Magick.command [ 1260 "\"%s\"", 1261 foreground._flag, 1262 "-fuzz", 1263 "\"" ++ print fuzz.value ++ "%%\"", 1264 "-draw \" color", 1265 coordinate._flag, 1266 "floodfill \"", 1267 "\"%s\"" 1268 ]; 1269 1270 _result = Magick.system command x; 1271 } 1272} 1273 1274Magick_frame_item = class 1275 Menuaction "_Frame" "surround with border or beveled frame" { 1276 action x = class 1277 _result { 1278 _vislevel = 3; 1279 1280 border = Magick.bordercol_widget; 1281 compose = Magick.compose_widget; 1282 matte = Magick.mattecol_widget; 1283 geometry = Magick.FrameGeometry_widget; 1284 1285 command = Magick.command [ 1286 "\"%s\"", 1287 compose._flag, 1288 border._flag, 1289 matte._flag, 1290 "-frame", 1291 geometry._flag, 1292 "\"%s\"" 1293 ]; 1294 1295 _result = Magick.system command x; 1296 } 1297} 1298 1299Magick_function_item = class 1300 Menuaction "_Function" "evaluate a function on each pixel channel" { 1301 action x = class 1302 _result { 1303 _vislevel = 3; 1304 1305 channels = Magick.channels_widget; 1306 function = Magick.function_widget; 1307 // FIXME: explain values; use sensible defaults. 1308 values = String "values" "0,0,0,0"; 1309 1310 command = Magick.command [ 1311 "\"%s\"", 1312 channels._flag, 1313 "-function", 1314 function._flag, 1315 values.value, 1316 "\"%s\"" 1317 ]; 1318 1319 _result = Magick.system command x; 1320 } 1321} 1322 1323Magick_fx_item = class 1324 Menuaction "_Fx" "apply a mathematical expression" { 1325 action x = class 1326 _result { 1327 _vislevel = 3; 1328 1329 channels = Magick.channels_widget; 1330 interpolate = Magick.interpolate_widget; 1331 virtpixback = Magick.VirtualPixelBack_widget; 1332 args = String "Expression" "u*1/2"; 1333 1334 command = Magick.command [ 1335 "\"%s\"", 1336 channels._flag, 1337 interpolate._flag, 1338 virtpixback._flag, 1339 "-fx", 1340 concat ["\"", args.value, "\""], 1341 "\"%s\"" 1342 ]; 1343 1344 _result = Magick.system command x; 1345 } 1346} 1347 1348Magick_gamma_item = class 1349 Menuaction "_Gamma" "apply a gamma correction" { 1350 action x = class 1351 _result { 1352 _vislevel = 3; 1353 1354 channels = Magick.channels_widget; 1355 gamma = Magick.gamma_widget; 1356 1357 command = Magick.command [ 1358 "\"%s\"", 1359 channels._flag, 1360 "-gamma", 1361 print gamma.value, 1362 "\"%s\"" 1363 ]; 1364 1365 _result = Magick.system command x; 1366 } 1367} 1368 1369Magick_gradient_item = class 1370 Menuaction "_Gradient" "apply a linear gradient" { 1371 action x = class 1372 _result { 1373 _vislevel = 3; 1374 1375 colourA = Magick.generalcol_widget; 1376 colourB = Magick.generalcol_widget; 1377 1378 position = Option "colourA is at" [ 1379 "top", "bottom", 1380 "left", "right", 1381 "top-left", "top-right", 1382 "bottom-left", "bottom-right"] 0; 1383 _baryArg 1384 = concat ["0,0,", colourA._flag, " 0,%%[fx:h-1],", colourB._flag], position.value == 0 1385 = concat ["0,0,", colourB._flag, " 0,%%[fx:h-1],", colourA._flag], position.value == 1 1386 = concat ["0,0,", colourA._flag, " %%[fx:w-1],0,", colourB._flag], position.value == 2 1387 = concat ["0,0,", colourB._flag, " %%[fx:w-1],0,", colourA._flag], position.value == 3 1388 = concat ["0,0,", colourA._flag, " %%[fx:w-1],%%[fx:h-1],", colourB._flag], position.value == 4 1389 = concat ["%%[fx:w-1],0,", colourA._flag, " 0,%%[fx:h-1],", colourB._flag], position.value == 5 1390 = concat ["%%[fx:w-1],0,", colourB._flag, " 0,%%[fx:h-1],", colourA._flag], position.value == 6 1391 = concat ["0,0,", colourB._flag, " %%[fx:w-1],%%[fx:h-1],", colourA._flag], position.value == 7 1392 = "dunno"; 1393 1394 command = Magick.command [ 1395 "\"%s\"", 1396 "-sparse-color barycentric \"" ++ _baryArg ++ "\"", 1397 "\"%s\"" 1398 ]; 1399 1400 _result = Magick.system command x; 1401 } 1402} 1403 1404Magick_gradientCorn_item = class 1405 Menuaction "_Gradient corners" 1406 "apply a bilinear gradient between the corners" { 1407 action x = class 1408 _result { 1409 _vislevel = 3; 1410 1411 colour_top_left = Magick.generalcol_widget; 1412 colour_top_right = Magick.generalcol_widget; 1413 colour_bottom_left = Magick.generalcol_widget; 1414 colour_bottom_right = Magick.generalcol_widget; 1415 1416 command = Magick.command [ 1417 "\"%s\"", 1418 "-sparse-color bilinear \"" ++ 1419 "0,0," ++ colour_top_left._flag ++ 1420 ",%%[fx:w-1],0" ++ colour_top_right._flag ++ 1421 ",0,%%[fx:h-1]" ++ colour_bottom_left._flag ++ 1422 ",%%[fx:w-1],%%[fx:h-1]" ++ colour_bottom_right._flag ++ "\"", 1423 "+depth", 1424 "\"%s\"" 1425 ]; 1426 1427 _result = Magick.system command x; 1428 } 1429} 1430 1431Magick_histogram_item = class 1432 Menuaction "_Histogram" "make a histogram image" { 1433 action x = class 1434 _result { 1435 _vislevel = 3; 1436 1437 command = Magick.command [ 1438 "\"%s\"", 1439 "-define histogram:unique-colors=false histogram:" ++ 1440 "\"%s\"" 1441 ]; 1442 1443 _result = Magick.system command x; 1444 } 1445} 1446 1447Magick_implode_item = class 1448 Menuaction "_Implode" "implode pixels about the center" { 1449 action x = class 1450 _result { 1451 _vislevel = 3; 1452 1453 factor = Scale "factor" 0 20 1; 1454 interpolate = Magick.interpolate_widget; 1455 // FIXME: virtual-pixel? 1456 1457 command = Magick.command [ 1458 "\"%s\"", 1459 interpolate._flag, 1460 "-implode", 1461 print factor.value, 1462 "\"%s\"" 1463 ]; 1464 1465 _result = Magick.system command x; 1466 } 1467} 1468 1469Magick_level_item = class 1470 Menuaction "_Level" "adjust the level of channels" { 1471 action x = class 1472 _result { 1473 _vislevel = 3; 1474 1475 channels = Magick.channels_widget; 1476 blk = Scale "black point" (-100) 200 0; 1477 wht = Scale "white point" (-100) 200 100; 1478 gam = Scale "gamma" 0 30 1; 1479 isPc = Toggle "Levels are percent" true; 1480 isInv = Toggle "Invert effect" false; 1481 1482 command = Magick.command [ 1483 "\"%s\"", 1484 channels._flag, 1485 (if isInv then "+" else "-") ++ "level", 1486 "\"" ++ print blk.value ++ "," ++ 1487 print wht.value ++ (if isPc then "%%" else "") ++ "," ++ 1488 print gam.value ++ "\"", 1489 "\"%s\"" 1490 ]; 1491 1492 _result = Magick.system command x; 1493 } 1494} 1495 1496Magick_levelCols_item = class 1497 Menuaction "_Level colors" "adjust levels to given colours" { 1498 action x = class 1499 _result { 1500 _vislevel = 3; 1501 1502 channels = Magick.channels_widget; 1503 colour_black = Magick.generalcol_widget; 1504 colour_white = Magick.generalcol_widget; 1505 isInv = Toggle "Invert effect" false; 1506 1507 command = Magick.command [ 1508 "\"%s\"", 1509 channels._flag, 1510 (if isInv then "+" else "-") ++ "level-colors", 1511 "\"" ++ colour_black._flag ++ "," ++ colour_white._flag ++ "\"", 1512 "\"%s\"" 1513 ]; 1514 1515 _result = Magick.system command x; 1516 } 1517} 1518 1519Magick_linearStretch_item = class 1520 Menuaction "_Linear stretch" "stretches tones, making some black/white" { 1521 action x = class 1522 _result { 1523 _vislevel = 3; 1524 1525 channels = Magick.channels_widget; 1526 blk = Scale "percent to make black" 0 100 0; 1527 wht = Scale "percent to make white" 0 100 0; 1528 1529 command = Magick.command [ 1530 "\"%s\"", 1531 channels._flag, 1532 "-linear-stretch", 1533 "\"" ++ print blk.value ++ "x" ++ print wht.value ++ "%%\"", 1534 "\"%s\"" 1535 ]; 1536 1537 _result = Magick.system command x; 1538 } 1539} 1540 1541Magick_magnify_item = class 1542 Menuaction "_Magnify" "double the size of the image with pixel art scaling" { 1543 action x = class 1544 _result { 1545 _vislevel = 3; 1546 1547 command = Magick.command [ 1548 "\"%s\"", 1549 "-magnify", 1550 "\"%s\"" 1551 ]; 1552 1553 _result = Magick.system command x; 1554 } 1555} 1556 1557Magick_modulate_item = class 1558 Menuaction "_Modulate" "modulate brightness, saturation and hue" { 1559 action x = class 1560 _result { 1561 _vislevel = 3; 1562 1563 modcolsp = Magick.ModColSp_widget; 1564 bright = Scale "brightness" 0 200 100; 1565 sat = Scale "saturation" 0 200 100; 1566 hue = Scale "hue" 0 200 100; 1567 1568 command = Magick.command [ 1569 "\"%s\"", 1570 modcolsp._flag, 1571 "-modulate", 1572 print bright.value ++ "," ++ print sat.value ++ "," ++ 1573 print hue.value, 1574 "\"%s\"" 1575 ]; 1576 1577 _result = Magick.system command x; 1578 } 1579} 1580 1581Magick_monochrome_item = class 1582 Menuaction "_Monochrome" "transform to black and white" { 1583 action x = class 1584 _result { 1585 _vislevel = 3; 1586 1587 // FIXME: also intensity? 1588 1589 intensity = Magick.intensity_widget; 1590 treedepth = Expression "Treedepth" 8; 1591 dither = Magick.dither_widget; 1592 1593 command = Magick.command [ 1594 "\"%s\"", 1595 intensity._flag, 1596 dither._flag, 1597 "-treedepth", 1598 print treedepth.expr, 1599 "-monochrome", 1600 "\"%s\"" 1601 ]; 1602 1603 _result = Magick.system command x; 1604 } 1605} 1606 1607Magick_morphology_item = class 1608 // See http://www.imagemagick.org/Usage/morphology/ 1609 Menuaction "_Morphology" "apply a morphological method" { 1610 action x = class 1611 _result { 1612 _vislevel = 3; 1613 1614 method = Magick.morphmeth_widget; 1615 iter = Expression "Iterations (-1=repeat until done)" 1; 1616 1617 kernel = Magick.kernel_widget; 1618 // FIXME: custom kernel eg "3x1+2+0:1,0,0" 1619 // width x height + offsx + offsy : {w*h values} 1620 // each value is 0.0 to 1.0 or "NaN" or "-" 1621 1622 // kernel args, mostly float radius,scale. radius=0=default. default scale = 1.0 1623 // but 1624 // ring takes: radius1, radius2, scale 1625 // rectangle and comet take: width x height + offsx + offsy 1626 // blur takes: radius x sigma 1627 // FIXME: for now, simply allow any string input. 1628 kernel_arg = String "Kernel arguments" ""; 1629 channels = Magick.channels_widget; 1630 1631 command = Magick.command [ 1632 "\"%s\"", 1633 channels._flag, 1634 "-morphology", 1635 method._flag ++ ":" ++ print iter.expr, 1636 kernel._flag ++ 1637 (if kernel_arg.value == "" then "" else ":") ++ kernel_arg.value, 1638 "\"%s\"" 1639 ]; 1640 1641 _result = Magick.system command x; 1642 } 1643} 1644 1645Magick_negate_item = class 1646 Menuaction "_Negate" "negate" { 1647 action x = class 1648 _result { 1649 _vislevel = 3; 1650 1651 channels = Magick.channels_widget; 1652 1653 command = Magick.command [ 1654 "\"%s\"", 1655 channels._flag, 1656 "-negate", 1657 "\"%s\"" 1658 ]; 1659 1660 _result = Magick.system command x; 1661 } 1662} 1663 1664Magick_addNoise_item = class 1665 Menuaction "_add Noise" "add noise" { 1666 action x = class 1667 _result { 1668 _vislevel = 3; 1669 1670 channels = Magick.channels_widget; 1671 attenuate = Scale "attenuate" 0 1.0 1.0; 1672 noise = Magick.noise_widget; 1673 1674 command = Magick.command [ 1675 "\"%s\"", 1676 channels._flag, 1677 "-attenuate", 1678 print attenuate.value, 1679 noise._flag, 1680 "\"%s\"" 1681 ]; 1682 1683 _result = Magick.system command x; 1684 } 1685} 1686 1687Magick_normalize_item = class 1688 Menuaction "_Normalize" "normalize" { 1689 action x = class 1690 _result { 1691 _vislevel = 3; 1692 1693 intensity = Magick.intensity_widget; 1694 channels = Magick.channels_widget; 1695 1696 command = Magick.command [ 1697 "\"%s\"", 1698 intensity._flag, 1699 channels._flag, 1700 "-normalize", 1701 "\"%s\"" 1702 ]; 1703 1704 _result = Magick.system command x; 1705 } 1706} 1707 1708Magick_opaque_item = class 1709 Menuaction "_Opaque" "change this colour to the fill colour" { 1710 action x = class 1711 _result { 1712 _vislevel = 3; 1713 1714 channels = Magick.channels_widget; 1715 fill = Magick.foreground_widget; 1716 changeColour = Magick.changeCol_widget; 1717 1718 command = Magick.command [ 1719 "\"%s\"", 1720 fill._flag, 1721 channels._flag, 1722 "-fuzz", 1723 "\"" ++ print changeColour.fuzz.value ++ "%%\"", 1724 (if changeColour.nonMatch then "+" else "-") ++ "opaque", 1725 "\"" ++ changeColour.colour._flag ++ "\"", 1726 "\"%s\"" 1727 ]; 1728 1729 _result = Magick.system command x; 1730 } 1731} 1732 1733Magick_paint_item = class 1734 Menuaction "_Paint" "simulate an oil painting" { 1735 action x = class 1736 _result { 1737 _vislevel = 3; 1738 1739 rad = Expression "radius" 10; 1740 1741 command = Magick.command [ 1742 "\"%s\"", 1743 "-paint", 1744 print rad.expr, 1745 "\"%s\"" 1746 ]; 1747 1748 _result = Magick.system command x; 1749 } 1750} 1751 1752/*=== FIXME Bug; remove for now. 1753Polaroid_item = class 1754 Menuaction "_Polaroid" "simulate a polaroid picture" { 1755 action x = class 1756 _result { 1757 _vislevel = 3; 1758 1759 angle = Scale "angle" (-90) 90 20; 1760 1761 command = Magick.command [ 1762 "\"%s\"", 1763 "-polaroid", 1764 print angle.value, 1765 "\"%s\"" 1766 ]; 1767 1768 _result = Magick.system command x; 1769 } 1770} 1771===*/ 1772 1773Magick_posterize_item = class 1774 Menuaction "_Posterize" "reduce to (n) levels per channel" { 1775 action x = class 1776 _result { 1777 _vislevel = 3; 1778 1779 levels = Expression "levels" 3; 1780 1781 command = Magick.command [ 1782 "\"%s\"", 1783 "-posterize", 1784 print levels.expr, 1785 "\"%s\"" 1786 ]; 1787 1788 _result = Magick.system command x; 1789 } 1790} 1791 1792Magick_raise_item = class 1793 Menuaction "_Raise" "lighten or darken image edges" { 1794 action x = class 1795 _result { 1796 _vislevel = 3; 1797 1798 thk = Expression "Thickness" 3; 1799 1800 command = Magick.command [ 1801 "\"%s\"", 1802 "-raise", 1803 print thk.expr, 1804 "\"%s\"" 1805 ]; 1806 1807 _result = Magick.system command x; 1808 } 1809} 1810 1811Magick_resize_item = class 1812 Menuaction "_Resize" "resize to given width and height" { 1813 action x = class 1814 _result { 1815 _vislevel = 3; 1816 1817 filter = Magick.filter_widget; 1818 type = Magick.ResizeType_widget; 1819 width = Scale "Width" 1 100 10; 1820 height = Scale "Height" 1 100 10; 1821 isPc = Toggle "Width and height are percent" false; 1822 1823 command = Magick.command [ 1824 "\"%s\"", 1825 filter._flag, 1826 "-" ++ type._flag, 1827 "\"" ++ print width.value ++ "x" ++ print height.value ++ 1828 (if isPc then "%%" else "!") ++ "\"", 1829 "\"%s\"" 1830 ]; 1831 1832 _result = Magick.system command x; 1833 } 1834} 1835 1836Magick_roll_item = class 1837 Menuaction "_Roll" "roll an image horizontally or vertically" { 1838 action x = class 1839 _result { 1840 _vislevel = 3; 1841 1842 rollx = Expression "X" 3; 1843 rolly = Expression "Y" 3; 1844 1845 command = Magick.command [ 1846 "\"%s\"", 1847 "-roll", 1848 (if rollx.expr >= 0 then "+" else "") ++ print rollx.expr ++ 1849 (if rolly.expr >= 0 then "+" else "") ++ print rolly.expr, 1850 "\"%s\"" 1851 ]; 1852 1853 _result = Magick.system command x; 1854 } 1855} 1856 1857Magick_rotate_item = class 1858 Menuaction "_Rotate" "rotate" { 1859 action x = class 1860 _result { 1861 _vislevel = 3; 1862 1863 angle = Scale "angle (degrees)" (-360) 360 20; 1864 virtpixback = Magick.VirtualPixelBack_widget; 1865 1866 command = Magick.command [ 1867 "\"%s\"", 1868 virtpixback._flag, 1869 "+distort", 1870 "SRT", 1871 print angle.value, 1872 "+repage", 1873 "\"%s\"" 1874 ]; 1875 1876 _result = Magick.system command x; 1877 } 1878} 1879 1880// FIXME: -segment, but cluster-threshold should be percentage of image area. 1881 1882Magick_sepia_item = class 1883 Menuaction "_Sepia tone" "simulate a sepia-toned photo" { 1884 action x = class 1885 _result { 1886 _vislevel = 3; 1887 1888 threshold = Scale "Threshold (percent)" 0 100 80; 1889 1890 command = Magick.command [ 1891 "\"%s\"", 1892 "-sepia-tone", 1893 "\"" ++ print threshold.value ++ "%%\"", 1894 "\"%s\"" 1895 ]; 1896 1897 _result = Magick.system command x; 1898 } 1899} 1900 1901Magick_shade_item = class 1902 Menuaction "_Shade" "shade with a distant light source" { 1903 action x = class 1904 _result { 1905 _vislevel = 3; 1906 1907 azimuth = Scale "Azimuth (degrees)" (-360) 360 0; 1908 elevation = Scale "Elevation (degrees)" 0 90 45; 1909 1910 command = Magick.command [ 1911 "\"%s\"", 1912 "-shade", 1913 print azimuth.value ++ "x" ++ print elevation.value, 1914 "\"%s\"" 1915 ]; 1916 1917 _result = Magick.system command x; 1918 } 1919} 1920 1921Magick_shadow_item = class 1922 Menuaction "_Shadow" "simulate a shadow" { 1923 action x = class 1924 _result { 1925 _vislevel = 3; 1926 1927 shadowCol = Magick.generalcol_widget; 1928 opacity = Scale "Opacity (percent)" 0 100 75; 1929 sigma = Scale "Sigma" 0 30 2; 1930 // FIXME: make offsets a single widget? 1931 offsx = Scale "X-offset" (-20) 20 4; 1932 offsy = Scale "Y-offset" (-20) 20 4; 1933 arePc = Toggle "offsets are percentages" false; 1934 1935 // FIXME: raw operation creates page offset, which vips dislikes. 1936 // So we take this futher, compositing with source. 1937 command = Magick.command [ 1938 "\"%s\"", 1939 "\"(\" +clone", 1940 "-background", "\"" ++ shadowCol._flag ++ "\"", 1941 "-shadow", 1942 concat [ 1943 "\"", 1944 print opacity.value, "x", print sigma.value, 1945 (if offsx.value >= 0 then "+" else ""), print offsx.value, 1946 (if offsy.value >= 0 then "+" else ""), print offsy.value, 1947 (if arePc then "%%" else ""), 1948 "\"" 1949 ], 1950 "\")\" +swap -background None -layers merge", 1951 "+repage", 1952 "\"%s\"" 1953 ]; 1954 1955 _result = Magick.system command x; 1956 } 1957} 1958 1959Magick_shave_item = class 1960 Menuaction "_Shave" "shave pixels from the edges" { 1961 action x = class 1962 _result { 1963 _vislevel = 3; 1964 1965 width = Scale "Width" 0 50 10; 1966 height = Scale "Height" 0 50 10; 1967 isPc = Toggle "Width and height are percent" false; 1968 1969 command = Magick.command [ 1970 "\"%s\"", 1971 "-shave", 1972 "\"" ++ print width.value ++ "x" ++ print height.value ++ 1973 (if isPc then "%%" else "") ++ "\"", 1974 "\"%s\"" 1975 ]; 1976 1977 _result = Magick.system command x; 1978 } 1979} 1980 1981Magick_shear_item = class 1982 Menuaction "_Shear" "shear along the x-axis and/or y-axis" { 1983 action x = class 1984 _result { 1985 _vislevel = 3; 1986 1987 shearX = Expression "shear X (degrees)" 0; 1988 shearY = Expression "shear Y (degrees)" 0; 1989 background = Magick.background_widget; 1990 1991 command = Magick.command [ 1992 "\"%s\"", 1993 background._flag, 1994 "-shear", 1995 print shearX.expr ++ "x" ++ print shearY.expr, 1996 "\"%s\"" 1997 ]; 1998 1999 _result = Magick.system command x; 2000 } 2001} 2002 2003Magick_sigmoid_item = class 2004 Menuaction "_Sigmoid" "increase or decrease mid-tone contrast sigmoidally" { 2005 action x = class 2006 _result { 2007 _vislevel = 3; 2008 2009 channels = Magick.channels_widget; 2010 contrast = Scale "contrast" 0 30 3; 2011 midpoint = Scale "mid-point (percent)" 0 100 50; 2012 isInv = Toggle "Invert effect" false; 2013 2014 command = Magick.command [ 2015 "\"%s\"", 2016 channels._flag, 2017 (if isInv then "+" else "-") ++ "sigmoidal-contrast", 2018 "\"" ++ print contrast.value ++ "x" ++ 2019 print midpoint.value ++ "%%\"", 2020 "\"%s\"" 2021 ]; 2022 2023 _result = Magick.system command x; 2024 } 2025} 2026 2027Magick_sketch_item = class 2028 Menuaction "_Sketch" "simulate a pencil sketch" { 2029 action x = class 2030 _result { 2031 _vislevel = 3; 2032 2033 radius = Magick.blur_rad_widget; 2034 sigma = Magick.sigma_widget; 2035 angle = Scale "angle" (-360) 360 0; 2036 2037 command = Magick.command [ 2038 "\"%s\"", 2039 "-sketch", 2040 print radius.value ++ "x" ++ print sigma.value ++ 2041 (if angle >= 0 then ("+" ++ print angle.value) else ""), 2042 "\"%s\"" 2043 ]; 2044 2045 _result = Magick.system command x; 2046 } 2047} 2048 2049Magick_solarize_item = class 2050 Menuaction "_Solarize" "negate all pixels above a threshold level" { 2051 action x = class 2052 _result { 2053 _vislevel = 3; 2054 2055 channels = Magick.channels_widget; 2056 threshold = Scale "Threshold (percent)" 0 100 50; 2057 2058 command = Magick.command [ 2059 "\"%s\"", 2060 channels._flag, 2061 "-solarize", 2062 "\"" ++ print threshold.value ++ "%%\"", 2063 "\"%s\"" 2064 ]; 2065 2066 _result = Magick.system command x; 2067 } 2068} 2069 2070// FIXME: -sparse-color needs abitrary list of {x,y,colour}. 2071 2072Magick_splice_item = class 2073 Menuaction "_Splice" "splice a colour into the image" { 2074 action x = class 2075 _result { 2076 _vislevel = 3; 2077 2078 background = Magick.background_widget; 2079 gravity = Magick.gravity_widget; 2080 geometry = Magick.WhxyGeometry_widget; 2081 2082 command = Magick.command [ 2083 "\"%s\"", 2084 background._flag, 2085 gravity._flag, 2086 "-splice", 2087 geometry._flag, 2088 "\"%s\"" 2089 ]; 2090 2091 _result = Magick.system command x; 2092 } 2093} 2094 2095Magick_spread_item = class 2096 Menuaction "_Spread" "displace pixels by random amount" { 2097 action x = class 2098 _result { 2099 _vislevel = 3; 2100 2101 virtpixback = Magick.VirtualPixelBack_widget; 2102 amount = Expression "Amount (pixels)" 5; 2103 2104 command = Magick.command [ 2105 "\"%s\"", 2106 virtpixback._flag, 2107 "-spread", 2108 print amount.expr, 2109 "\"%s\"" 2110 ]; 2111 2112 _result = Magick.system command x; 2113 } 2114} 2115 2116Magick_statistic_item = class 2117 Menuaction "_Statistic" "replace each pixel with statistic from neighbourhood" { 2118 action x = class 2119 _result { 2120 _vislevel = 3; 2121 2122 width = Expression "Width" 5; 2123 height = Expression "Height" 5; 2124 statisticType = Magick.StatType_widget; 2125 2126 command = Magick.command [ 2127 "\"%s\"", 2128 "-statistic", 2129 statisticType._flag, 2130 print width.expr ++ "x" ++ print height.expr, 2131 "\"%s\"" 2132 ]; 2133 2134 _result = Magick.system command x; 2135 } 2136} 2137 2138Magick_swirl_item = class 2139 Menuaction "_Swirl" "swirl around the centre" { 2140 action x = class 2141 _result { 2142 _vislevel = 3; 2143 2144 angle = Magick.angle_widget; 2145 2146 command = Magick.command [ 2147 "\"%s\"", 2148 "-swirl", 2149 print angle.value, 2150 "\"%s\"" 2151 ]; 2152 2153 _result = Magick.system command x; 2154 } 2155} 2156 2157Magick_thresholdMenu_item = class 2158 Menupullright "_Threshold" "make black or white" { 2159 2160 Magick_threshold_item = class 2161 Menuaction "_Threshold" "apply black/white threshold" { 2162 action x = class 2163 _result { 2164 _vislevel = 3; 2165 2166 intensity = Magick.intensity_widget; 2167 channels = Magick.channels_widget; 2168 threshold = Scale "Threshold (percent)" 0 100 50; 2169 2170 command = Magick.command [ 2171 "\"%s\"", 2172 intensity._flag, 2173 channels._flag, 2174 "-threshold", 2175 "\"" ++ print threshold.value ++ "%%\"", 2176 "\"%s\"" 2177 ]; 2178 2179 _result = Magick.system command x; 2180 } 2181 } 2182 2183 Magick_blackThreshold_item = class 2184 Menuaction "_Black threshold" "where below threshold set to black" { 2185 action x = class 2186 _result { 2187 _vislevel = 3; 2188 2189 channels = Magick.channels_widget; 2190 threshold = Scale "Threshold (percent)" 0 100 50; 2191 2192 command = Magick.command [ 2193 "\"%s\"", 2194 channels._flag, 2195 "-black-threshold", 2196 "\"" ++ print threshold.value ++ "%%\"", 2197 "\"%s\"" 2198 ]; 2199 2200 _result = Magick.system command x; 2201 } 2202 } 2203 2204 Magick_whiteThreshold_item = class 2205 Menuaction "_White threshold" "where above threshold set to white" { 2206 action x = class 2207 _result { 2208 _vislevel = 3; 2209 2210 channels = Magick.channels_widget; 2211 threshold = Scale "Threshold (percent)" 0 100 50; 2212 2213 command = Magick.command [ 2214 "\"%s\"", 2215 channels._flag, 2216 "-white-threshold", 2217 "\"" ++ print threshold.value ++ "%%\"", 2218 "\"%s\"" 2219 ]; 2220 2221 _result = Magick.system command x; 2222 } 2223 } 2224 2225 Magick_latThreshold_item = class 2226 Menuaction "_Local Adaptive Threshold" "where above average plus offset set to white, otherwise black" { 2227 action x = class 2228 _result { 2229 _vislevel = 3; 2230 2231 width = Expression "Width" 10; 2232 height = Expression "Height" 10; 2233 offset = Scale "Offset (percent)" (-100) 100 0; 2234 // note: "-lat" doesn't respond to channels 2235 2236 command = Magick.command [ 2237 "\"%s\"", 2238 "-lat", 2239 concat ["\"", print width.expr, "x", print height.expr, 2240 (if offset.value >= 0 then "+" else ""), print offset.value, 2241 "%%\"" 2242 ], 2243 "\"%s\"" 2244 ]; 2245 2246 _result = Magick.system command x; 2247 } 2248 } 2249 2250 Magick_randThreshold_item = class 2251 Menuaction "_Random Threshold" "between specified limits, apply random threshold" { 2252 action x = class 2253 _result { 2254 _vislevel = 3; 2255 2256 channels = Magick.channels_widget; 2257 low = Scale "Low threshold" 0 100 10; 2258 high = Scale "High threshold" 0 100 90; 2259 isPc = Toggle "Thresholds are percent" true; 2260 2261 command = Magick.command [ 2262 "\"%s\"", 2263 channels._flag, 2264 "-random-threshold", 2265 "\"" ++ print low.value ++ "x" ++ print high.value ++ 2266 (if isPc then "%%" else "") ++ "\"", 2267 "\"%s\"" 2268 ]; 2269 2270 _result = Magick.system command x; 2271 } 2272 } 2273 2274} // end ThresholdMenu_item 2275 2276 2277// Note: alternatives include: 2278// convert in.tif -write mpr:TILE +delete -size 200x200 -background XXXX -tile-offset +30+30 tile:mpr:TILE out.tif 2279 2280Magick_tile_item = class 2281 Menuaction "_Tile" "fill given size with tiled image" { 2282 action x = class 2283 _result { 2284 _vislevel = 3; 2285 2286 size = Magick.Size_widget; 2287 2288 command = Magick.command [ 2289 size._flag, 2290 "tile:" ++ "\"%s\"", 2291 "\"%s\"" 2292 ]; 2293 2294 _result = Magick.system command x; 2295 } 2296} 2297 2298Magick_tint_item = class 2299 Menuaction "_Tint" "apply a tint" { 2300 action x = class 2301 _result { 2302 _vislevel = 3; 2303 2304 foreground = Magick.foreground_widget; 2305 amount = Scale "amount (percent)" 0 100 50; 2306 2307 command = Magick.command [ 2308 "\"%s\"", 2309 foreground._flag, 2310 "-tint", 2311 // snibgo note: although the amount is a percentage, it doesn't need "%" character. 2312 print amount.value, 2313 "\"%s\"" 2314 ]; 2315 2316 _result = Magick.system command x; 2317 } 2318} 2319 2320Magick_transparent_item = class 2321 Menuaction "_Transparent" "make this colour transparent" { 2322 action x = class 2323 _result { 2324 _vislevel = 3; 2325 2326 changeColour = Magick.changeCol_widget; 2327 2328 command = Magick.command [ 2329 "\"%s\"", 2330 "-fuzz", 2331 "\"" ++ print changeColour.fuzz.value ++ "%%\"", 2332 (if changeColour.nonMatch then "+" else "-") ++ "transparent", 2333 "\"" ++ changeColour.colour._flag ++ "\"", 2334 "\"%s\"" 2335 ]; 2336 2337 _result = Magick.system command x; 2338 } 2339} 2340 2341Magick_trim_item = class 2342 Menuaction "_Trim" "trims away border" { 2343 action x = class 2344 _result { 2345 _vislevel = 3; 2346 2347 fuzz = Magick.fuzz_widget; 2348 2349 command = Magick.command [ 2350 "\"%s\"", 2351 "-fuzz", 2352 "\"" ++ print fuzz.value ++ "%%\"", 2353 "-trim +repage", 2354 "\"%s\"" 2355 ]; 2356 2357 _result = Magick.system command x; 2358 } 2359} 2360 2361Magick_uniqueCols_item = class 2362 Menuaction "_Unique colours" "discard all but one of any pixel color" { 2363 action x = class 2364 _result { 2365 _vislevel = 3; 2366 2367 command = Magick.command [ 2368 "\"%s\"", 2369 "-unique-colors", 2370 "\"%s\"" 2371 ]; 2372 2373 _result = Magick.system command x; 2374 } 2375} 2376 2377Magick_vignette_item = class 2378 Menuaction "_Vignette" "soften the edges in vignette style" { 2379 action x = class 2380 _result { 2381 _vislevel = 3; 2382 2383 radius = Magick.blur_rad_widget; 2384 sigma = Magick.sigma_widget; 2385 rx = Scale "Rolloff x (percent)" 0 100 10; 2386 ry = Scale "Rolloff y (percent)" 0 100 10; 2387 background = Magick.background_widget; 2388 2389 command = Magick.command [ 2390 "\"%s\"", 2391 background._flag, 2392 "-vignette", 2393 print radius.value ++ "x" ++ print sigma.value ++ 2394 (if rx.value >= 0 then "+" else "") ++ print rx.value ++ 2395 (if ry.value >= 0 then "+" else "") ++ print ry.value, 2396 "\"%s\"" 2397 ]; 2398 2399 _result = Magick.system command x; 2400 } 2401} 2402 2403Magick_wave_item = class 2404 Menuaction "_Wave" "shear the columns into a sine wave" { 2405 action x = class 2406 _result { 2407 _vislevel = 3; 2408 2409 amplitude = Scale "Amplitude (pixels)" 0 100 10; 2410 wavelength = Scale "Wavelength (pixels)" 0 100 10; 2411 2412 command = Magick.command [ 2413 "\"%s\"", 2414 "-wave", 2415 print amplitude.value ++ "x" ++ print wavelength.value, 2416 "\"%s\"" 2417 ]; 2418 2419 _result = Magick.system command x; 2420 } 2421} 2422 2423 2424