I need some direction from someone more familiar with the particulars of using BitBlt.
In my current project there are 3 forms: srcForm dstForm maskForm of which scrForm and dstForm are 32-bit depth and the maskForm is 1-bit depth. The maskForm contains black pixels in a non-rectangular shape.
I want to copy pixels from the scrForm onto the dstForm using the maskForm for inclusion. The srcForm is smaller in extent than the dstForm. The maskForm is the same size as the dstForm. I've tried a number of things, and frankly went into this believing it would be very simple, but ended up implementing pixel copies. There must be a smarter way.
- Steve
Hi,
BitBlt doesn't support a "three-way-copy" at this point (e.g., take pixels from two sources, combine them and store them into a third form) so the best you can do is to use a temporary form for compositing. E.g.
| tmpForm | tmpForm := Form extent: srcForm extent depth: srcForm depth. srcForm displayOn: tmpForm. "make a copy of src" maskForm displayOn: tmpForm at: 0@0 rule: Form bitAnd. "mask out pixels" tmpForm displayOn: dstForm at: 0@0 rule: Form paint. "copy non-zero pixels"
Note: above code is not tested. In particular 'Form bitAnd' might be the wrong way around - check out the various combination rules; one of them will do the trick.
Cheers, - Andreas
-----Original Message----- From: squeak-dev-admin@lists.squeakfoundation.org [mailto:squeak-dev-admin@lists.squeakfoundation.org] On Behalf Of Stephan B. Wessels Sent: Wednesday, October 30, 2002 1:07 PM To: Squeak mailing list Subject: BitBlt question
I need some direction from someone more familiar with the particulars of using BitBlt.
In my current project there are 3 forms: srcForm dstForm maskForm of which scrForm and dstForm are 32-bit depth and the maskForm is 1-bit depth. The maskForm contains black pixels in a non-rectangular shape.
I want to copy pixels from the scrForm onto the dstForm using the maskForm for inclusion. The srcForm is smaller in extent than the dstForm. The maskForm is the same size as the dstForm. I've tried a number of things, and frankly went into this believing it would be very simple, but ended up implementing pixel copies. There must be a smarter way.
- Steve
Andreas,
Thanks for the prompt help. It's pretty close to what I need.
For those not interested in the arcane details of what I'm trying to do with these forms, skip the rest of this message.
What I've done is written a simple "tool" in Squeak that allows someone to select a folder full of full-sized digital images and generate a set of web pages for viewing those images. These web pages have simple navigation tools and thumbnails for each digital image, allowing simple selection for viewing.
It's not a new concept. I just prefer to do this sort of thing with Squeak. And I get to learn a little bit more about Form and BitBlt.
Here's an example of the application of my first pass at this tool: http://w3.one.net/~swessels/pages/steve/family-vac-2002/index.html
To make that work I used a pixel copy technique. It's pretty slow. Hence the request for help.
Here (http://w3.one.net/~swessels/images/other/example.jpg) is a screen capture of trying to use BitBlt without doing pixel copies. Using Andreas' suggestion, you can see the bottom of the workspace and the displayed results.
The original digital photograph is a large JPEG image. The first form, "scaledForm", is the original photograph drawn in the proper smaller size for my intended thumbnail.
"newForm" is showing several steps combined. It is a white form of the final size for the thumbnail. "scaledForm" was drawn onto "newForm", then using round mask forms I white-out the four corners to make them round. The CornerRounder morph is not used for several reasons. Although I could probably extend that morph's utility methods to operate on Forms now. That's another discussion.
The "shadowForm" is a composite drawn from several smaller Forms. I did not adopt the shadow methods from Morphs. I wanted a subtle but different look.
"maskForm" is like "newForm" except the drawing pixels are all black. It is a 1-bit deep form.
"tempForm" is the result of applying Form erase with BitBlt, using the "scaledForm" and "maskForm".
"destForm" is the result of applying "tempForm" with the Form paint rule. Note from the workspace code shown that "shadowForm" had been drawn there first. It's very close to what I want. However, the lower right corner of the drawing shows bleed-through of the original "shadowForm" because "scaledForm" has black pixels in that corner. When I make these thumbnails larger it's very obvious.
The "pixelCopied" drawing is what I want (and am currently using). It's the goal-image and is drawn in the slower manner. I walk through the "scaledForm" pixel-by-pixel, check if the "maskForm" is black for that same pixel, and then copy it to the final form. This keeps the corner shadow images intact since they are masked out and it rounds off the corners using the mask itself as a guide.
So, not quite there yet.
- Steve
Hi,
It's not a new concept. I just prefer to do this sort of thing with Squeak. And I get to learn a little bit more about Form and BitBlt.
What's wrong with:
sketch := SketchMorph withForm: (Form fromBinaryStream: myFile). sketch cornerStyle: #rounded; extent: myThumbnailExtent; addDropShadow; shadowColor: (Color black alpha: 0.5); fullDrawOn: destForm getCanvas.
?! ;-)
"destForm" is the result of applying "tempForm" with the Form paint rule. Note from the workspace code shown that "shadowForm" had been drawn there first. It's very close to what I want. However, the lower right corner of the drawing shows bleed-through of the original "shadowForm" because "scaledForm" has black pixels in that corner. When I make these thumbnails larger it's very obvious.
Not very obvious at that size ;-) But there are two things you can try. First of all, try to get rid of the "zero pixels" in the form (note: there's a difference between "zero" and "black" pixels - black is _not_ zero in Squeak). It might be enough to "Form>>paint" the original form onto a form which has been filled black, e.g.,
blackenedForm := Form extent: tmpForm extent depth: tmpForm depth. blackenedForm fillBlack. tmpForm displayOn: blackenedForm at: 0@0 rule: Form paint. "NOT Form>>over" tmpForm := blackenedForm.
Alternatively, try doing the blits the other way around, by inverting the mask. This should work too.
Cheers, - Andreas
squeak-dev@lists.squeakfoundation.org