Image.st
changeset 191 a81db32ff94b
parent 178 54b7347f495f
child 193 3abcc2ee1641
--- a/Image.st	Tue Sep 19 16:59:18 1995 +0200
+++ b/Image.st	Thu Sep 21 13:39:49 1995 +0200
@@ -29,7 +29,7 @@
 COPYRIGHT (c) 1991 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/Image.st,v 1.40 1995-08-31 03:20:03 claus Exp $
+$Header: /cvs/stx/stx/libview/Image.st,v 1.41 1995-09-21 11:39:49 claus Exp $
 '!
 
 !Image class methodsFor:'documentation'!
@@ -50,7 +50,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libview/Image.st,v 1.40 1995-08-31 03:20:03 claus Exp $
+$Header: /cvs/stx/stx/libview/Image.st,v 1.41 1995-09-21 11:39:49 claus Exp $
 "
 !
 
@@ -467,6 +467,23 @@
     "
 !
 
+fromSubImage:anImage in:aRectangle
+    "create & return an Image from a rectangular area in another image. 
+     This can also be used to get a subimage in another depth."
+
+    ^ self new fromSubImage:anImage in:aRectangle.
+
+    "
+     |i1 i8|
+
+     i1 := Image fromFile:'bitmaps/garfield.gif'.
+     i8 := Depth8Image fromSubImage:i1 in:(0@0 corner:20@20).
+     i8 inspect
+    "
+
+    "Created: 20.9.1995 / 01:05:43 / claus"
+!
+
 width:w height:h
     "create a new image, given width, height. Assume a depth of 1."
 
@@ -482,7 +499,8 @@
 width:w height:h depth:d
     "create a new image, given width, height and depth"
 
-    ^ (self implementorForDepth:d) width:w height:h depth:d
+    ^ (self implementorForDepth:d) new
+	width:w height:h depth:d
 !
 
 width:w height:h fromArray:anArray
@@ -633,6 +651,71 @@
     device := deviceForm := monoDeviceForm := fullColorDeviceForm := nil
 ! !
 
+!Image methodsFor:'pixel copying'!
+
+subImageIn:aRectangle
+    "create and return a new image consisting of a subArea of myself"
+
+    ^ self class fromSubImage:self in:aRectangle
+
+    "
+     |i|
+
+     i := Image fromFile:'bitmaps/garfield.gif'.
+     i inspect.
+     (i subImageIn:(300@160 corner:340@200)) inspect
+    "
+
+    "Created: 20.9.1995 / 01:24:20 / claus"
+!
+
+copyFrom:anImage x:srcX y:srcY toX:dstX y:dstY width:w height:h
+    "replace a rectangulat area by pixels from another image.
+     WARNING:
+     This implementation is a slow fallback (the loop over the
+     source pixels is very slow). If this method is used heavily, you
+     may want to redefine it in concrete subclasses for the common case of
+     of copying from an Image with the same depth & palette."
+
+    |dX dY|
+
+    dX := srcX-dstX.
+    dY := srcY-dstY.
+    ((photometric == anImage photometric)
+     and:[self bitsPerPixel == anImage bitsPerPixel
+     and:[colorMap = anImage colorMap]]) ifTrue:[
+	"/ can loop over values
+	anImage valuesFromX:srcX  y:srcY 
+			toX:srcX+w-1 y:srcY+h-1  
+			 do:[:x :y :pixelValue |
+	    self atX:x-dX y:y-dY putValue:pixelValue.
+	]
+    ] ifFalse:[
+	"/ must loop over colors
+	anImage colorsFromX:srcX  y:srcY 
+			toX:srcX+w-1 y:srcY+h-1  
+			 do:[:x :y :clr |
+	    self atX:x-dX y:y-dY put:clr.
+	]
+    ]
+
+    "
+     |i1 i8 i4|
+
+     i8 := Image fromFile:'bitmaps/garfield.gif'.
+     i8 inspect.
+     i1 := Image fromFile:'bitmaps/SBrowser.xbm'.
+     i1 inspect.
+
+     i4 := Depth4Image fromImage:i8.
+     i4 copyFrom:i1 x:0 y:0 toX:20 y:20 width:30 height:30.
+     i4 inspect.
+    "
+
+    "Created: 20.9.1995 / 10:14:01 / claus"
+    "Modified: 20.9.1995 / 10:25:31 / claus"
+! !
+
 !Image methodsFor:'instance release'!
 
 release
@@ -1536,7 +1619,9 @@
 fromImage:anImage
     "setup the receiver from another image.
      Color precision may be lost, if conversion is from a higher depth
-     image. This implementation is a slow fallback (the loop over the
+     image. 
+     WARNING:
+     This implementation is a slow fallback (the loop over the
      source pixels is very slow). If this method is used heavily, you
      may want to redefine it in concrete subclasses for common source images."
 
@@ -1545,29 +1630,7 @@
     bytes := ByteArray uninitializedNew:(self bytesPerRow * height).
     bitsPerSample := self bitsPerSample.
     samplesPerPixel := self samplesPerPixel.
-    samplesPerPixel == 3 ifTrue:[
-	photometric := #rgb
-    ] ifFalse:[
-	photometric := anImage photometric.
-	photometric == #palette ifTrue:[
-	    colorMap := anImage colorMap copy.
-	    "
-	     must compress the colormap, if source image has higher depth
-	     than myself. 
-	    "
-	    anImage bitsPerPixel > self bitsPerPixel ifTrue:[
-		"
-		 get used colors are extracted into our colorMap
-		 (the at-put below will set the pixelValue according the
-		 new colorIndex
-		"
-		colorMap := anImage usedColors asArray.
-		colorMap size > (1 bitShift:self bitsPerPixel) ifTrue:[
-		    'IMAGE: possibly too many colors in image' errorPrintNL
-		]
-	    ]
-	]
-    ].
+    self colormapFromImage:anImage.
     anImage colorsFromX:0 y:0 toX:(width-1) y:(height-1) do:[:x :y :clr |
 	self atX:x y:y put:clr
     ].
@@ -1586,6 +1649,63 @@
      i24 := Depth24Image fromImage:i.
      i24 inspect.
     "
+
+    "Created: 20.9.1995 / 00:59:03 / claus"
+!
+
+fromSubImage:anImage in:aRectangle
+    "setup the receiver from another image, extracting a rectangular
+     area. Color precision may be lost, if conversion is from a higher depth
+     image. 
+     WARNING:
+     This implementation is a slow fallback (the loop over the
+     source pixels is very slow). If this method is used heavily, you
+     may want to redefine it in concrete subclasses for the common case of
+     of creating a subImage with the same depth & palette."
+
+    |x0 y0|
+
+    width := aRectangle width + 1.
+    height := aRectangle height + 1.
+    bytes := ByteArray uninitializedNew:(self bytesPerRow * height).
+    bitsPerSample := self bitsPerSample.
+    samplesPerPixel := self samplesPerPixel.
+    self colormapFromImage:anImage.
+    x0 := aRectangle left.
+    y0 := aRectangle top.
+    ((photometric == anImage photometric)
+    and:[self bitsPerPixel == anImage bitsPerPixel
+    and:[colorMap = anImage colorMap]]) ifTrue:[
+	"/ can do it by value
+	anImage valuesFromX:x0  y:y0 
+			toX:aRectangle right y:aRectangle bottom 
+			 do:[:x :y :pixelValue |
+	    self atX:x-x0 y:y-y0 putValue:pixelValue.
+	]
+    ] ifFalse:[
+	"/ must do it by colors
+	anImage colorsFromX:x0  y:y0 
+			toX:aRectangle right y:aRectangle bottom 
+			 do:[:x :y :clr |
+	    self atX:x-x0 y:y-y0 put:clr.
+	]
+    ].
+
+    "
+     |i i2 i4 i8 i24|
+
+     i := Image fromFile:'bitmaps/garfield.gif'.
+     i inspect.
+     i4 := Depth4Image fromSubImage:i in:(300@160 corner:340@200).
+     i4 inspect.
+     i8 := Depth8Image fromSubImage:i in:(300@160 corner:340@200).
+     i8 inspect.
+     i24 := Depth24Image fromSubImage:i in:(300@160 corner:340@200).
+     i24 inspect.
+    "
+
+    "Created: 20.9.1995 / 01:06:02 / claus"
+    "Modified: 20.9.1995 / 10:15:37 / claus"
 !
 
 fromForm:aForm
@@ -2540,6 +2660,39 @@
 
 !Image methodsFor:'private'!
 
+colormapFromImage:anImage
+    "setup the receivers colormap from another image.
+     Color precision may be lost, if conversion is from a higher depth
+     image. This does not convert any pixel values; it is  non-public helper
+     for fromImage:/fromSubImake:"
+
+    samplesPerPixel == 3 ifTrue:[
+	photometric := #rgb
+    ] ifFalse:[
+	photometric := anImage photometric.
+	photometric == #palette ifTrue:[
+	    colorMap := anImage colorMap copy.
+	    "
+	     must compress the colormap, if source image has higher depth
+	     than myself. 
+	    "
+	    anImage bitsPerPixel > self bitsPerPixel ifTrue:[
+		"
+		 get used colors are extracted into our colorMap
+		 (the at-put below will set the pixelValue according the
+		 new colorIndex
+		"
+		colorMap := anImage usedColors asArray.
+		colorMap size > (1 bitShift:self bitsPerPixel) ifTrue:[
+		    'IMAGE: possibly too many colors in image' errorPrintNL
+		]
+	    ]
+	]
+    ].
+
+    "Created: 20.9.1995 / 00:58:42 / claus"
+!
+
 magnifyRowFrom:srcBytes offset:srcStart pixels:oldPixels 
 	  into:dstBytes offset:dstStart factor:mX