#FEATURE by cg
class: ImageEditView
class definition
comment/format in:
#drawingColors
#drawingColors:
#selectedColor
#selectedColor:
changed:
#askForSpecialOperation
#drawingColorHolders
#gradientFillIn:orientation:auto:
#initialize
#makeUndo
#undo
--- a/ImageEditView.st Thu Feb 23 14:22:56 2017 +0100
+++ b/ImageEditView.st Thu Feb 23 15:55:02 2017 +0100
@@ -15,12 +15,13 @@
ImageView subclass:#ImageEditView
instanceVariableNames:'readOnly magnification imageReaderClass resourceClass
- resourceSelector mouseKeyColorMode undoImages modifiedHolder
- editMode lastPastePoint imageInfoHolder activityInfoHolder
- pickedColorHolder drawingColors drawingPixels drawingColorHolders
- drawingPixelHolders clickInfoCallBack penWidth sprayProcess
- sprayPosition spraySpot drawingAlpha floodFillMaxHueError
- floodFillMaxLightError userAllowedToChangeDrawingColor'
+ resourceSelector mouseKeyColorMode undoImages originalImage
+ modifiedHolder editMode lastPastePoint imageInfoHolder
+ activityInfoHolder pickedColorHolder drawingColors drawingPixels
+ drawingColorHolders drawingPixelHolders clickInfoCallBack
+ penWidth sprayProcess sprayPosition spraySpot drawingAlpha
+ floodFillMaxHueError floodFillMaxLightError
+ userAllowedToChangeDrawingColor'
classVariableNames:'Clipboard ClipboardMagnified LastMagnification
GridMagnificationLimit MaxUndos LastSaveDirectory LastSaveClass
EditModePoint EditModeBox EditModeFilledBox EditModeFill
@@ -206,16 +207,25 @@
!
drawingColorHolders
+ drawingColorHolders isNil ifTrue:[
+ drawingColorHolders := Array with:(nil asValue) with:(nil asValue). "/ left/right mouse colors
+ ].
^ drawingColorHolders
+
+ "Modified: / 23-02-2017 / 10:14:49 / cg"
!
drawingColors
^ drawingColorHolders collect:[:each | each value].
+
+ "Modified: / 23-02-2017 / 10:17:14 / cg"
!
drawingColors:anArrayTwoColors
(drawingColorHolders at:1) value:(anArrayTwoColors at:1).
(drawingColorHolders at:2) value:(anArrayTwoColors at:2).
+
+ "Modified: / 23-02-2017 / 10:17:21 / cg"
!
editMode
@@ -449,11 +459,13 @@
].
^ clr
- "Modified: / 20-09-2010 / 11:34:07 / cg"
+ "Modified: / 23-02-2017 / 10:17:06 / cg"
!
selectedColor: aColor
(drawingColorHolders at:(mouseKeyColorMode min:drawingColorHolders size)) value:aColor
+
+ "Modified: / 23-02-2017 / 10:17:02 / cg"
!
selectedColorIndex
@@ -1032,11 +1044,13 @@
('-' nil nil)
('gradient fill horizontal' fillHorizontalGradientRectIcon gradientFillHorizontal)
('gradient fill vertical' fillVerticalGradientRectIcon gradientFillVertical)
- ('gradient fill diagonal' fillDiagonalGradientRectIcon gradientFillDiagonal)
+ "/ unfinished
+ "/ ('gradient fill diagonal' fillDiagonalGradientRectIcon gradientFillDiagonal)
('-' nil nil)
('auto gradient fill horizontal' fillHorizontalGradientRectIcon autoGradientFillHorizontal)
('auto gradient fill vertical' fillVerticalGradientRectIcon autoGradientFillVertical)
- ('auto gradient fill diagonal' fillDiagonalGradientRectIcon autoGradientFillDiagonal)
+ "/ unfinished
+ "/ ('auto gradient fill diagonal' fillDiagonalGradientRectIcon autoGradientFillDiagonal)
).
].
@@ -1064,7 +1078,7 @@
^ operation
"Created: / 20-02-2017 / 17:37:23 / cg"
- "Modified: / 22-02-2017 / 21:02:02 / cg"
+ "Modified: / 23-02-2017 / 15:54:42 / cg"
!
autoCropLeft:doLeft right:doRight top:doTop bottom:doBottom
@@ -1341,12 +1355,13 @@
!
gradientFillIn:imageBox orientation:orientation auto:auto
- "/ with auto, pick 2 (or 4 if diagonal) bounding pixels and do a gradient fill with those;
+ "/ with auto, pick 2 bounding pixels and do a gradient fill with those;
+ "/ (don't know what diagonal should do, yet)
"/ if auto is false, use color1/color2 for the fill
|x0 y0 x1 y1 image n color1 color2
- r0 g0 b0 dR dG dB i dist
- cTop cBot xD yD cDiag n1 n2 dd|
+ r0 g0 b0 dR dG dB i cX cY A B qAB a b pD1x pD1y pD2x pD2y
+ dxH dyH hX hY dH dP f |
self makeUndo.
@@ -1354,7 +1369,6 @@
y0 := imageBox top.
x1 := imageBox right-1.
y1 := imageBox bottom-1.
-
image := self image.
self setModified.
@@ -1408,9 +1422,9 @@
^ self.
].
- color1 := (drawingColorHolders at:1) value.
+ color1 := (self drawingColorHolders at:1) value.
color1 isNil ifTrue:[ color1 := Color black ].
- color2 := (drawingColorHolders at:2) value.
+ color2 := (self drawingColorHolders at:2) value.
color2 isNil ifTrue:[ color2 := Color white ].
r0 := color1 red.
@@ -1421,9 +1435,9 @@
n := y1-y0.
n = 0 ifTrue:[^ self].
- dR := (color2 red - color1 red) / n.
- dG := (color2 green - color1 green) / n.
- dB := (color2 blue - color1 blue) / n.
+ dR := (color2 red - r0) / n.
+ dG := (color2 green - g0) / n.
+ dB := (color2 blue - b0) / n.
x0 to:x1 do:[:x |
i := 0.
@@ -1440,9 +1454,9 @@
n := x1-x0.
n = 0 ifTrue:[^ self ].
- dR := (color2 red - color1 red) / n.
- dG := (color2 green - color1 green) / n.
- dB := (color2 blue - color1 blue) / n.
+ dR := (color2 red - r0) / n.
+ dG := (color2 green - g0) / n.
+ dB := (color2 blue - b0) / n.
y0 to:y1 do:[:y |
i := 1.
@@ -1457,50 +1471,164 @@
].
orientation == #diagonal ifTrue:[
- dist := ((x1 - x0) squared + (y1 - y0) squared) sqrt.
- dR := (color2 red - color1 red) / dist.
- dG := (color2 green - color1 green) / dist.
- dB := (color2 blue - color1 blue) / dist.
+ cX := (x1+1 + x0) / 2.
+ cY := (y1+1 + y0) / 2.
+ A := cY-y0.
+ B := cX-x0.
+ (A=0 or:[B=0]) ifTrue:[^ self].
+
+ qAB := A/B.
- x0 to:x1 do:[:x |
- cTop := image colorAtX:x y:y0.
- cBot := image colorAtX:x y:y1.
- "/ point on diagonal
- xD := x.
- yD := (y1-y0)/(x1-x0)*x.
- "/ color at point on diagonal
- cDiag := image colorAtX:xD rounded y:yD rounded.
- dd := ((x-x0) squared + (yD-y0) squared) sqrt.
- cDiag := Color red:(color1 red + (dd*dR)) green:(color1 green + (dd*dG)) blue:(color1 blue + (dd*dB)).
-
- n1 := yD-y0+1. "/ num points between top at x and diagonalPoint at x
- n2 := y1-yD+1. "/ num points between diagonalPoint at x and bottom at x and
- y0 to:y1 do:[:y |
- |clr d dR2 dG2 dB2|
-
- y < yD ifTrue:[
- "/ gradient from top-color at x to diagonal point at x
- d := y-y0.
- dR2 := (cDiag red - cTop red) / n1.
- dG2 := (cDiag green - cTop green) / n1.
- dB2 := (cDiag blue - cTop blue) / n1.
- clr := Color red:(cTop red + (d*dR2)) green:(cTop green + (d*dG2)) blue:(cTop blue + (d*dB2)).
+ "/ {(cX-10) rounded . (cX-5) rounded . cX rounded . (cX+5)rounded . (cX+10)rounded }
+ x0 to:x1
+ do:[:x |
+ b := cX-x.
+ b = 0 ifTrue:[
+ pD1x := pD2x := cX.
+ pD1y := pD2y := cY.
+ ] ifFalse:[
+ "/ (A/B) = (a/b) -> a = (A/B)*b
+ a := qAB*b.
+ pD1x := ((cX-b) max:x0) min:x1.
+ pD1y := ((cY+a) max:y0) min:y1.
+ pD2x := ((cX-b) max:x0) min:x1.
+ pD2y := ((cY-a) max:y0) min:y1.
+ ].
+ "/ {(cY-10)rounded . (cY-5)rounded . cY rounded. (cY+5)rounded. (cY+10)rounded }
+ y0 to:y1
+ do:[:y |
+ "/ the edge-point to interpolate against...
+ "/ take a line from C through x/y and compute where it hits the edge H
+ a := y-cY.
+ b := x-cX.
+ (a = 0) ifTrue:[
+ "/ exactly in the middle
+ hX := (x < cX) ifTrue:[x0] ifFalse:[x1].
+ hY := cY.
] ifFalse:[
- "/ gradient from diagonal point at x to bottom point at x
- d := y1-y.
- dR2 := (cBot red - cDiag red) / n2.
- dG2 := (cBot green - cDiag green) / n2.
- dB2 := (cBot blue - cDiag blue) / n2.
- clr := Color red:(cDiag red + (d*dR2)) green:(cDiag green + (d*dG2)) blue:(cDiag blue + (d*dB2)).
+ (b = 0) ifTrue:[
+ hX := cX.
+ hY := (y < cY) ifTrue:[y0] ifFalse:[y1].
+ ] ifFalse:[
+ "/ (dH/A) = (b/a) -> dH = (b/a)*A
+ y <= pD1y ifTrue:[
+ "/ in left-upper half
+ (y <= pD2y) ifTrue:[
+ "/ in upper quadrant
+ dxH := (b/a)*A.
+ hX := cX-dxH.
+ hY := y0.
+ ] ifFalse:[
+ "/ in left quadrant
+ dyH := (a/b)*B negated.
+ hY := cY+dyH.
+ hX := x0.
+ ].
+ ] ifFalse:[
+ "/ in right-lower half
+ y >= pD2y ifTrue:[
+ "/ in lower quadrant
+ dxH := (b/a)*A negated.
+ hX := cX-dxH.
+ hY := y1.
+ ] ifFalse:[
+ "/ in right quadrant
+ dyH := (a/b)*B.
+ hY := cY+dyH.
+ hX := x1.
+ ].
+ ].
+ ].
+ hX := hX min:x1.
+ hY := hY min:y1.
].
- image colorAtX:x y:y put:clr.
- ]
+
+ "/ the color at H
+ color2 := image colorAtX:hX rounded y:hY rounded.
+
+ "/ the distance between H and C
+ dH := (hX@hY) dist:(cX@cY).
+ "/ the distance between P and C
+ dP := (x@y) dist:(cX@cY).
+ "/ the fraction (0 at H; 1 at C)
+ f := 1 - (dP / dH).
+ self assert:(f between:0 and:1).
+
+ "/ the new color
+ dR := color2 red + ((r0-color2 red ) * f).
+ dG := color2 green + ((g0-color2 green) * f).
+ dB := color2 blue + ((b0-color2 blue) * f).
+ image colorAtX:x y:y put:(Color red:dR green:dG blue:dB).
+
+"/ y <= pD1y ifTrue:[
+"/ "/ in left-upper half
+"/ (y <= pD2y) ifTrue:[
+"/ "/ in upper quadrant
+"/ image colorAtX:x y:y put:Color red.
+"/ ] ifFalse:[
+"/ "/ in left quadrant
+"/ image colorAtX:x y:y put:Color green.
+"/ ].
+"/ ] ifFalse:[
+"/ "/ in right-lower half
+"/ y >= pD2y ifTrue:[
+"/ "/ in lower quadrant
+"/ image colorAtX:x y:y put:Color blue.
+"/ ] ifFalse:[
+"/ "/ in right quadrant
+"/ image colorAtX:x y:y put:Color yellow.
+"/ ].
+"/
+"/ ].
+ ].
].
+ "/ image colorAtX:cX rounded y:cY rounded put:Color magenta.
+
+"/ clr2 := image colorAtX:p2X y:p2Y.
+"/
+"/ cTop := image colorAtX:x y:y0.
+"/ cBot := image colorAtX:x y:y1.
+"/ "/ point on diagonal
+"/ xD := x.
+"/ yD := (y1-y0)/(x1-x0)*x.
+"/ "/ color at point on diagonal
+"/ "/ cDiag := image colorAtX:xD rounded y:yD rounded.
+"/ "/ the distance of the diagonal point from the origin
+"/ dd := ((x-x0) squared + (yD-y0) squared) sqrt.
+"/ "/ desired color at point on diagonal
+"/ cDiag := Color red:(color1 red + (dd*dR)) green:(color1 green + (dd*dG)) blue:(color1 blue + (dd*dB)).
+"/"/ image colorAtX:xD rounded y:yD rounded put:cDiag.
+"/
+"/ n1 := yD-y0+1. "/ num points between top at x and diagonalPoint at x
+"/ n2 := y1-yD+1. "/ num points between diagonalPoint at x and bottom at x
+"/ y0 to:y1 do:[:y |
+"/ |clr d dR2 dG2 dB2|
+"/
+"/ y < yD ifTrue:[
+"/ "/ gradient from top-color at x to diagonal point at x
+"/ d := y-y0.
+"/ dR2 := (cDiag red - cTop red) / n1.
+"/ dG2 := (cDiag green - cTop green) / n1.
+"/ dB2 := (cDiag blue - cTop blue) / n1.
+"/ clr := Color red:(cTop red + (d*dR2)) green:(cTop green + (d*dG2)) blue:(cTop blue + (d*dB2)).
+"/ image colorAtX:x y:y put:clr.
+"/ ] ifFalse:[
+"/ "/ gradient from diagonal point at x to bottom point at x
+"/ d := y-yD.
+"/ dR2 := (cBot red - cDiag red) / n2.
+"/ dG2 := (cBot green - cDiag green) / n2.
+"/ dB2 := (cBot blue - cDiag blue) / n2.
+"/ clr := Color red:(cDiag red + (d*dR2)) green:(cDiag green + (d*dG2)) blue:(cDiag blue + (d*dB2)).
+"/ "/ clr := image colorAtX:x y:y.
+"/ image colorAtX:x y:y put:clr.
+"/ ].
+"/ ]
+"/ ].
^ self.
].
"Created: / 22-02-2017 / 21:00:01 / cg"
- "Modified: / 22-02-2017 / 23:05:49 / cg"
+ "Modified: / 23-02-2017 / 15:41:23 / cg"
!
magnifyAntiAliasedImageTo:newSize
@@ -1623,14 +1751,18 @@
!
makeUndo
- image notNil ifTrue:[
+ |theCopy|
+
+ image notNil ifTrue:[
[undoImages size >= MaxUndos] whileTrue:[
undoImages removeFirst.
].
- undoImages add:image copy
+ theCopy := image copy.
+ undoImages add:theCopy.
+ originalImage isNil ifTrue:[ originalImage := theCopy ].
]
- "Modified: / 20-11-2007 / 17:26:50 / cg"
+ "Modified: / 23-02-2017 / 15:43:55 / cg"
!
pasteAt: aPoint mode:modeSymbol
@@ -2039,19 +2171,25 @@
!
undo
- undoImages notEmpty ifTrue:[
- windowGroup withExecuteCursorDo:[
- |oldImage newImage|
-
- oldImage := self image.
- newImage := undoImages removeLast.
- self clearModified.
- self image:newImage scroll:(newImage extent ~= oldImage extent) "false".
- "/ self changed:#image.
- ]
+ |newImage|
+
+ undoImages notEmpty ifTrue:[
+ newImage := undoImages removeLast.
+ ] ifFalse:[
+ (Dialog confirm:(resources string:'No more undo images remembered. Back to the initial image?'))
+ ifFalse:[^ self].
+ newImage := originalImage copy
+ ].
+
+ windowGroup withExecuteCursorDo:[
+ |oldImage|
+
+ oldImage := self image.
+ self clearModified.
+ self image:newImage scroll:(newImage extent ~= oldImage extent).
]
- "Modified: / 10.2.2000 / 23:21:24 / cg"
+ "Modified: / 23-02-2017 / 15:47:15 / cg"
! !
!ImageEditView methodsFor:'image editing-editmode button actions'!
@@ -3088,7 +3226,9 @@
modifiedHolder := false asValue.
mouseKeyColorMode := 1.
resourceClass := resourceSelector := nil.
- drawingColorHolders := Array with:(nil asValue) with:(nil asValue). "/ left/right mouse colors
+ drawingColorHolders isNil ifTrue:[
+ drawingColorHolders := Array with:(nil asValue) with:(nil asValue). "/ left/right mouse colors
+ ].
drawingPixelHolders := Array with:(nil asValue) with:(nil asValue). "/ left/right mouse colors
spraySpot := 8.
@@ -3098,7 +3238,7 @@
self editMode:EditModePoint.
- "Modified: / 17-02-2017 / 16:24:04 / cg"
+ "Modified: / 23-02-2017 / 10:17:46 / cg"
! !
!ImageEditView methodsFor:'loading & saving'!