Using video input in Squeak

Bert Freudenberg bert at impara.de
Thu Jul 22 20:35:36 UTC 2004


Well, in this case, why do you allocate a new form at all? Just 
overwrite the values in the one you got! Also, for speed, do not build 
the colorMap inside the loop, but before:

initializeProcess

    | colorMap threshold |
    frame := Form extent: self decoderSize depth: 16.	"must be 16, or 
you need a different colorMap"
    threshold := 0.5. "tweak here"
    colorMap := ColorMap shifts: #(0 0 -5 0)
       masks: #(0 0 2r000001111100000 0)
       colors: ((1 to: 32) collect: [:i | i < (threshold * 32)
          ifTrue: [Color black pixelValueForDepth: 16]
          ifFalse: [Color white pixelValueForDepth: 16]]).
	
    process := [[
	self decoderRequestCapture.
	frameSemaphore wait.
	self decoderCopyLastCapturedFrameInto: frame.
	(BitBlt toForm: frame)
		copyForm: frame to: 0 at 0 rule: Form over colorMap: colorMap.
	] repeat] forkAt: self decoderProcessPriority.

This code is untested, of course, but I doubt you can get much more 
efficient than that ;)

- Bert -

Am 22.07.2004 um 19:09 schrieb Rob Hensley:

> OK, I'm almost there! The version I'm working with now (including 
> you're wonderful suggestions!) displays exactly ONE frame of the B/W 
> image (Woo Hoo!) but then blows up. This is the code:
>
> initializeProcess
>
>    | colorMap bwFrame |
>    frame _ Form extent: self decoderSize depth: Display depth.	
>    process _ [[true] whileTrue: [
> 	self decoderRequestCapture.
> 	frameSemaphore wait.
> 	self decoderCopyLastCapturedFrameInto: frame.
> 	colorMap _ ColorMap shifts: #(0 0 -5 0)
> 		masks: #(0 0 2r000001111100000 0)
> 		colors: ((1 to: 32) collect: [:i |
> 		i < 16 ifTrue: [1] ifFalse: [0]]).
> 	bwFrame _ Form extent: frame extent depth:1.
> 	(BitBlt toForm: bwFrame)
> 		copyForm: frame to: 0 at 0 rule: Form over colorMap: colorMap.
>
> 	"Here's the problem: the class I am extending wants to display
> 	frame (which MUST be of depth 16 or greater), not bwFrame
> 	(which is of depth 1), so I need to get bwFrame's revised
> 	colorMap back to depth 16 before I make frame equal to
> 	bwFrame. This is why it is blowing up. Any ideas?"
>
> 	frame _ bwFrame.
> 	]] forkAt: self decoderProcessPriority.
>
> -----Original Message-----
> From: squeak-dev-bounces at lists.squeakfoundation.org 
> [mailto:squeak-dev-bounces at lists.squeakfoundation.org] On Behalf Of 
> Bert Freudenberg
> Sent: Thursday, July 22, 2004 4:38 AM
> To: The general-purpose Squeak developers list
> Subject: Re: Using video input in Squeak
>
>
> Am 22.07.2004 um 03:58 schrieb Dean_Swan at Mitel.COM:
>
>>
>> Hi Rob, Bert, Jack:
>>
>> Form asGrayScale actually does extract the green component from 32 bit
>> forms, or converts a lower depth Form to a 32 bit form and then
>> extracts the green component.  It is NOT however, a single BitBlt
>> call.  It does a copyBits for each column, and some fancy form/bitmap
>> substituion to treat the 32 bit form as if it were an 8 bit form four
>> times as wide.
>
> I think the asGrayscale method is older than the ColorMap class, which
> is a rather recent extension to the original BitBlt. For performance,
> it should be rewritten now.
>
>> How would you accomplish this with only a "single BitBlt call"?
>
> ==== snip ====
> | orgForm bwForm |
> "Make a dark shape on light ground"
> Display getCanvas
> 	fillRectangle: (0 at 0 extent: 400 at 300) color: Color yellow;
> 	fillOval: (100 at 100 extent: 30 at 50) color: Color blue.
> orgForm := Form fromUser asFormOfDepth: 16.
> "setup colormap to extract green component and map to 0 or 1"
> colorMap := ColorMap shifts: #(0 0 -5 0)
> 	masks: #(0 0 2r000001111100000 0)
> 	colors: ((1 to: 32) collect: [:i | i < 16 ifTrue: [1] ifFalse: [0]]).
> "16 = threshold of 0.5"
> "This should also be allocated only once "
> bwForm := Form extent: orgForm extent depth: 1.
> "Do this every frame"
> (BitBlt toForm: bwForm)
> 	copyForm: orgForm to: 0 at 0 rule: Form over colorMap: colorMap.
> "Done"
> bwForm display
> ==== snap ====
>
> For 32 bpp, you of course need to tweak the shifts, masks, and colors:
>
> ColorMap shifts: #(0 0 -8 0)
> 	masks: #(0 0 16r00FF00 0)
> 	colors: ((1 to: 256) collect: [:i | i < 128 ifTrue: [1] ifFalse:
> [0]]).  "128 = threshold of 0.5"
>
> I guess the 16 bpp version will be faster, but you should use whatever
> the plugin delivers fastest. You should avoid the conversion to another
> depth unless it is really necessary. Also, all constant calculations
> should be moved out of the inner loop (the one that fetches images from
> the camera and processes them).
>
> Also, if your destination bitmap is not of depth 1, the colors in the
> ColorMap of course need other PixelValues:
>
> String streamContents: [:s | #(1 8 16 32) do: [:d |
> 	s print: d; nextPutAll: ': '.
> 	{Color black. Color white} do: [:c |
> 		s nextPutAll: (c pixelValueForDepth: d) hex; space].
> 	s cr]]
>
> 1: 16r1 16r0
> 8: 16r1 16rFF
> 16: 16r1 16r7FFF
> 32: 16rFF000001 16rFFFFFFFF
>
>> Rob, just a caveat using Form>>asGrayScale - It is an approximation.
>>  I tried it using a workspace as the test bitmap, and the selected
>> text didn't come out as selected because with default colors, selected
>> text is black on a bright green and the background is bright white.
>>  This leads to what looks like no selected text in the grayscale
>> version, where the "properly" calculated Form>>yComponent method does
>> show the selected text as black on medium gray.
>
> You just have to adjust the threshold ...
>
> - Bert -
>




More information about the Squeak-dev mailing list