home
1 September 2005
Gdi Plus
background:
I have always been surprised at the state of affairs of any graphics
api, but perhaps it is because I was spoiled in the early 1980's, by
the fine work done by Bill Atkinson
with the Macintosh Quickdraw. It was perhaps that Atkinson worked
more independently than his successors, that his work was better
thought out, more consistent, elegant and well documented that it in
many respects is better than what we have today. I recall with
early windows 32 bit api's they had largely borrowed form QuickDraw,
filling in many of QuickDraw's shortcomings with novel ideas of their
own. The problem was, and even today still is with GDI plus
enhancement, that for every shortcoming that is corrected, new and
obvious inconsistencies, mistakes, misdirections, and just plain slop
are introduced. I was recently asked to show a machine vision
expert and mathlab level programmer how to throw some bits and
bytes / pixels on the screen. Not having done this in four years
it was a painful experience, just to re figure what was the proper way
to access the pixmap. Of all the interfaces what was the one that
really worked, while the others were just for this application or these
conditions or dead ends when somebody started to generalize
functionality and then just gave up. I left my friend with an
example and many bytes, bits, code fragments and spare parts lying
around like some cluttered and dirty old automobile garage. Then
a couple of months later I happened across the latest Microsoft
improvement called GDIplus. How come I couldn't find this in the
help system when I was in their developer environment before?
comments:
For the windows Vis.Net, lookup gdiplus, the big differences are
- It needs to be initialized and released at the beginning and end
of any windowing program. (Presumably because it lives in a truly
non-shared environment, unlike before where one program could break how
another rendered.)
- The vector graphics operations go through a common transformation
operation. Scaling, rotation, filters (anti-alias), are all
implemented as well as a stack based approach to the currently selected
transformation. Other hints are included here like, quality v.
speed, selection.
- The interface between the vector graphics and the pixel graphics
is much better. It is much easier to draw some vector graphics
into a Bitmap buffer and then read/write over what was drawn. It
would be really good only the Bitmap, Graphics and such interfaces are
hopelessly confused. (Nothing that a good simple wrapper can't
clean up though!).
- Other interfaces for common objects have been cleaned up a
bit. Pen(s), Brush(es) and such are true objects, Paths added
etc. In the two steps back department Bitmaps, Images and such
are designed poorly and take on whole bunch of tasks/responsibilities
belonging elsewhere. Interfaces that you may regularly use
require the obligatory obj->func(obj->attrib1, obj->attrib2,
obj->attrib3, ..., obj->attribn); have you hold state information
arbitrarily (sound like CPen and CBrush?). In all lots of
misdirection. Oh well. I note that in the code everything
seems to break down to C calls and when the API is actually using the
CPU clock your really in traditional GDI world with ::StretchBlt.
example:
The following very quick Windows example shows
- standard simple vector drawing
- vector drawing with stretching, and 2D rotation
- access to and modification of the GDI Plus vector graphics
in pixel plane. What I have done is blur by averaging adjacent
pixels followed by reinforcement of the original vector
graphics. The blurring should cause the colors to bleed to
a colored equilibration, but I think that it fades to gray due to round
down error.
- that even with such a small example you may need to concern
yourself with optimization. I have done just a little bit of
thinking on the subject and can see no way to generally optimize byte
plane graphics. The buffer would need to be retyped depending on
the transformation and its optimum storage and transformation seems
widely dependent on what exactly you would hope to achieve
This example is almost 1K lines of code. All but perhaps near 100
are the MFC auto generated.
Development environment Microsoft Visual C++.net V7.1, but it
would be pretty trivial to port it to earlier versions.
Download Project, source (~50kb)
references:
home