File: LibImageManip.zip Author: Edmund Vermeulen <edmundv@xs4all.nl> Release: 1.1.0 (Jan 26th 2000) Compatibility: BeOS R4 for PowerPC and Intel Location: contrib/libraries Description: Image manipulation library Notes: Public domain
LibImageManip is my attempt at creating a library for image manipulation add-ons that is simple to use. It is modelled after, and based on, the datatypes library (now the translation kit) by Jon Watte.
The library basically supports two kinds of add-ons, known as manipulators and converters.
The library and its add-on interface are designed to be as simple as possible in order to encourage anyone to create add-ons or use the library in his/her applications. The library is completely free and comes with full source code.
The image manipulation library uses a proxy class for accessing bitmaps. This
has several advantages over directly using the BBitmap
class:
BBitmap
format.
The proxy class is an abstract base class with the following interface:
class BitmapAccessor { public: virtual ~BitmapAccessor(); virtual bool IsValid() = 0; virtual bool CreateBitmap(BRect bounds, color_space space) = 0; virtual BRect Bounds() = 0; virtual color_space ColorSpace() = 0; virtual float BytesPerPixel(); virtual void *AccessBits(BRect area, int32 *rowBytes) = 0; virtual void BitsNotChanged() = 0; };
The IsValid()
, Bounds()
, and ColorSpace()
functions work the same as the equivalent functions in the BBitmap
class.
Beware that Bounds()
may return a rectangle that is not positioned
at (0, 0).
The CreateBitmap()
function is called from within the Convert()
function by a converter add-on to create the destination bitmap.
The BytesPerPixel()
function is used to get the number of bytes in
a single pixel. If the pixel size is larger than you would expect then you should
simply skip the extra bytes at the end to get to the next pixel. This can be the case
for 'multi-channel' bitmaps, where several channels of data are interleaved. For
example, when accessing only the blue part of a 32-bit bitmap as if it was an 8-bit
grayscale bitmap. For monochrome bitmaps the number of bytes per pixel is 1/8th.
These bitmaps are special. For instance, you can only access the bits on their
natural alignment, and not in the middle of a chunk.
With the AccessBits()
function you gain access to the raw data
of a certain area of the bitmap. The number of bytes per row is returned in the
rowBytes variable. You can use this number to skip to the next row of
pixels if you accessed more then one row. The pointer returned by AccessBits()
will remain valid until another call to AccessBits()
or to the destructor
is made. For efficienscy reasons you should keep the requested area small.
For applications there is a class for accessing BBitmaps
implemented
in the library. It is called BBitmapAccessor
, and besides the normal
bitmap accessor functions, it has the following extra functions:
class BBitmapAccessor : public BitmapAccessor { public: // Constructor BBitmapAccessor(BBitmap *bitmap = NULL, const BRect *section = NULL); // Overriden BitmapAccessor functions ... // Get pointer to the BBitmap virtual BBitmap *Bitmap() const; // Get/set if the BBitmap should be deleted at destruction time virtual bool Dispose() const; virtual void SetDispose(bool flag); // Set invokers for automatically sending messages when a bitmap // is created and/or when it is updated virtual void SetInvokers(BInvoker *bitmapCreated, BInvoker *bitmapUpdated); private: ... };
The BBitmap
to accesss can be specified in the constructor. Optionally,
access can be restricted to a given rectangular section. By default, the ownership of the
BBitmap
stays with the caller. If you want the BBitmapAccessor
object to delete the bitmap for you then you should call SetDispose(true)
on it.
If a new BBitmap
is created through CreateBitmap()
then the
ownership initially lies with the BBitmapAccessor
object. Call
SetDispose(false)
on it if you don't want it to be deleted for you.
You can set invokers for automatically sending messages when a bitmap is created and/or when it is updated. You will be notified by the invoker's message with some extra data added to it. This will be respectively the newly created bitmap pointer, or a rectangle of the updated area. The data can be extracted from the message as follows:
BBitmap *new_bitmap; msg->FindPointer("bitmap", reinterpret_cast(&new_bitmap)); BRect update_rect; msg->FindRect("rect", &update_rect);
The invokers will automatically be deleted by the BBitmapAccessor
object.
Here is a list of all exported data and functions of an image manipulation add-on.
const char addonName[]; /* required, C string, ex "Gamma Correct" */ const char addonInfo[]; /* required, descriptive C string, ex "Makes images brighter. Written by Slartibardfast." */ const char addonCategory[]; /* optional, C string, ex "Color" */ int32 addonVersion; /* required, integer, ex 100 */ status_t Manipulate( BitmapAccessor *sourceBitmap, BMessage *ioExtension, /* can be NULL */ bool checkOnly); status_t Convert( BitmapAccessor *sourceBitmap, BitmapAccessor *destBitmap, /* call CreateBitmap() on this */ BMessage *ioExtension, /* can be NULL */ bool checkOnly); status_t MakeConfig( /* optional */ BMessage *ioExtension, /* can be NULL */ BView **outView); status_t GetConfigMessage( /* optional */ BMessage *ioExtension, BMessage *ioCapability);
The addonName
, addonInfo
, addonCategory
,
and addonVersion
are exported data that contain user accessable
information about the add-on.
The Manipulate()
and Convert()
functions are where
the real work is done. Depending on which function an add-on exports, it
is considered to be an image manipulator or image converter. Both functions
can be called in normal or in 'check-only' mode. This last mode is used to
ask an add-on if it supports a certain source bitmap and io extension.
The add-on should return B_NOT_ALLOWED
if it doesn't.
Both the Manipulate()
and Convert()
functions take
a pointer to a source bitmap accessor. The Convert()
function
also take a pointer to an empty bitmap accessor object on which it will call
CreateBitmap()
to create the destination bitmap. The
ioExtension argument is optional, and may be ignored by the
add-on.
The ioExtension message can be used for passing add-on specific
configuration settings as explained below. It can also be used to, for
example, ask the add-on to only affect a certain rectangle instead of the
whole bitmap. Some standard io extensions are
defined for this purpose. The add-on should add the io extensions that it
supports to the ioCapability message in its GetConfigMessage()
function.
The last two functions are optional. MakeConfig()
allows the
add-on to create a BView
with controls to let the user
configure the add-on's settings. GetConfigMessage()
is used to
get the current settings and supported capabilities from the add-on. The
settings are added to the ioExtension message. This message can
be stored and passed back to the add-on through the Manipulate()
or Convert()
functions. The capabilities are added as name and
type code pairs to the ioCapability message. This can be used
by an application to check if an add-on supports a certain io extension.
Here is a list of the functions that an application can use in the image manipulation library.
/* Get the current version of the library and the minimum version with which it is still compatible */ const char * Image_Version( int32 *curVersion, /* will receive the current version */ int32 *minVersion); /* will receive the minimum version */ /* Initialize the library before usage */ status_t Image_Init( const char *loadPath); /* NULL for the default */ /* Shutdown the library after usage */ status_t Image_Shutdown(); /* Get all image manipulators that support a given source bitmap and io extension */ status_t Image_GetManipulators( BitmapAccessor *sourceBitmap, /* NULL to get all manipulators */ BMessage *ioExtension, /* can be NULL */ image_addon_id **outList, /* call delete[] on it when done */ int32 *outCount); /* will receive amount in list */ /* Get all image converters that support a given source bitmap and io extension */ status_t Image_GetConverters( BitmapAccessor *sourceBitmap, /* NULL to get all converters */ BMessage *ioExtension, /* can be NULL */ image_addon_id **outList, /* call delete[] on it when done */ int32 *outCount); /* will receive amount in list */ /* Get info on an image manipulator or image converter add-on */ status_t Image_GetAddonInfo( image_addon_id imageAddon, const char **addonName, /* will receive pointer to the name */ const char **addonInfo, /* will receive pointer to the info */ const char **addonCategory /* will receive pointer to the category */ int32 *addonVersion); /* will receive the version */ /* Let an add-on manipulate a bitmap */ status_t Image_Manipulate( image_addon_id imageManipulator, BitmapAccessor *sourceBitmap, BMessage *ioExtension, /* can be NULL */ bool checkOnly = false); /* Let an add-on convert a bitmap to another bitmap */ status_t Image_Convert( image_addon_id imageConverter, BitmapAccessor *sourceBitmap, BitmapAccessor *destBitmap, /* will be called CreateBitmap() on */ BMessage *ioExtension, /* can be NULL */ bool checkOnly = false); /* Let an add-on make a BView that allows the user to configure it */ status_t Image_MakeConfigurationView( image_addon_id imageAddon, BMessage *ioExtension, /* can be NULL */ BView **configView); /* will receive pointer to the new BView */ /* Get configuration and capabilities from an add-on */ status_t Image_GetConfigurationMessage( image_addon_id imageAddon, BMessage *ioExtension, /* message to add config info to */ BMessage *ioCapability); /* message to add capability info to */ /* Create a new BBitmapAccessor object; mimics the constructor */ BBitmapAccessor * Image_CreateBBitmapAccessor( BBitmap *bitmap = NULL, const BRect *section = NULL);
To use the library in your own applications you have two options:
_IMPEXP_IMAGEMANIP
to nothing
before including any of the library's header files. With weak linkage, you
have to use the Image_CreateBBitmapAccessor()
function to create
new BBitmapAccessor
objects.
Name | Type | Description |
---|---|---|
"color_space" | B_INT32_TYPE
| If possible, create the new bitmap with this color space when you call
CreateBitmap() .
|
"selection_rect" | B_RECT_TYPE
| Selection rectangle; the pixels that make up the edge of the rectangle are considered included in the rectangle. |
"selection_map" | B_POINTER_TYPE
| Selection bitmap; the pointer is to a BitmapAccessor object
which defines an "alpha" channel to determine selected-ness.
|
"use_alpha" | B_BOOL_TYPE
| Use the alpha channel for determining selected-ness (for B_RGBA32
and friends).
|
"progress_invoker" | B_POINTER_TYPE
| Pointer to a BInvoker for sending progress messages with the amount of
completion added. E.g. AddFloat("completion", 0.5) for 50%.
|
Release 1.1.0 (Jan 26th 2000)
Release 1.0.0 (Nov 18th 1999)
BitmapAccessor::BytesPerPixel()
now uses the OS function
get_pixel_size_for()
.
Release 0.6.1 (Jan 4th, 1999)
Release 0.6.0 (Aug 23th, 1998)
BBitmapAccessor
object. This is needed when using weak linkage with the library.
BitmapAccessor::AccessBits()
.
Instead, you can now call the new BitsNotChanged()
function when
you are finished with the bits, and didn't change them. This is better then
having to know beforehand that you aren't going to change anything. Suggested
by Jon Watte.
BRect
pointer argument to the constructor of
BBitmapAccessor
. If specified, it will limit access to the given area. I.e.
Bounds()
will return a smaller area. Suggested by Jon Watte.
BBitmapAccessor::AccessBits()
with fractional
BRect
values.
Release 0.5.0 (Aug 9th, 1998)
const
restrictions in the BitmapAccessor
abstract base class.
Release 0.4.0 (Jul 13th, 1998)
BBitmapAccessor
is implemented in the library instead of the
header file, and has a SetInvokers()
function for setting
invokers that send messages when the bitmap is created and when it is updated.
BytesPerPixel()
function.
Release 0.3.0 (Jul 6th, 1998)
GetConfigMessage()
.
This allows an application to check if an add-on supports a certain io
extension. Suggested by Jon Watte.
Release 0.2.0 (Jun 22nd, 1998)
To be able to use the library, you should copy the file 'libimagemanip.so' to the folder 'boot/home/config/lib'. You also need some add-ons in the folder 'boot/home/config/add-ons/ImageManip'.
The image manipulation library was written by Edmund Vermeulen, based on the original code of the datatypes library written by Jon Watte.
The library, its example application, and the example add-ons are public domain. There are no restrictions on distribution or usage.