ImageEditor.st
changeset 3497 632e25674f39
parent 3496 83bb01ebff3b
child 3505 a7aec486480c
equal deleted inserted replaced
3496:83bb01ebff3b 3497:632e25674f39
    17 	instanceVariableNames:'imageEditView colorMapMode editMode mouseKeyColorMode
    17 	instanceVariableNames:'imageEditView colorMapMode editMode mouseKeyColorMode
    18 		selectedColorIndex postOpenAction imageSeqNr drawingColormap
    18 		selectedColorIndex postOpenAction imageSeqNr drawingColormap
    19 		lastShiftUsedWrap lastGrabbedScreenArea
    19 		lastShiftUsedWrap lastGrabbedScreenArea
    20 		allowedToChangeImageDimensionAndDepth savedImage savedFile'
    20 		allowedToChangeImageDimensionAndDepth savedImage savedFile'
    21 	classVariableNames:'DefaultRelativeSizes LastColormapMode LastDirectory
    21 	classVariableNames:'DefaultRelativeSizes LastColormapMode LastDirectory
    22 		LastSizeString LastURL MaskClipboard LastDepth'
    22 		LastSizeString LastURL MaskClipboard LastDepth
       
    23 		LastNumThresholdGrayColors'
    23 	poolDictionaries:''
    24 	poolDictionaries:''
    24 	category:'Interface-UIPainter'
    25 	category:'Interface-UIPainter'
    25 !
    26 !
    26 
    27 
    27 !ImageEditor class methodsFor:'documentation'!
    28 !ImageEditor class methodsFor:'documentation'!
  2849             translateLabel: true
  2850             translateLabel: true
  2850             submenuChannel: modeMenu
  2851             submenuChannel: modeMenu
  2851             isVisible: modeMenuVisible
  2852             isVisible: modeMenuVisible
  2852           )
  2853           )
  2853          (MenuItem
  2854          (MenuItem
  2854             label: 'Colors'
  2855             label: 'Image'
  2855             translateLabel: true
  2856             translateLabel: true
  2856             submenuChannel: menuColors
  2857             submenuChannel: menuColors
  2857           )
  2858           )
  2858          (MenuItem
  2859          (MenuItem
  2859             label: 'Settings'
  2860             label: 'Settings'
  2874           )
  2875           )
  2875          )
  2876          )
  2876         nil
  2877         nil
  2877         nil
  2878         nil
  2878       )
  2879       )
       
  2880 
       
  2881     "Modified: / 23-10-2017 / 10:39:43 / cg"
  2879 !
  2882 !
  2880 
  2883 
  2881 menuColors
  2884 menuColors
  2882     "This resource specification was automatically generated
  2885     "This resource specification was automatically generated
  2883      by the MenuEditor of ST/X."
  2886      by the MenuEditor of ST/X."
  3122                (MenuItem
  3125                (MenuItem
  3123                   label: 'Make GrayScale with Depth (Threshold)...'
  3126                   label: 'Make GrayScale with Depth (Threshold)...'
  3124                   itemValue: thresholdGrayToDepth
  3127                   itemValue: thresholdGrayToDepth
  3125                 )
  3128                 )
  3126                (MenuItem
  3129                (MenuItem
       
  3130                   label: 'Make GrayScale with N Gray Colors (Dither)...'
       
  3131                   itemValue: ditherToNumberOfGrayColors
       
  3132                 )
       
  3133                (MenuItem
       
  3134                   label: 'Make GrayScale with N Gray Colors (Threshold)...'
       
  3135                   itemValue: thresholdToNumberOfGrayColors
       
  3136                 )
       
  3137                (MenuItem
  3127                   label: '-'
  3138                   label: '-'
  3128                 )
  3139                 )
  3129                (MenuItem
  3140                (MenuItem
  3130                   label: 'Make Slightly Brighter'
  3141                   label: 'Make Slightly Brighter'
  3131                   itemValue: makeSlightlyBrighter
  3142                   itemValue: makeSlightlyBrighter
  3204          )
  3215          )
  3205         nil
  3216         nil
  3206         nil
  3217         nil
  3207       )
  3218       )
  3208 
  3219 
  3209     "Modified: / 31-08-2017 / 14:43:51 / cg"
  3220     "Modified: / 23-10-2017 / 11:18:58 / cg"
  3210 !
  3221 !
  3211 
  3222 
  3212 menuEdit
  3223 menuEdit
  3213     <resource: #menu>
       
  3214     "This resource specification was automatically generated
  3224     "This resource specification was automatically generated
  3215      by the MenuEditor of ST/X."
  3225      by the MenuEditor of ST/X."
       
  3226 
  3216     "Do not manually edit this!! If it is corrupted,
  3227     "Do not manually edit this!! If it is corrupted,
  3217      the MenuEditor may not be able to read the specification."
  3228      the MenuEditor may not be able to read the specification."
       
  3229 
       
  3230 
  3218     "
  3231     "
  3219      MenuEditor new openOnClass:ImageEditor andSelector:#menuEdit
  3232      MenuEditor new openOnClass:ImageEditor andSelector:#menuEdit
  3220      (Menu new fromLiteralArrayEncoding:(ImageEditor menuEdit)) startUp"
  3233      (Menu new fromLiteralArrayEncoding:(ImageEditor menuEdit)) startUp
  3221     
  3234     "
  3222     ^ #( #Menu
  3235 
  3223       #((MenuItem activeHelpKey: editUndo enabled: canUndoHolder label: 'Undo' itemValue: doUndo) (MenuItem label: '-') (MenuItem enabled: imageIsLoadedHolder label: 'Copy to Clipboard' itemValue: doCopyImageToClipboard) (MenuItem label: '-') (MenuItem activeHelpKey: editResize enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: 'Resize...' itemValue: doResizeImage) (MenuItem activeHelpKey: editMagnifyImage enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: 'Magnify...' itemValue: doMagnifyImage) (MenuItem activeHelpKey: editMagnifyImage enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: 'Magnify By...' itemValue: doMagnifyImageBy) (MenuItem activeHelpKey: editRotate enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: 'Rotate...' itemValue: doRotateImage) (MenuItem activeHelpKey: edit3DProjection enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: '3D Projection...' itemValue: do3DProjection) (MenuItem enabled: imageIsLoadedAndAllowedToFlipHolder label: 'Flip' submenu: (Menu ((MenuItem activeHelpKey: editFlipVertical enabled: imageIsLoadedAndNotReadonlyHolder label: 'Flip - Vertical' itemValue: doFlipVertical labelImage: (ResourceRetriever ImageEditor flipVerticalIcon 'Flip - Vertical')) (MenuItem activeHelpKey: editFlipHorizontal enabled: imageIsLoadedAndNotReadonlyHolder label: 'Flip - Horizontal' itemValue: doFlipHorizontal labelImage: (ResourceRetriever ImageEditor flipHorizontalIcon 'Flip - Horizontal'))) nil nil)) (MenuItem label: '-') (MenuItem enabled: imageIsLoadedAndAllowedToChangeImageDimension label: 'Crop' submenu: (Menu ((MenuItem activeHelpKey: cropManual label: 'Manual...' itemValue: doCropManual) (MenuItem label: '-' isVisible: false) (MenuItem activeHelpKey: autoCropAll label: 'All' itemValue: autoCropAll) (MenuItem label: '-') (MenuItem activeHelpKey: autoCropLeft label: 'Left' itemValue: autoCropLeft) (MenuItem activeHelpKey: autoCropRight label: 'Right' itemValue: autoCropRight) (MenuItem activeHelpKey: autoCropTop label: 'Top' itemValue: autoCropTop) (MenuItem activeHelpKey: autoCropBottom label: 'Bottom' itemValue: autoCropBottom)) nil nil)) (MenuItem activeHelpKey: uncropManual enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth label: 'Uncrop (Add Border)...' itemValue: doUnCropManual) (MenuItem activeHelpKey: shiftManual enabled: imageIsLoadedAndAllowedToChangeImageDimension label: 'Shift...' itemValue: doShiftManual) (MenuItem label: '-') (MenuItem activeHelpKey: fileEditMask enabled: hasMaskHolder label: 'Edit Mask' itemValue: doEditMask) (MenuItem enabled: imageIsLoadedAndNotReadonlyHolder label: 'Text...' itemValue: doInsertTextFromUser) (MenuItem label: '-') (MenuItem enabled: imageIsLoadedHolder label: 'Animation Sequence' submenu: (Menu ((MenuItem enabled: imageHasNextImageHolder label: 'Next in Sequence' itemValue: nextImageInSequence) (MenuItem enabled: imageHasPreviousImageHolder label: 'Previous in Sequence' itemValue: previousImageInSequence) (MenuItem label: '-') (MenuItem enabled: imageHasImageSequenceHolder label: 'Edit each from Sequence' itemValue: editEachImageFromSequence)) nil nil)))
  3236     <resource: #menu>
  3224       nil
  3237 
  3225       nil )
  3238     ^ 
  3226 
  3239      #(Menu
  3227     "Modified: / 12-04-2017 / 09:25:18 / cg"
  3240         (
  3228     "Modified (comment): / 30-08-2017 / 00:30:38 / cg"
  3241          (MenuItem
       
  3242             activeHelpKey: editUndo
       
  3243             enabled: canUndoHolder
       
  3244             label: 'Undo'
       
  3245             itemValue: doUndo
       
  3246           )
       
  3247          (MenuItem
       
  3248             label: '-'
       
  3249           )
       
  3250          (MenuItem
       
  3251             enabled: imageIsLoadedHolder
       
  3252             label: 'Copy to Clipboard'
       
  3253             itemValue: doCopyImageToClipboard
       
  3254           )
       
  3255          (MenuItem
       
  3256             label: '-'
       
  3257           )
       
  3258          (MenuItem
       
  3259             activeHelpKey: editResize
       
  3260             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3261             label: 'Resize...'
       
  3262             itemValue: doResizeImage
       
  3263           )
       
  3264          (MenuItem
       
  3265             activeHelpKey: editMagnifyImage
       
  3266             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3267             label: 'Magnify...'
       
  3268             itemValue: doMagnifyImage
       
  3269           )
       
  3270          (MenuItem
       
  3271             activeHelpKey: editMagnifyImage
       
  3272             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3273             label: 'Magnify By...'
       
  3274             itemValue: doMagnifyImageBy
       
  3275           )
       
  3276          (MenuItem
       
  3277             activeHelpKey: editRotate
       
  3278             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3279             label: 'Rotate...'
       
  3280             itemValue: doRotateImage
       
  3281           )
       
  3282          (MenuItem
       
  3283             activeHelpKey: edit3DProjection
       
  3284             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3285             label: '3D Projection...'
       
  3286             itemValue: do3DProjection
       
  3287           )
       
  3288          (MenuItem
       
  3289             enabled: imageIsLoadedAndAllowedToFlipHolder
       
  3290             label: 'Flip'
       
  3291             submenu: 
       
  3292            (Menu
       
  3293               (
       
  3294                (MenuItem
       
  3295                   activeHelpKey: editFlipVertical
       
  3296                   enabled: imageIsLoadedAndNotReadonlyHolder
       
  3297                   label: 'Flip - Vertical'
       
  3298                   itemValue: doFlipVertical
       
  3299                   labelImage: (ResourceRetriever ImageEditor flipVerticalIcon 'Flip - Vertical')
       
  3300                 )
       
  3301                (MenuItem
       
  3302                   activeHelpKey: editFlipHorizontal
       
  3303                   enabled: imageIsLoadedAndNotReadonlyHolder
       
  3304                   label: 'Flip - Horizontal'
       
  3305                   itemValue: doFlipHorizontal
       
  3306                   labelImage: (ResourceRetriever ImageEditor flipHorizontalIcon 'Flip - Horizontal')
       
  3307                 )
       
  3308                )
       
  3309               nil
       
  3310               nil
       
  3311             )
       
  3312           )
       
  3313          (MenuItem
       
  3314             label: '-'
       
  3315           )
       
  3316          (MenuItem
       
  3317             enabled: imageIsLoadedAndAllowedToChangeImageDimension
       
  3318             label: 'Crop'
       
  3319             submenu: 
       
  3320            (Menu
       
  3321               (
       
  3322                (MenuItem
       
  3323                   activeHelpKey: cropManual
       
  3324                   label: 'Manual...'
       
  3325                   itemValue: doCropManual
       
  3326                 )
       
  3327                (MenuItem
       
  3328                   label: '-'
       
  3329                   isVisible: false
       
  3330                 )
       
  3331                (MenuItem
       
  3332                   activeHelpKey: autoCropAll
       
  3333                   label: 'All'
       
  3334                   itemValue: autoCropAll
       
  3335                 )
       
  3336                (MenuItem
       
  3337                   label: '-'
       
  3338                 )
       
  3339                (MenuItem
       
  3340                   activeHelpKey: autoCropLeft
       
  3341                   label: 'Left'
       
  3342                   itemValue: autoCropLeft
       
  3343                 )
       
  3344                (MenuItem
       
  3345                   activeHelpKey: autoCropRight
       
  3346                   label: 'Right'
       
  3347                   itemValue: autoCropRight
       
  3348                 )
       
  3349                (MenuItem
       
  3350                   activeHelpKey: autoCropTop
       
  3351                   label: 'Top'
       
  3352                   itemValue: autoCropTop
       
  3353                 )
       
  3354                (MenuItem
       
  3355                   activeHelpKey: autoCropBottom
       
  3356                   label: 'Bottom'
       
  3357                   itemValue: autoCropBottom
       
  3358                 )
       
  3359                )
       
  3360               nil
       
  3361               nil
       
  3362             )
       
  3363           )
       
  3364          (MenuItem
       
  3365             activeHelpKey: uncropManual
       
  3366             enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth
       
  3367             label: 'Uncrop (Add Border)...'
       
  3368             itemValue: doUnCropManual
       
  3369           )
       
  3370          (MenuItem
       
  3371             activeHelpKey: shiftManual
       
  3372             enabled: imageIsLoadedAndAllowedToChangeImageDimension
       
  3373             label: 'Shift...'
       
  3374             itemValue: doShiftManual
       
  3375           )
       
  3376          (MenuItem
       
  3377             label: '-'
       
  3378           )
       
  3379          (MenuItem
       
  3380             activeHelpKey: fileEditMask
       
  3381             enabled: hasMaskHolder
       
  3382             label: 'Edit Mask'
       
  3383             itemValue: doEditMask
       
  3384           )
       
  3385          (MenuItem
       
  3386             enabled: imageIsLoadedAndNotReadonlyHolder
       
  3387             label: 'Text...'
       
  3388             itemValue: doInsertTextFromUser
       
  3389           )
       
  3390          (MenuItem
       
  3391             label: '-'
       
  3392           )
       
  3393          (MenuItem
       
  3394             enabled: imageIsLoadedHolder
       
  3395             label: 'Animation Sequence'
       
  3396             submenu: 
       
  3397            (Menu
       
  3398               (
       
  3399                (MenuItem
       
  3400                   enabled: imageHasNextImageHolder
       
  3401                   label: 'Next in Sequence'
       
  3402                   itemValue: nextImageInSequence
       
  3403                 )
       
  3404                (MenuItem
       
  3405                   enabled: imageHasPreviousImageHolder
       
  3406                   label: 'Previous in Sequence'
       
  3407                   itemValue: previousImageInSequence
       
  3408                 )
       
  3409                (MenuItem
       
  3410                   label: '-'
       
  3411                 )
       
  3412                (MenuItem
       
  3413                   enabled: imageHasImageSequenceHolder
       
  3414                   label: 'Edit each from Sequence'
       
  3415                   itemValue: editEachImageFromSequence
       
  3416                 )
       
  3417                )
       
  3418               nil
       
  3419               nil
       
  3420             )
       
  3421           )
       
  3422          )
       
  3423         nil
       
  3424         nil
       
  3425       )
  3229 !
  3426 !
  3230 
  3427 
  3231 menuFile
  3428 menuFile
  3232     "This resource specification was automatically generated
  3429     "This resource specification was automatically generated
  3233      by the MenuEditor of ST/X."
  3430      by the MenuEditor of ST/X."
  7793     "Created: / 24-08-2017 / 17:49:42 / cg"
  7990     "Created: / 24-08-2017 / 17:49:42 / cg"
  7794 !
  7991 !
  7795 
  7992 
  7796 ditherGrayToDepth:depth
  7993 ditherGrayToDepth:depth
  7797     self withExecuteCursorDo:[
  7994     self withExecuteCursorDo:[
  7798         |newImage|
  7995         |image newImage|
  7799 
  7996 
       
  7997         image := self image.
  7800         depth == 1 ifTrue:[
  7998         depth == 1 ifTrue:[
  7801             newImage := self image asErrorDitheredMonochromeImage
  7999             newImage := image asErrorDitheredMonochromeImage
  7802         ] ifFalse:[
  8000         ] ifFalse:[
  7803             newImage := self image asGrayImageDepth:depth dither:#floydSteinberg.
  8001             newImage := image asGrayImageDepth:depth dither:#floydSteinberg.
  7804         ].
  8002         ].
  7805         imageEditView newImageWithUndo:newImage.
  8003         imageEditView newImageWithUndo:newImage.
  7806     ].
  8004     ].
  7807 
  8005 
  7808     "Created: / 24-08-2017 / 17:51:07 / cg"
  8006     "Created: / 24-08-2017 / 17:51:07 / cg"
  7809     "Modified: / 30-08-2017 / 01:18:43 / cg"
  8007     "Modified: / 23-10-2017 / 10:58:18 / cg"
  7810 !
  8008 !
  7811 
  8009 
  7812 ditherToDepth
  8010 ditherToDepth
  7813     self askForDepthThenDo:[:depth |
  8011     self askForDepthThenDo:[:depth |
  7814         self convertToDepth:depth dither:true
  8012         self convertToDepth:depth dither:true
  7815     ].
  8013     ].
  7816 
  8014 
  7817     "Created: / 07-07-2006 / 13:22:10 / cg"
  8015     "Created: / 07-07-2006 / 13:22:10 / cg"
  7818     "Modified: / 30-08-2017 / 00:34:42 / cg"
  8016     "Modified: / 30-08-2017 / 00:34:42 / cg"
       
  8017 !
       
  8018 
       
  8019 ditherToNumberOfGrayColors
       
  8020     |oldDepth numGrayColors suggestion grayImage userInput grayColors|
       
  8021 
       
  8022     oldDepth := self image depth.
       
  8023     grayImage := self image asGrayImageDepth:8.
       
  8024     
       
  8025     suggestion := LastNumThresholdGrayColors notNil ifTrue:[
       
  8026                     LastNumThresholdGrayColors
       
  8027                   ] ifFalse:[
       
  8028                     oldDepth > 8 
       
  8029                         ifTrue:[256] 
       
  8030                         ifFalse:[2 raisedTo:((oldDepth // 2 - 1) nextPowerOf2)]
       
  8031                   ].
       
  8032 
       
  8033     Dialog modifyingBoxWith:[:box |
       
  8034         |preview slider update thresholdValue|
       
  8035 
       
  8036         thresholdValue := suggestion asValue.
       
  8037 
       
  8038         box enterField 
       
  8039             converter:(PrintConverter new initForNumber);
       
  8040             model:thresholdValue.
       
  8041 
       
  8042         box verticalPanel extent:1.0 @ 300.
       
  8043 
       
  8044         box verticalPanel add:(slider := HorizontalSlider new start:2 stop:256 step:1).
       
  8045         slider model:thresholdValue.
       
  8046         slider width:1.0; leftInset:4; rightInset:4.
       
  8047 
       
  8048         box verticalPanel add:(preview := ImageView new).
       
  8049         preview extent:300 @300.
       
  8050         preview level:-1.
       
  8051         box verticalPanel horizontalLayout:#fitSpace.
       
  8052 
       
  8053         update := 
       
  8054             [
       
  8055                 |numGrayColors depth s t tImage|
       
  8056 
       
  8057                 numGrayColors := thresholdValue value clampBetween:2 and:256.
       
  8058                 grayColors := Color grayColorVector:numGrayColors.
       
  8059                 tImage := grayImage asDitheredImageUsing:grayColors depth:(grayImage depth).
       
  8060                 
       
  8061                 preview image:(tImage magnifiedPreservingRatioTo:preview extent).
       
  8062             ].
       
  8063         update value.
       
  8064         box enterField acceptOnLostFocus:true.
       
  8065         box enterField acceptOnLeave:true.
       
  8066         thresholdValue onChangeEvaluate:update.
       
  8067 
       
  8068     ] do:[
       
  8069         userInput := Dialog request:'Number of Gray Colors ?' initialAnswer:suggestion asString.
       
  8070     ].
       
  8071     userInput isEmptyOrNil ifTrue:[^ self].
       
  8072 
       
  8073 
       
  8074     numGrayColors := Number readFrom:userInput onError:nil.
       
  8075     numGrayColors isNil ifTrue:[^ self].
       
  8076 
       
  8077     grayColors := Color grayColorVector:numGrayColors.
       
  8078     imageEditView newImageWithUndo:(grayImage asDitheredImageUsing:grayColors depth:(grayImage depth)).
       
  8079 
       
  8080     "Created: / 23-10-2017 / 11:17:44 / cg"
  7819 !
  8081 !
  7820 
  8082 
  7821 do3DProjection
  8083 do3DProjection
  7822     "make a naive 3D projection;
  8084     "make a naive 3D projection;
  7823      can be used to create those typical marketing images as seen in web pages"
  8085      can be used to create those typical marketing images as seen in web pages"
  8325 
  8587 
  8326     ] do:[
  8588     ] do:[
  8327         userInput := Dialog request:'Threshold (0=black; 1=white) ?' initialAnswer:0.5.
  8589         userInput := Dialog request:'Threshold (0=black; 1=white) ?' initialAnswer:0.5.
  8328     ].
  8590     ].
  8329     userInput isEmptyOrNil ifTrue:[^ self].
  8591     userInput isEmptyOrNil ifTrue:[^ self].
       
  8592 
  8330     thresholdBrighness := Number readFrom:userInput onError:nil.
  8593     thresholdBrighness := Number readFrom:userInput onError:nil.
  8331     thresholdBrighness isNil ifTrue:[^ self].
  8594     thresholdBrighness isNil ifTrue:[^ self].
  8332 
  8595 
  8333     thresholdBrighness := thresholdBrighness clampBetween:0 and:1.
  8596     thresholdBrighness := thresholdBrighness clampBetween:0 and:1.
  8334     
  8597     
  8335     imageEditView newImageWithUndo:(image asThresholdMonochromeImage:thresholdBrighness)
  8598     imageEditView newImageWithUndo:(image asThresholdMonochromeImage:thresholdBrighness)
  8336 
  8599 
  8337     "Created: / 24-08-2017 / 15:26:44 / cg"
  8600     "Created: / 24-08-2017 / 15:26:44 / cg"
  8338     "Modified: / 24-08-2017 / 17:54:21 / cg"
  8601     "Modified: / 24-08-2017 / 17:54:21 / cg"
  8339     "Modified (format): / 01-09-2017 / 10:28:24 / cg"
  8602     "Modified (format): / 23-10-2017 / 10:42:52 / cg"
  8340 !
  8603 !
  8341 
  8604 
  8342 makeNegative
  8605 makeNegative
  8343     "negates current image by negating the color map"
  8606     "negates current image by negating the color map"
  8344 
  8607 
  8374     self askForDepthThenDo:[:depth |
  8637     self askForDepthThenDo:[:depth |
  8375         self convertToDepth:depth dither:false
  8638         self convertToDepth:depth dither:false
  8376     ].
  8639     ].
  8377 
  8640 
  8378     "Created: / 30-08-2017 / 00:31:33 / cg"
  8641     "Created: / 30-08-2017 / 00:31:33 / cg"
       
  8642 !
       
  8643 
       
  8644 thresholdToNumberOfGrayColors
       
  8645     |oldDepth numGrayColors suggestion grayImage userInput grayColors|
       
  8646 
       
  8647     oldDepth := self image depth.
       
  8648     grayImage := self image asGrayImageDepth:8.
       
  8649     
       
  8650     suggestion := LastNumThresholdGrayColors notNil ifTrue:[
       
  8651                     LastNumThresholdGrayColors
       
  8652                   ] ifFalse:[
       
  8653                     oldDepth > 8 
       
  8654                         ifTrue:[256] 
       
  8655                         ifFalse:[2 raisedTo:((oldDepth // 2 - 1) nextPowerOf2)]
       
  8656                   ].
       
  8657 
       
  8658     Dialog modifyingBoxWith:[:box |
       
  8659         |preview slider update thresholdValue|
       
  8660 
       
  8661         thresholdValue := suggestion asValue.
       
  8662 
       
  8663         box enterField 
       
  8664             converter:(PrintConverter new initForNumber);
       
  8665             model:thresholdValue.
       
  8666 
       
  8667         box verticalPanel extent:1.0 @ 300.
       
  8668 
       
  8669         box verticalPanel add:(slider := HorizontalSlider new start:2 stop:256 step:1).
       
  8670         slider model:thresholdValue.
       
  8671         slider width:1.0; leftInset:4; rightInset:4.
       
  8672 
       
  8673         box verticalPanel add:(preview := ImageView new).
       
  8674         preview extent:300 @300.
       
  8675         preview level:-1.
       
  8676         box verticalPanel horizontalLayout:#fitSpace.
       
  8677 
       
  8678         update := 
       
  8679             [
       
  8680                 |numGrayColors depth s t tImage|
       
  8681 
       
  8682                 numGrayColors := thresholdValue value clampBetween:2 and:256.
       
  8683                 grayColors := Color grayColorVector:numGrayColors.
       
  8684                 tImage := grayImage asNearestPaintImageDepth:(grayImage depth) colors:grayColors.
       
  8685                 
       
  8686                 preview image:(tImage magnifiedPreservingRatioTo:preview extent).
       
  8687             ].
       
  8688         update value.
       
  8689         box enterField acceptOnLostFocus:true.
       
  8690         box enterField acceptOnLeave:true.
       
  8691         thresholdValue onChangeEvaluate:update.
       
  8692 
       
  8693     ] do:[
       
  8694         userInput := Dialog request:'Number of Gray Colors ?' initialAnswer:suggestion asString.
       
  8695     ].
       
  8696     userInput isEmptyOrNil ifTrue:[^ self].
       
  8697 
       
  8698 
       
  8699     numGrayColors := Number readFrom:userInput onError:nil.
       
  8700     numGrayColors isNil ifTrue:[^ self].
       
  8701 
       
  8702     grayColors := Color grayColorVector:numGrayColors.
       
  8703     imageEditView newImageWithUndo:(grayImage asNearestPaintImageDepth:(grayImage depth) colors:grayColors).
       
  8704 
       
  8705     "Created: / 23-10-2017 / 10:55:15 / cg"
  8379 ! !
  8706 ! !
  8380 
  8707 
  8381 !ImageEditor methodsFor:'user actions-editing-colors'!
  8708 !ImageEditor methodsFor:'user actions-editing-colors'!
  8382 
  8709 
  8383 convertToDepth:depth dither:doDither
  8710 convertToDepth:depth dither:doDither