ImageEditor.st
changeset 3468 2cf3a445a2f6
parent 3466 2d5ea09863c6
child 3469 52837773925b
equal deleted inserted replaced
3467:2f9054aca4c6 3468:2cf3a445a2f6
  1505     "
  1505     "
  1506 
  1506 
  1507     <resource: #canvas>
  1507     <resource: #canvas>
  1508 
  1508 
  1509     ^ 
  1509     ^ 
  1510      #(FullSpec
  1510     #(FullSpec
  1511         name: changeHLSDialogSpec
  1511        name: changeHLSDialogSpec
  1512         window: 
  1512        window: 
  1513        (WindowSpec
  1513       (WindowSpec
  1514           label: 'HLS Edit Dialog'
  1514          label: 'HLS Edit Dialog'
  1515           name: 'HLS Edit Dialog'
  1515          name: 'HLS Edit Dialog'
  1516           min: (Point 10 10)
  1516          min: (Point 10 10)
  1517           bounds: (Rectangle 0 0 312 258)
  1517          bounds: (Rectangle 0 0 378 312)
  1518         )
  1518        )
  1519         component: 
  1519        component: 
  1520        (SpecCollection
  1520       (SpecCollection
  1521           collection: (
  1521          collection: (
  1522            (LabelSpec
  1522           (LabelSpec
  1523               label: 'Hue-Shift:'
  1523              label: 'Hue-Shift:'
  1524               name: 'HueLabel'
  1524              name: 'HueLabel'
  1525               layout: (LayoutFrame 20 0 21 0 120 0 43 0)
  1525              layout: (LayoutFrame 20 0 21 0 187 0 43 0)
  1526               translateLabel: true
  1526              translateLabel: true
  1527               adjust: right
  1527              adjust: right
  1528             )
  1528            )
  1529            (InputFieldSpec
  1529           (InputFieldSpec
  1530               name: 'HueShiftEntryField'
  1530              name: 'HueShiftEntryField'
  1531               layout: (LayoutFrame 123 0 21 0 166 0 43 0)
  1531              layout: (LayoutFrame 194 0 21 0 237 0 43 0)
  1532               tabable: true
  1532              tabable: true
  1533               model: hueShiftAmount
  1533              model: hueShiftAmount
  1534               type: numberInRange
  1534              type: numberInRange
  1535               minValue: 0
  1535              minValue: 0
  1536               maxValue: 360
  1536              maxValue: 360
  1537               acceptChannel: acceptChannel
  1537              acceptChannel: acceptChannel
  1538               acceptOnPointerLeave: false
  1538              acceptOnPointerLeave: false
  1539             )
  1539            )
  1540            (ThumbWheelSpec
  1540           (ThumbWheelSpec
  1541               name: 'HueWheel'
  1541              name: 'HueWheel'
  1542               layout: (LayoutFrame 180 0 22 0 297 0 42 0)
  1542              layout: (LayoutFrame 246 0 22 0 363 0 42 0)
  1543               model: hueShiftAmount
  1543              model: hueShiftAmount
  1544               orientation: horizontal
  1544              orientation: horizontal
  1545               step: 1
  1545              step: 1
  1546               endlessRotation: true
  1546              endlessRotation: true
  1547             )
  1547            )
  1548            (LabelSpec
  1548           (LabelSpec
  1549               label: 'Light Factor:'
  1549              label: 'Light Factor:'
  1550               name: 'LightLabel'
  1550              name: 'LightLabel'
  1551               layout: (LayoutFrame 18 0 50 0 120 0 72 0)
  1551              layout: (LayoutFrame 20 0 50 0 187 0 72 0)
  1552               translateLabel: true
  1552              translateLabel: true
  1553               adjust: right
  1553              adjust: right
  1554             )
  1554            )
  1555            (InputFieldSpec
  1555           (InputFieldSpec
  1556               name: 'LightEntryField'
  1556              name: 'LightEntryField'
  1557               layout: (LayoutFrame 123 0 50 0 166 0 72 0)
  1557              layout: (LayoutFrame 194 0 50 0 237 0 72 0)
  1558               tabable: true
  1558              tabable: true
  1559               model: lightAmount
  1559              model: lightAmount
  1560               type: numberInRange
  1560              type: numberInRange
  1561               minValue: 0
  1561              minValue: 0
  1562               maxValue: 1000
  1562              maxValue: 1000
  1563               acceptChannel: acceptChannel
  1563              acceptChannel: acceptChannel
  1564               acceptOnPointerLeave: false
  1564              acceptOnPointerLeave: false
  1565             )
  1565            )
  1566            (ThumbWheelSpec
  1566           (ThumbWheelSpec
  1567               name: 'LightWheel'
  1567              name: 'LightWheel'
  1568               layout: (LayoutFrame 180 0 51 0 297 0 71 0)
  1568              layout: (LayoutFrame 246 0 51 0 363 0 71 0)
  1569               model: lightAmount
  1569              model: lightAmount
  1570               orientation: horizontal
  1570              orientation: horizontal
  1571               stop: 1000
  1571              stop: 1000
  1572               step: 1
  1572              step: 1
  1573             )
  1573            )
  1574            (LabelSpec
  1574           (LabelSpec
  1575               label: 'Saturation Factor:'
  1575              label: 'Saturation Factor:'
  1576               name: 'SaturationLabel'
  1576              name: 'SaturationLabel'
  1577               layout: (LayoutFrame 9 0 79 0 120 0 101 0)
  1577              layout: (LayoutFrame 20 0 79 0 187 0 101 0)
  1578               translateLabel: true
  1578              translateLabel: true
  1579               adjust: right
  1579              adjust: right
  1580             )
  1580            )
  1581            (InputFieldSpec
  1581           (InputFieldSpec
  1582               name: 'SaturationEntryField'
  1582              name: 'SaturationEntryField'
  1583               layout: (LayoutFrame 123 0 79 0 166 0 101 0)
  1583              layout: (LayoutFrame 194 0 79 0 237 0 101 0)
  1584               tabable: true
  1584              tabable: true
  1585               model: saturationAmount
  1585              model: saturationAmount
  1586               type: numberInRange
  1586              type: numberInRange
  1587               minValue: 0
  1587              minValue: 0
  1588               maxValue: 1000
  1588              maxValue: 1000
  1589               acceptChannel: acceptChannel
  1589              acceptChannel: acceptChannel
  1590               acceptOnPointerLeave: false
  1590              acceptOnPointerLeave: false
  1591             )
  1591            )
  1592            (ThumbWheelSpec
  1592           (ThumbWheelSpec
  1593               name: 'SaturationWheel'
  1593              name: 'SaturationWheel'
  1594               layout: (LayoutFrame 180 0 80 0 297 0 100 0)
  1594              layout: (LayoutFrame 246 0 80 0 363 0 100 0)
  1595               model: saturationAmount
  1595              model: saturationAmount
  1596               orientation: horizontal
  1596              orientation: horizontal
  1597               stop: 1000
  1597              stop: 1000
  1598               step: 1
  1598              step: 1
  1599             )
  1599            )
  1600            (LabelSpec
  1600           (LabelSpec
  1601               label: 'Color Shift'
  1601              label: 'Color Shift'
  1602               name: 'Label2'
  1602              name: 'Label2'
  1603               layout: (LayoutFrame 5 0 110 0 -15 0.5 132 0)
  1603              layout: (LayoutFrame 5 0 127 0 -15 0.5 149 0)
  1604               translateLabel: true
  1604              translateLabel: true
  1605             )
  1605            )
  1606            (LabelSpec
  1606           (LabelSpec
  1607               name: 'HueColorLabel'
  1607              name: 'HueColorLabel'
  1608               layout: (LayoutFrame 18 0.0 133 0 -41 0.5 217 0)
  1608              layout: (LayoutFrame 18 0.0 150 0 -41 0.5 234 0)
  1609               level: -1
  1609              level: -1
  1610               backgroundChannel: hlsColor
  1610              backgroundChannel: hlsColor
  1611               translateLabel: true
  1611              translateLabel: true
  1612             )
  1612            )
  1613            (LabelSpec
  1613           (LabelSpec
  1614               label: 'Preview'
  1614              label: 'Preview'
  1615               name: 'Label3'
  1615              name: 'Label3'
  1616               layout: (LayoutFrame 5 0.5 110 0 -5 1 132 0)
  1616              layout: (LayoutFrame 5 0.5 127 0 -5 1 149 0)
  1617               translateLabel: true
  1617              translateLabel: true
  1618             )
  1618            )
  1619            (LabelSpec
  1619           (LabelSpec
  1620               name: 'PreviewLabel'
  1620              name: 'PreviewLabel'
  1621               layout: (LayoutFrame 36 0.5 133 0 -23 1.0 217 0)
  1621              layout: (LayoutFrame 36 0.5 150 0 -23 1.0 234 0)
  1622               level: -1
  1622              level: -1
  1623               translateLabel: true
  1623              translateLabel: true
  1624               labelChannel: previewImageHolder
  1624              labelChannel: previewImageHolder
  1625             )
  1625            )
  1626            (HorizontalPanelViewSpec
  1626           (HorizontalPanelViewSpec
  1627               name: 'HorizontalPanel1'
  1627              name: 'HorizontalPanel1'
  1628               layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1)
  1628              layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1)
  1629               horizontalLayout: fitSpace
  1629              horizontalLayout: fitSpace
  1630               verticalLayout: center
  1630              verticalLayout: center
  1631               horizontalSpace: 3
  1631              horizontalSpace: 3
  1632               verticalSpace: 3
  1632              verticalSpace: 3
  1633               reverseOrderIfOKAtLeft: true
  1633              reverseOrderIfOKAtLeft: true
  1634               component: 
  1634              component: 
  1635              (SpecCollection
  1635             (SpecCollection
  1636                 collection: (
  1636                collection: (
  1637                  (ActionButtonSpec
  1637                 (ActionButtonSpec
  1638                     label: 'Cancel'
  1638                    label: 'Cancel'
  1639                     name: 'Button1'
  1639                    name: 'Button1'
  1640                     translateLabel: true
  1640                    translateLabel: true
  1641                     tabable: true
  1641                    tabable: true
  1642                     model: cancel
  1642                    model: cancel
  1643                     extent: (Point 151 22)
  1643                    extent: (Point 183 28)
  1644                   )
       
  1645                  (ActionButtonSpec
       
  1646                     label: 'OK'
       
  1647                     name: 'Button2'
       
  1648                     translateLabel: true
       
  1649                     tabable: true
       
  1650                     model: accept
       
  1651                     extent: (Point 152 22)
       
  1652                   )
       
  1653                  )
  1644                  )
  1654                
  1645                 (ActionButtonSpec
  1655               )
  1646                    label: 'OK'
  1656             )
  1647                    name: 'Button2'
       
  1648                    translateLabel: true
       
  1649                    tabable: true
       
  1650                    model: accept
       
  1651                    extent: (Point 183 28)
       
  1652                  )
       
  1653                 )
       
  1654               
       
  1655              )
       
  1656              keepSpaceForOSXResizeHandleH: true
  1657            )
  1657            )
  1658          
  1658           )
  1659         )
  1659         
  1660       )
  1660        )
       
  1661      )
  1661 !
  1662 !
  1662 
  1663 
  1663 cropSpec
  1664 cropSpec
  1664     "This resource specification was automatically generated
  1665     "This resource specification was automatically generated
  1665      by the UIPainter of ST/X."
  1666      by the UIPainter of ST/X."
  6138     "Created: / 12-03-1999 / 00:20:28 / cg"
  6139     "Created: / 12-03-1999 / 00:20:28 / cg"
  6139     "Modified: / 16-02-2017 / 10:17:25 / cg"
  6140     "Modified: / 16-02-2017 / 10:17:25 / cg"
  6140 !
  6141 !
  6141 
  6142 
  6142 changeHLS
  6143 changeHLS
  6143     "interactive Hue/Light/Saturation editing"
  6144     "interactive Hue/Light/Saturation editing with thumbWheels"
  6144 
  6145 
  6145     |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel 
  6146     |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel 
  6146      shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema
  6147      shiftAction originalAvgColor avgColorHolder avgColor shiftedColor shiftProcess readySema
  6147      originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels
  6148      originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels
  6148      anyChange |
  6149      anyChange |
  6149 
  6150 
  6150     "/ compute the averageColor in the background (while asking user)
       
  6151     avgColorHolder := nil asValue.
  6151     avgColorHolder := nil asValue.
  6152     previewImageHolder := nil asValue.
  6152     previewImageHolder := nil asValue.
  6153 
  6153 
       
  6154     "/
       
  6155     "/ compute the averageColor in the background (while building dialog and asking user)
       
  6156     "/
  6154     readySema := Semaphore new.
  6157     readySema := Semaphore new.
  6155     [
  6158     [
  6156         |image|
  6159         |image|
  6157 
  6160 
  6158         image := imageEditView image.
  6161         image := imageEditView image.
  6159         originalColormap := image colorMap copy.
  6162         originalColormap := image colorMap copy.
  6160         originalPixels := image bits.
  6163         originalPixels := image bits.
  6161         avgColor := image averageColor.
  6164 
       
  6165         previewImage := self image magnifiedPreservingRatioTo:100@100.
       
  6166 
       
  6167         avgColor := originalAvgColor := previewImage "image" averageColor.
  6162         avgColorHolder value:avgColor.
  6168         avgColorHolder value:avgColor.
  6163 
  6169 
  6164         previewImage := self image magnifiedPreservingRatioTo:100@100.
       
  6165         previewImageHolder value: previewImage.
  6170         previewImageHolder value: previewImage.
  6166         originalPreviewColormap := previewImage colorMap copy.
  6171         originalPreviewColormap := previewImage colorMap copy.
  6167         originalPreviewPixels := previewImage bits.
  6172         originalPreviewPixels := previewImage bits.
  6168 
  6173 
  6169         readySema signal.
  6174         readySema signal.
  6175     anyChange := false.
  6180     anyChange := false.
  6176 
  6181 
  6177     shiftedColor := [:clr :hShift :lFactor :sFactor |
  6182     shiftedColor := [:clr :hShift :lFactor :sFactor |
  6178                         Color 
  6183                         Color 
  6179                                 hue:((clr hue) ? 0 + hShift) 
  6184                                 hue:((clr hue) ? 0 + hShift) 
  6180                                 light:((clr light * lFactor / 100) min:100)
  6185                                 light:((clr light * (lFactor/100)) min:100)
  6181                                 saturation:((clr saturation * sFactor / 100) min:100)].
  6186                                 saturation:((clr saturation * (sFactor/100)) min:100)].
  6182 
  6187 
  6183     shiftAction := 
  6188     shiftAction := 
  6184         [
  6189         [
  6185             |hShift lFactor sFactor|
  6190             |hShift lFactor sFactor|
  6186 
  6191 
  6195 
  6200 
  6196             hShift := hueShift value.
  6201             hShift := hueShift value.
  6197             lFactor := lightValue value.
  6202             lFactor := lightValue value.
  6198             sFactor := saturationValue value.
  6203             sFactor := saturationValue value.
  6199 
  6204 
  6200             avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor).
  6205             avgColorHolder value:(shiftedColor value:originalAvgColor value:hShift value:lFactor value:sFactor).
  6201 
  6206 
  6202             previewImage
  6207             previewImage
  6203                 colorMap:originalPreviewColormap copy;
  6208                 colorMap:originalPreviewColormap copy;
  6204                 bits:originalPreviewPixels copy;
  6209                 bits:originalPreviewPixels copy;
  6205                 release;
  6210                 release;
  6253 
  6258 
  6254     anyChange ifTrue:[
  6259     anyChange ifTrue:[
  6255         self updateImage.
  6260         self updateImage.
  6256         self updateImagePreView.
  6261         self updateImagePreView.
  6257     ].
  6262     ].
       
  6263 
       
  6264     "Modified: / 28-08-2017 / 13:05:35 / cg"
  6258 !
  6265 !
  6259 
  6266 
  6260 changeHLSOfColors:colorsToShift
  6267 changeHLSOfColors:colorsToShift
  6261     "interactive Hue/Light/Saturation editing"
  6268     "interactive Hue/Light/Saturation editing"
  6262 
  6269 
  6263     |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel 
  6270     |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel 
  6264      shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema
  6271      shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema
  6265      originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels
  6272      originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels
  6266      anyChange |
  6273      anyChange |
  6267 
  6274 
  6268     "/ compute the averageColor in the background (while asking user)
       
  6269     avgColorHolder := nil asValue.
  6275     avgColorHolder := nil asValue.
  6270     previewImageHolder := nil asValue.
  6276     previewImageHolder := nil asValue.
  6271 
  6277 
       
  6278     "/
       
  6279     "/ compute the averageColor in the background (while building dialog and asking user)
       
  6280     "/
  6272     readySema := Semaphore new.
  6281     readySema := Semaphore new.
  6273     [
  6282     [
  6274         |image red green blue|
  6283         |image red green blue|
  6275 
  6284 
  6276         image := imageEditView image.
  6285         image := imageEditView image.
  6296     anyChange := false.
  6305     anyChange := false.
  6297 
  6306 
  6298     shiftedColor := [:clr :hShift :lFactor :sFactor |
  6307     shiftedColor := [:clr :hShift :lFactor :sFactor |
  6299                         Color 
  6308                         Color 
  6300                                 hue:((clr hue) ? 0 + hShift) 
  6309                                 hue:((clr hue) ? 0 + hShift) 
  6301                                 light:((clr light * lFactor / 100) min:100)
  6310                                 light:((clr light * lFactor) min:100)
  6302                                 saturation:((clr saturation * sFactor / 100) min:100)].
  6311                                 saturation:((clr saturation * sFactor) min:100)].
  6303 
  6312 
  6304     shiftAction := 
  6313     shiftAction := 
  6305         [
  6314         [
  6306             |hShift lFactor sFactor|
  6315             |hShift lFactor sFactor|
  6307 
  6316 
  6387 
  6396 
  6388     anyChange ifTrue:[
  6397     anyChange ifTrue:[
  6389         self updateImage.
  6398         self updateImage.
  6390         self updateImagePreView.
  6399         self updateImagePreView.
  6391     ].
  6400     ].
       
  6401 
       
  6402     "Modified (comment): / 28-08-2017 / 13:04:44 / cg"
  6392 !
  6403 !
  6393 
  6404 
  6394 clearColormapEntry0AndMaskedPixels
  6405 clearColormapEntry0AndMaskedPixels
  6395     "ensure that there is a colorMap entry with 0/0/0 at position
  6406     "ensure that there is a colorMap entry with 0/0/0 at position
  6396      0 and then clear all masked pixels (to pixelValue 0).
  6407      0 and then clear all masked pixels (to pixelValue 0).