ImageEditor.st
changeset 1008 327f93d57c7b
parent 996 9423ae277168
child 1033 21b3bc025e0c
equal deleted inserted replaced
1007:98f4db3e2d23 1008:327f93d57c7b
  1121                        #(#MenuItem
  1121                        #(#MenuItem
  1122                           #label: 'Compress colormap'
  1122                           #label: 'Compress colormap'
  1123                           #translateLabel: true
  1123                           #translateLabel: true
  1124                           #value: #compressColorMap
  1124                           #value: #compressColorMap
  1125                           #activeHelpKey: #compressColormap
  1125                           #activeHelpKey: #compressColormap
       
  1126                           #enabled: #hasColormap
       
  1127                       )
       
  1128                        #(#MenuItem
       
  1129                           #label: 'Sort colormap'
       
  1130                           #translateLabel: true
       
  1131                           #value: #sortColorMap
       
  1132                           #enabled: #hasColormap
  1126                       )
  1133                       )
  1127                     ) nil
  1134                     ) nil
  1128                     nil
  1135                     nil
  1129                 )
  1136                 )
  1130             )
  1137             )
  1168             )
  1175             )
  1169           ) nil
  1176           ) nil
  1170           nil
  1177           nil
  1171       )
  1178       )
  1172 
  1179 
  1173     "Modified: / 7.9.1998 / 18:21:27 / cg"
  1180     "Modified: / 30.9.1998 / 23:53:12 / cg"
  1174 !
  1181 !
  1175 
  1182 
  1176 menuMouseButtonColors
  1183 menuMouseButtonColors
  1177     "This resource specification was automatically generated
  1184     "This resource specification was automatically generated
  1178      by the MenuEditor of ST/X."
  1185      by the MenuEditor of ST/X."
  1389     ^ [(Smalltalk at:(imageEditView resourceClass) ifAbsent:nil) notNil]
  1396     ^ [(Smalltalk at:(imageEditView resourceClass) ifAbsent:nil) notNil]
  1390 
  1397 
  1391     "Created: / 31.7.1998 / 02:02:22 / cg"
  1398     "Created: / 31.7.1998 / 02:02:22 / cg"
  1392 !
  1399 !
  1393 
  1400 
       
  1401 hasColormap
       
  1402     ^ [self image notNil and:[self image colorMap notNil]]
       
  1403 
       
  1404     "Created: / 30.9.1998 / 23:53:55 / cg"
       
  1405 !
       
  1406 
  1394 imageInfoHolder
  1407 imageInfoHolder
  1395     |holder|
  1408     |holder|
  1396     (holder := builder bindingAt:#imageInfoHolder) isNil ifTrue:[
  1409     (holder := builder bindingAt:#imageInfoHolder) isNil ifTrue:[
  1397         builder aspectAt:#imageInfoHolder put:(holder :=  '' asValue).
  1410         builder aspectAt:#imageInfoHolder put:(holder :=  '' asValue).
  1398     ].
  1411     ].
  1872 colorMapMode:aMode
  1885 colorMapMode:aMode
  1873     "calculates a new color map for the image from aMode"
  1886     "calculates a new color map for the image from aMode"
  1874 
  1887 
  1875     |depth numColors newColorMap newImage 
  1888     |depth numColors newColorMap newImage 
  1876      oldImage image newColors realColorMap oldFileName
  1889      oldImage image newColors realColorMap oldFileName
  1877      usedColors useNearest usageCounts tmpBits tmpMap quest| 
  1890      usedColors useNearest usageCounts tmpBits tmpMap quest
       
  1891      prevMode maskThreshold maskImage| 
  1878 
  1892 
  1879     self withExecuteCursorDo:[
  1893     self withExecuteCursorDo:[
  1880         oldImage := self image.
  1894         oldImage := self image.
       
  1895 
       
  1896         prevMode := colorMapMode.
       
  1897         oldImage depth > 8 ifTrue:[
       
  1898             prevMode := nil
       
  1899         ].
  1881 
  1900 
  1882         newColorMap := self class listOfColorMaps at:aMode.
  1901         newColorMap := self class listOfColorMaps at:aMode.
  1883         depth       := (newColorMap size log: 2) asInteger. 
  1902         depth       := (newColorMap size log: 2) asInteger. 
  1884 
  1903 
  1885         useNearest := false.
  1904         useNearest := false.
  1886         depth == 1 ifTrue:[
  1905         depth == 1 ifTrue:[
  1887             quest := 'Keep colormap (or use standard B&W)'
  1906             quest := 'Keep colormap (or use standard B&W)'
  1888         ] ifFalse:[
  1907         ] ifFalse:[
  1889             quest := 'Keep colormap (or use standard)'
  1908             prevMode isNil ifTrue:[
       
  1909                 quest := 'Compute colormap (or use standard)'
       
  1910             ] ifFalse:[
       
  1911                 quest := 'Keep colormap (or use standard)'
       
  1912             ]
  1890         ].
  1913         ].
  1891         ((colorMapMode value = aMode)
  1914         ((prevMode = aMode)
  1892         or:[self confirm:(resources string:quest)]) ifTrue:[
  1915         or:[self confirm:(resources string:quest)]) ifTrue:[
       
  1916 
  1893             "/ keep the colormap
  1917             "/ keep the colormap
       
  1918             newColorMap atAllPut:Color black.
  1894             depth > oldImage depth ifTrue:[
  1919             depth > oldImage depth ifTrue:[
  1895                 "/ easy - simply copy the part
  1920                 "/ easy - simply copy the part
  1896                 numColors := 1 bitShift:oldImage depth.
  1921                 numColors := 1 bitShift:oldImage depth.
  1897                 0 to:numColors-1 do:[:pixel |
  1922                 0 to:numColors-1 do:[:pixel |
  1898                     newColorMap at:(pixel+1) put:(oldImage colorFromValue:pixel)
  1923                     newColorMap at:(pixel+1) put:(oldImage colorFromValue:pixel)
  1902                 usedColors := oldImage usedColorsMax:(1 bitShift:depth).
  1927                 usedColors := oldImage usedColorsMax:(1 bitShift:depth).
  1903                 (usedColors notNil and:[usedColors size <= (1 bitShift:depth)]) ifTrue:[
  1928                 (usedColors notNil and:[usedColors size <= (1 bitShift:depth)]) ifTrue:[
  1904                     "/ yea - just install them
  1929                     "/ yea - just install them
  1905                     usedColors asArray keysAndValuesDo:[:idx :clr |
  1930                     usedColors asArray keysAndValuesDo:[:idx :clr |
  1906                         newColorMap at:idx put:clr
  1931                         newColorMap at:idx put:clr
  1907                     ]
  1932                     ].
  1908                 ] ifFalse:[
  1933                 ] ifFalse:[
  1909                     "/ copy over those that are most often used.
  1934                     "/ copy over those that are most often used.
  1910                     oldImage depth < 8 ifTrue:[
  1935                     oldImage depth < 8 ifTrue:[
  1911                         tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height).
  1936                         tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height).
  1912                         oldImage bits
  1937                         oldImage bits
  1963         imageEditView makeUndo.
  1988         imageEditView makeUndo.
  1964 
  1989 
  1965         newImage    := (Image implementorForDepth: depth) new.  
  1990         newImage    := (Image implementorForDepth: depth) new.  
  1966         oldFileName := oldImage fileName.
  1991         oldFileName := oldImage fileName.
  1967 
  1992 
  1968         Object errorSignal handle:
  1993         Image imageErrorSignal handle:[:ex|
  1969         [:ex|
  1994             Color colorErrorSignal handle:[:ex|
  1970             Object errorSignal handle:
       
  1971             [:ex|
       
  1972                 imageEditView undo.
  1995                 imageEditView undo.
  1973                 ^self warn:(resources string:'Conversion failed !!')
  1996                 ^ self warn:(resources string:'Conversion failed !!')
  1974             ]
  1997             ] do:[
  1975             do:
       
  1976             [
       
  1977                 newImage := (Image implementorForDepth: depth) new.
  1998                 newImage := (Image implementorForDepth: depth) new.
  1978                 newImage width:oldImage width height:oldImage height depth:depth.
  1999                 newImage width:oldImage width height:oldImage height depth:depth.
  1979                 newImage colorMap:newColorMap.
  2000                 newImage colorMap:newColorMap.
  1980                 newImage photometric:#palette.
  2001                 newImage photometric:#palette.
  1981                 newImage bits:(ByteArray new:(newImage bytesPerRow * newImage height)).
  2002                 newImage bits:(ByteArray new:(newImage bytesPerRow * newImage height)).
  1985                     |newColor|
  2006                     |newColor|
  1986 
  2007 
  1987                     (newColorMap includes:clr)
  2008                     (newColorMap includes:clr)
  1988                         ifTrue: [newColor := clr]
  2009                         ifTrue: [newColor := clr]
  1989                         ifFalse: [
  2010                         ifFalse: [
  1990                             useNearest ifTrue:[
  2011                             newColor := clr nearestIn:newColorMap.
  1991                                 newColor := clr nearestIn:newColorMap
  2012                             useNearest ifFalse:[
  1992                             ] ifFalse:[
  2013                                 (newColor deltaFrom:clr) > 0.5 ifTrue:[
  1993                                 newColor := oldImage colorMap first
  2014                                     newColor := oldImage colorFromValue:0
       
  2015                                 ]
  1994                             ]
  2016                             ]
  1995                         ].
  2017                         ].
  1996                     newImage colorAtX:x y:y put:newColor.
  2018                     newImage colorAtX:x y:y put:newColor.
  1997                 ].
  2019                 ].
  1998                 image := newImage
  2020                 image := newImage
  1999             ].
  2021             ].
  2000         ] 
  2022         ] do:[ 
  2001         do:
  2023             image := newImage fromImage:oldImage
  2002         [ 
       
  2003             image := newImage fromImage: oldImage
       
  2004         ].
  2024         ].
  2005 
  2025 
  2006         (aMode asString endsWith:'mask')
  2026         (aMode asString endsWith:'mask') ifTrue:[
  2007         ifTrue:
  2027             image mask isNil ifTrue:[
  2008         [
  2028                 (self confirm:'Generate mask from black ?') ifTrue:[
  2009             image mask isNil
  2029                     maskThreshold := 0.1.
  2010             ifTrue:
  2030                     maskImage := Depth1Image fromImage:(image asThresholdMonochromeImage:maskThreshold). 
  2011             [
  2031                 ] ifFalse:[
  2012                 image mask: (Depth1Image fromImage: (image asThresholdMonochromeImage: 0.1)). 
  2032                     maskImage := Depth1Image extent:image extent.
       
  2033                     maskImage data:(ByteArray 
       
  2034                                         new:(maskImage bytesPerRow * maskImage height)
       
  2035                                         withAll:16rFF).
       
  2036 
       
  2037 "/                    maskImage fillRectangle:(image bounds) withColor:(Color colorId:1).
       
  2038                 ].
       
  2039                 image mask:maskImage.
  2013             ].
  2040             ].
  2014         ]
  2041         ] ifFalse:[ 
  2015         ifFalse:
       
  2016         [ 
       
  2017             image mask: nil.
  2042             image mask: nil.
  2018         ]. 
  2043         ]. 
  2019         realColorMap := OrderedCollection new.
  2044         realColorMap := OrderedCollection new.
  2020         image realColorMap do:
  2045         image realColorMap do:
  2021         [:clr|
  2046         [:clr|
  2039             self findColorMapMode.
  2064             self findColorMapMode.
  2040             self updateLabelsAndHistory.
  2065             self updateLabelsAndHistory.
  2041         ]
  2066         ]
  2042     ]
  2067     ]
  2043 
  2068 
  2044     "Modified: / 7.9.1998 / 17:57:55 / cg"
  2069     "Modified: / 30.9.1998 / 23:44:19 / cg"
  2045 !
  2070 !
  2046 
  2071 
  2047 compressColorMap
  2072 compressColorMap
  2048     "calculates a new color map for the image, using only used colors"
  2073     "calculates a new color map for the image, using only used colors"
  2049 
  2074 
  2142         ]
  2167         ]
  2143     ]
  2168     ]
  2144 
  2169 
  2145     "Created: / 28.7.1998 / 20:03:11 / cg"
  2170     "Created: / 28.7.1998 / 20:03:11 / cg"
  2146     "Modified: / 15.9.1998 / 17:53:32 / cg"
  2171     "Modified: / 15.9.1998 / 17:53:32 / cg"
       
  2172 !
       
  2173 
       
  2174 sortColorMap
       
  2175     "calculates a new color map for the image, sorting colors"
       
  2176 
       
  2177     |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits| 
       
  2178 
       
  2179     oldImage := self image.
       
  2180     depth := oldImage depth.
       
  2181 
       
  2182     oldImage photometric ~~ #palette ifTrue:[
       
  2183         self information:'Compress colorMap: Only palette images have colormaps.'.
       
  2184         ^ self
       
  2185     ].
       
  2186 
       
  2187     usedColors := oldImage realColorMap.
       
  2188 
       
  2189     imageEditView makeUndo.
       
  2190 
       
  2191     self withExecuteCursorDo:[
       
  2192 "/        newColorMap := Array new:usedColors size.
       
  2193 
       
  2194         "/ translation table
       
  2195         oldToNew := ByteArray new:(1 bitShift:depth).
       
  2196         newColorMap := usedColors asArray.
       
  2197         newColorMap sort:[:a :b |
       
  2198                                 a redByte == b redByte ifTrue:[
       
  2199                                     a greenByte == b greenByte ifTrue:[
       
  2200                                         a blueByte < b blueByte
       
  2201                                     ] ifFalse:[
       
  2202                                         a greenByte < b greenByte 
       
  2203                                     ]
       
  2204                                 ] ifFalse:[
       
  2205                                     a redByte < b redByte 
       
  2206                                 ]
       
  2207                           ].
       
  2208 
       
  2209         oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr |
       
  2210             |newPixel|
       
  2211 
       
  2212             (usedColors includes:clr) ifTrue:[
       
  2213                 newPixel := newColorMap indexOf:clr.
       
  2214                 oldToNew at:oldIdx put:newPixel-1.
       
  2215             ]
       
  2216         ].
       
  2217 
       
  2218         oldBits := oldImage bits.
       
  2219         newBits := ByteArray new:(oldBits size).
       
  2220         depth ~~ 8 ifTrue:[
       
  2221             "/ expand/compress can only handle 8bits
       
  2222             tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height).
       
  2223             oldBits
       
  2224                 expandPixels:depth
       
  2225                 width:oldImage width
       
  2226                 height:oldImage height 
       
  2227                 into:tmpBits
       
  2228                 mapping:oldToNew.
       
  2229             tmpBits
       
  2230                 compressPixels:depth 
       
  2231                 width:oldImage width 
       
  2232                 height:oldImage height 
       
  2233                 into:newBits 
       
  2234                 mapping:nil
       
  2235         ] ifFalse:[
       
  2236             oldBits
       
  2237                 expandPixels:depth
       
  2238                 width:oldImage width
       
  2239                 height:oldImage height 
       
  2240                 into:newBits
       
  2241                 mapping:oldToNew.
       
  2242         ].
       
  2243 
       
  2244         newImage := oldImage species new
       
  2245                         width:oldImage width
       
  2246                         height:oldImage height
       
  2247                         depth:depth
       
  2248                         fromArray:newBits.
       
  2249 
       
  2250         newImage colorMap:newColorMap.  
       
  2251         newImage fileName:oldImage fileName.
       
  2252         newImage mask:(oldImage mask copy).
       
  2253 
       
  2254         (imageEditView image:newImage) notNil ifTrue:
       
  2255         [
       
  2256             self listOfColors contents: newImage colorMap.
       
  2257             self findColorMapMode.
       
  2258             self updateLabelsAndHistory.
       
  2259         ]
       
  2260     ]
       
  2261 
       
  2262     "Modified: / 15.9.1998 / 17:53:32 / cg"
       
  2263     "Created: / 30.9.1998 / 23:51:23 / cg"
  2147 ! !
  2264 ! !
  2148 
  2265 
  2149 !ImageEditor methodsFor:'user actions - editing'!
  2266 !ImageEditor methodsFor:'user actions - editing'!
  2150 
  2267 
  2151 doBrowseClass
  2268 doBrowseClass