Previously Teigha developers could add an alpha channel to a raster image using the OdGiRasterImage::convert method and subsequently cutting off the background color. However, using the new OdGiRasterImage wrapper OdGiRasterImageAlphaChannelAdder simplifies this task.
Creating an object
Before we can create an instance of OdGiRasterImageAlphaChannelAdder, obtain an instance of the original OdGiRasterImage. There are several ways to get it. For example, if the original image is a file, we can use the Teigha raster service to load it:
OdRxRasterServicesPtr pRasSvcs = odrxDynamicLinker()->loadApp(RX_RASTER_SERVICES_APPNAME, false);
if (pRasSvcs.isNull()) // Check that raster services module correctly loaded
throw OdError(eNullPtr);
OdGiRasterImagePtr pOriginalImage = pRasSvcs->loadRasterImage(inputFileName);
if (pOriginalImage.isNull()) // Check that raster image correctly loaded throw OdError(eNullPtr);
If we have OdGsDevice from which we can take the raster image, use the following code:
OdGiRasterImagePtr pOriginalImage = OdGiRasterImagePtr(pDevice->properties()->getAt(L"RasterImage"));>
if (pOriginalImage.isNull())
throw OdError(eNullPtr);
After we obtain an instance of the original image, create an instance of OdGiRasterImageAlphaChannelAdder:
OdGiRasterImagePtr pImage = OdGiRasterImageAlphaChannelAdder::createObject( pOriginalImage, CutOffColor, CutOffColorThreshold );
if (pImage.isNull())
throw OdError(eNullPtr);
where CutOffColor is the color of the pixels to which the alpha value 0 will be assigned and CutOffColorThreshold is a threshold value for alpha interpolation (described below).
Working with OdGiRasterImageAlphaChannelAdder
We can work with an instance of OdGiRasterImageAlphaChannelAdder as a usual OdGiRasterImage. For example, we can save it using the Teigha raster service:
pRasSvcs->saveRasterImage( pImage, ouptupFileName );
We also can access image pixels using the OdGiRasterImage::scanLines method. However, because OdGiRasterImageAlphaChannelAdder does not store a compatible pixels array, direct access is not allowed and
const OdUInt8 *pPixels = pImage->scanLines();
will give a NULL pointer. Instead of direct access, copy the pixel array into an intermediate user-defined array:
OdUInt8Array scanLine;
scanLine.resize(pInputImage->scanLineSize());
pImage->scanLines(scanLine.asArrayPtr(), 0);
Using pixel cut colors and threshold values
As an example, let’s use the following raster image with different gray rectangles and a white background:
Create OdGiRasterImageAlphaChannelAdder with white cutoff color and zero threshold and save it to a file:
OdRxRasterServicesPtr pRasSvcs = odrxDynamicLinker()->loadApp(RX_RASTER_SERVICES_APPNAME, false);
if (pRasSvcs.isNull()) // Check that raster services module correctly loaded
throw OdError(eNullPtr);
OdGiRasterImagePtr pOriginalImage = pRasSvcs->loadRasterImage(inputFileName);
if (pOriginalImage.isNull()) // Check that raster image correctly loaded
throw OdError(eNullPtr);
OdGiRasterImagePtr pImage = OdGiRasterImageAlphaChannelAdder::createObject( pOriginalImage, ODRGB( 255, 255, 255 ) );
if (pImage.isNull())
throw OdError(eNullPtr);
pRasSvcs->saveRasterImage( pImage, ouptupFileName );
The result is:
All white pixels now have zero alpha values.
We can use the threshold value to make a smooth cut. If the threshold is not zero, each pixel’s color that lies in the interval [Cut Color Component Value – threshold; Cut Color Component Value + threshold] are assigned the alpha value interpolated on the interval [Color = Cut Color, Alpha value = 0 -> Color = Cut Color + threshold, Alpha value = 255].
So, if we set the threshold to 20, we obtain the following result:
All white pixels are still transparent, and pixels of the last rectangle become partially transparent.
If we increase the threshold value up to 40, the last rectangle becomes more transparent and the next-to-last rectangle becomes partially transparent:
Conclusion
OdGiRasterImageAlphaChannelAdder gives Teigha developers a simple way to set an alpha channel to a raster image.