Creating transparent image using ATIL

<?xml encoding=”UTF-8″>By Balaji Ramamoorthy

Here is a sample code that implements a custom ATIL image filter to create transparent images. The implementation sets the Alpha channel for Red color pixels in the image. You can modify it to use any other RGB value if you choose. The complete sample project can be downloaded here :
Download TransparentSnapShotUsingATIL

The sample project uses the “getSnapShot” to capture a snap shot of the entities selected. To try it,  build the attached sample project and load it in AutoCAD 2015. Open any drawing and run “GenImg” command and select the entity when prompted. The red background is intentionally set to the AcGsDevice while generating the screenshot. This is because, we can then use Red as the color to turn transparent from the image filter. The transparent image is generated under “D:TempTest_Arx.png”.

Here is the relevant code :

//MyRgbaTransparency.h

 
 <span>#ifndef</span><span>  MYRGBATRANSPARENCY_H</span>
 <span>#define</span><span>  MYRGBATRANSPARENCY_H</span>
 
 <span>class</span><span>  MyRgbaTransparency </span>
 	: <span>public</span><span>  Atil::ImageFilter</span>
 <span>{</span>
 <span>public</span><span> :</span>
 	MyRgbaTransparency ( 
 		Atil::RowProviderInterface* pInput, 
 		<span>int</span><span>  nKeyColors, </span>
 		Atil::RgbColor* paKeyColors);
 
 	<span>virtual</span><span>  ~MyRgbaTransparency ();</span>
 
 	<span>virtual</span><span>  <span>int</span><span>  rowsRemaining ();</span></span>
 
 	<span>virtual</span><span>  <span>void</span><span>  getNextRow</span></span>
 		(Atil::DataBuffer &oneRow);
 
 	<span>virtual</span><span>  <span>void</span><span>  convertColor</span></span>
 		(Atil::ImagePixel& color) <span>const</span><span> ;</span>
 
 <span>private</span><span> :</span>
 	<span>enum</span><span>  By <span>{</span> kQuad, kTreble, kNon <span>}</span>;</span>
 	By mBy;
 	<span>int</span><span>  mnRows;</span>
 	<span>int</span><span>  mnColumns;</span>
 	<span>int</span><span>  mnKeyColors;</span>
 	<span>int</span><span>  mnRowsRemaining;</span>
 	Atil::RgbColor* mpKeyColors;
 <span>}</span>;
 
 <span>#endif</span>
 
 <span>//MyRgbaTransparency.cpp</span>
 <span>#include</span><span>  <span>"stdafx.h"</span></span>
 <span>#include</span><span>  <span>"MyRgbaTransparency.h"</span></span>
 
 MyRgbaTransparency::MyRgbaTransparency
 	(Atil::RowProviderInterface* pInput, 
 	<span>int</span><span>  nKeyColors, </span>
 	Atil::RgbColor* paKeyColors )
 <span>{</span>
 	connectInput( pInput );
 
 	Atil::Size size(input(0)->size());
 	mnColumns = size.width;;
 	mnRows = size.height;
 	mnRowsRemaining = size.height;
 	mnKeyColors = nKeyColors;
 
 	<span>switch</span><span> (input(0)->dataModel().dataModelType())</span>
 	<span>{</span>
 		<span>case</span><span>  Atil::DataModelAttributes</span>
 			::DataModelType::kRgbModel:
 		<span>{</span>
 			mBy = kTreble;
 			init( size );
 			<span>break</span><span> ;</span>
 		<span>}</span>
 
 		<span>default</span><span> :</span>
 		<span>{</span>
 			mBy = kQuad;
 			init( size );
 			<span>break</span><span> ;</span>
 		<span>}</span>
 	<span>}</span>
 <span>}</span>
 
 MyRgbaTransparency::~MyRgbaTransparency ()
 <span>{</span>
 <span>}</span>
 
 <span>int</span><span>  MyRgbaTransparency::rowsRemaining ()</span>
 <span>{</span>
 	<span>return</span><span>  mnRowsRemaining;</span>
 <span>}</span>
 
 <span>void</span><span>  MyRgbaTransparency::getNextRow</span>
 	(Atil::DataBuffer &oneRow)
 <span>{</span>
 	input(0)->getNextRow(oneRow);
 
 	<span>if</span><span>  ( mnRowsRemaining > 0 ) </span>
 	<span>{</span>
 		<span>if</span><span>  ( mBy == kTreble ) </span>
 		<span>{</span>
 			Atil::RgbColor *pColor = 
 				(Atil::RgbColor*) oneRow.dataPtr();
 			<span>for</span><span>  (<span>int</span><span>  i=0; i<mnColumns; ++i) </span></span>
 			<span>{</span>
 				<span>if</span><span> ( pColor[i].rgba.red == 255 && </span>
 					pColor[i].rgba.blue == 0 && 
 					pColor[i].rgba.green == 0)
 				<span>{</span><span>// Turn alpha to 0 only for Red values</span>
 					pColor[i].rgba.alpha = 0;
 				<span>}</span>
 			<span>}</span>
 		<span>}</span> 
 		--mnRowsRemaining;
 	<span>}</span>
 <span>}</span>
 
 <span>void</span><span>  MyRgbaTransparency::convertColor</span>
 	(Atil::ImagePixel& color) <span>const</span>
 <span>{</span>
 	ImageFilter::convertColor(color);
 	<span>switch</span><span>  ( color.type )</span>
 	<span>{</span>
 		<span>case</span><span>  Atil::DataModelAttributes::PixelType::kRgba:</span>
 		<span>{</span>
 			Atil::RgbColor rgb( color.value.rgba );
 			<span>if</span><span> ( rgb.rgba.red == 255 </span>
 				&& rgb.rgba.blue == 0 
 				&& rgb.rgba.green == 0)
 			<span>{</span><span>// Turn alpha to 0 only for Red values</span>
 				rgb.packed = rgb.packed;
 				rgb.rgba.alpha = 0;
 				color.value.rgba = rgb;
 			<span>}</span>
 			<span>break</span><span> ;</span>
 		<span>}</span>
 	<span>}</span>
 <span>}</span>
 
 <span>// Usage of the Transparency Image filter</span>
 
 Atil::RgbModel rgbModel(
 	Atil::RgbModelAttributes::k4Channels, 
 	Atil::DataModelAttributes::kRedGreenBlueAlpha);
 
 Atil::ImagePixel initialColor(
 	Atil::DataModelAttributes::PixelType::kRgba);
 
 initialColor.setToZero();
 initialColor.type = Atil::DataModelAttributes::kRgba;
 initialColor.value.rgba = 0xff000000;
 Atil::Image imgSource(
 	Atil::Size(width, height), 
 	&rgbModel, initialColor);
 
 <span>// get a snapshot of the GsView</span>
 pView->getSnapShot(&imgSource, screenRect.m_min);
 
 Atil::RowProviderInterface *pPipe 
 	= imgSource.read(
 		imgSource.size(), 
 		Atil::Offset(0,0),Atil::kBottomUpLeftRight);
 
 <span>if</span><span> (pPipe != NULL)</span>
 <span>{</span>
 	Atil::RgbColor aColors[1];
 	COLORREF crBkg = RGB(255, 0, 0); 
 
 	aColors[0] = Atil::RgbColor(
 		GetRValue(crBkg), 
 		GetGValue(crBkg & 0xffff), 
 		GetBValue(crBkg), 0);
 
 	pPipe = <span>new</span><span>  MyRgbaTransparency(</span>
 		pPipe, 
 		1, 
 		aColors);
 	<span>if</span><span>  (pPipe != NULL && pPipe->isValid()) </span>
 	<span>{</span>
 		TCHAR drive[_MAX_DRIVE];
 		TCHAR dir[_MAX_DIR];
 		TCHAR fname[_MAX_FNAME];
 		TCHAR ext[_MAX_EXT];	
 		<span>// find out what extension we have</span>
 		_tsplitpath_s(
 			pFileName, 
 			drive, dir, fname, ext);
 
 		Atil::ImageFormatCodec *pCodec = NULL;
 
 		<span>if</span><span>  (CString(ext) == _T(<span>".png"</span><span> ))</span></span>
 			pCodec = <span>new</span><span>  PngFormatCodec();</span>
 
 		<span>if</span><span>  (pCodec != NULL)</span>
 		<span>{</span>
 			<span>// and it is compatible</span>
 			<span>if</span><span>  (Atil::FileWriteDescriptor::</span>
 				isCompatibleFormatCodec(
 				pCodec, &(pPipe->dataModel()), 
 				pPipe->size())) 
 			<span>{</span>
 			<span>// create a new file output object</span>
 			Atil::FileWriteDescriptor fileWriter(pCodec);
 			Atil::FileSpecifier fs(
 				Atil::StringBuffer((lstrlen(pFileName)+1) 
 				* <span>sizeof</span><span> (TCHAR), </span>
 				(<span>const</span><span>  Atil::Byte *)pFileName, </span>
 				Atil::StringBuffer::kUTF_16), 
 				Atil::FileSpecifier::kFilePath);
 
 			<span>// if the file already exists</span>
 			<span>// we better delete it because setFileSpecifier </span>
 			<span>// will fail otherwise</span>
 			_tremove(pFileName);
 
 			<span>if</span><span>  (fileWriter.setFileSpecifier(fs))</span>
 			<span>{</span>
 				fileWriter.createImageFrame(
 					pPipe->dataModel(), 
 					pPipe->size());
 
 				<span>// At any rate you want to fetch the property</span>
 				<span>// from the write file descriptor then alter </span>
 				<span>// it and set it inuc1u8230?</span>
 				Atil::FormatCodecPropertyInterface *pProp 
 					= fileWriter.getProperty(
 				Atil::FormatCodecPropertyInterface::kCompression);
 				<span>if</span><span>  (pProp != NULL) </span>
 				<span>{</span>
 				<span>if</span><span>  (CString(ext) == _T(<span>".png"</span><span> )) </span></span>
 				<span>{</span>
 					PngCompression *pComp = 
 						<span>dynamic_cast</span><span> <PngCompression*>(pProp);</span>
 					<span>if</span><span>  (pComp != NULL) </span>
 					<span>{</span>
 					pComp->selectCompression(
 						PngCompressionType::kHigh);
 
 					fileWriter.setProperty(pComp);
 					<span>}</span>
 				<span>}</span>
 
 				<span>// clean up</span>
 				<span>delete</span><span>  pProp; </span>
 				pProp = NULL;
 				<span>}</span>
 			<span>}</span>
 
 			Atil::FormatCodecPropertySetIterator* pPropsIter
 				= fileWriter.newPropertySetIterator();
 			<span>if</span><span>  (pPropsIter)</span>
 			<span>{</span>
 				<span>for</span><span>  (pPropsIter->start(); </span>
 					!pPropsIter->endOfList(); 
 					pPropsIter->step())
 				<span>{</span>
 					Atil::FormatCodecPropertyInterface* pProp
 						= pPropsIter->openProperty();
 					<span>if</span><span>  (pProp->isRequired())</span>
 					<span>{</span>
 						fileWriter.setProperty(pProp);
 					<span>}</span>
 					pPropsIter->closeProperty();
 				<span>}</span>
 				<span>delete</span><span>  pPropsIter;</span>
 			<span>}</span>
 
 			Atil::FormatCodecPropertyInterface 
 				*pTransparencyProp
 			= fileWriter.getProperty(
 			Atil::FormatCodecPropertyInterface::kTransparency);
 
 			<span>if</span><span> (pTransparencyProp)</span>
 			<span>{</span>
 				fileWriter.setProperty(pTransparencyProp);
 			<span>}</span>
 
 			<span>// ok - ready to write it</span>
 			fileWriter.writeImageFrame(pPipe);
 
 			done = <span>true</span><span> ;</span>
 			<span>}</span>
 		<span>}</span>
 		<span>delete</span><span>  pCodec;</span>
 		<span>}</span>
 	<span>}</span>
 <span>}</span>
 


Comments

4 responses to “Creating transparent image using ATIL”

  1. Is it possible convert .CAL to Tiff using ATIL in .NET ?

  2. Hi Ranjan,
    I do not think, ATIL can read a .cal image format. The list of codecs in the ATIL folder does not have a codec for it. I can only find JFIF, JPG, PNG, TIFF and BMP codecs.
    Also, ATIL is a C++ only libary. If you want to use ATIL, you may need to create a C++ module and have it loaded in AutoCAD. You can then have your wrapper function invoked from .Net.
    Regards,
    Balaji

  3. Sun Lingyun Avatar
    Sun Lingyun

    Hi Balaji:
    The Atil library is so big, where should I start learning? The SDK_DOC only have specification, but do not have any demo code.

  4. Hi, Balaji,
    this doesn’t work on arx23. I received the black image.

Leave a Reply to leehaoCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading