ADN Open CIS
Сообщество программистов Autodesk в СНГ

21/03/2015

Создание прозрачного растра при помощи ATIL

Вот пример кода, который реализует собственный фильтр растра ATIL для создания прозрачного растра. Реализация устанавливает Альфа-канал для пикселей красного цвета в растре. Вы можете изменить код для использования любого другого значения RGB цвета. Полностью пример проекта можно скачать отсюда: TransparentSnapShotUsingATIL

Этот пример использует метод getSnapShot для сколки выбранных примитивов. Чтобы попробовать его перестройте проект и загрузите его в AutoCAD 2015. Откройте чертеж и запустите команду GenImg и выберите примитив. Красный фон будет намеренно установлен для AcGsDevice при генерации образа экрана. Это потому что мы используем красный цвет в качестве прозрачного в фильтре. Прозрачный растр будет сохранен в файл “D:\Temp\Test_Arx.png”.

Вот соответствующий код:

Код - C++: [Выделить]
  1. // MyRgbaTransparency.h
  2.  
  3. #ifndef  MYRGBATRANSPARENCY_H
  4. #define  MYRGBATRANSPARENCY_H
  5.  
  6. class  MyRgbaTransparency
  7.   : public  Atil::ImageFilter
  8. {
  9. public :
  10.   MyRgbaTransparency (
  11.     Atil::RowProviderInterface* pInput,
  12.     int  nKeyColors,
  13.     Atil::RgbColor* paKeyColors);
  14.  
  15.   virtual  ~MyRgbaTransparency ();
  16.  
  17.   virtual  int  rowsRemaining ();
  18.   virtual  void  getNextRow (Atil::DataBuffer &oneRow);
  19.   virtual  void  convertColor (Atil::ImagePixel& color) const ;
  20.  
  21. private :
  22.   enum  By { kQuad, kTreble, kNon };
  23.   By mBy;
  24.   int  mnRows;
  25.   int  mnColumns;
  26.   int  mnKeyColors;
  27.   int  mnRowsRemaining;
  28.   Atil::RgbColor* mpKeyColors;
  29. };
  30.  
  31. #endif
  32.  
  33.  
  34. // MyRgbaTransparency.cpp
  35.  
  36. #include  "stdafx.h"
  37. #include  "MyRgbaTransparency.h"
  38.  
  39. MyRgbaTransparency::MyRgbaTransparency
  40.   (Atil::RowProviderInterface* pInput,
  41.   int  nKeyColors,
  42.   Atil::RgbColor* paKeyColors )
  43. {
  44.   connectInput( pInput );
  45.   Atil::Size size(input(0)->size());
  46.   mnColumns = size.width;;
  47.   mnRows = size.height;
  48.   mnRowsRemaining = size.height;
  49.   mnKeyColors = nKeyColors;
  50.  
  51.   switch (input(0)->dataModel().dataModelType())
  52.   {
  53.   case  Atil::DataModelAttributes::DataModelType::kRgbModel:
  54.     {
  55.       mBy = kTreble;
  56.       init( size );
  57.       break ;
  58.     }
  59.   default :
  60.     {
  61.       mBy = kQuad;
  62.       init( size );
  63.       break ;
  64.     }
  65.   }
  66. }
  67.  
  68. MyRgbaTransparency::~MyRgbaTransparency ()
  69. {
  70.  
  71. }
  72.  
  73. int  MyRgbaTransparency::rowsRemaining ()
  74. {
  75.   return  mnRowsRemaining;
  76. }
  77.  
  78. void  MyRgbaTransparency::getNextRow (Atil::DataBuffer &oneRow)
  79. {
  80.   input(0)->getNextRow(oneRow);
  81.   if  ( mnRowsRemaining > 0 )
  82.   {
  83.     if  ( mBy == kTreble )
  84.     {
  85.       Atil::RgbColor *pColor = (Atil::RgbColor*) oneRow.dataPtr();
  86.  
  87.       for  (int  i=0; i<mnColumns; ++i)
  88.       {
  89.         if ( pColor[i].rgba.red == 255 &&
  90.           pColor[i].rgba.blue == 0 &&
  91.           pColor[i].rgba.green == 0)
  92.         { // Устанавливаем Альфа в 0 только для красного цвета
  93.           pColor[i].rgba.alpha = 0;
  94.         }
  95.       }
  96.     }
  97.     --mnRowsRemaining;
  98.   }
  99. }
  100.  
  101. void  MyRgbaTransparency::convertColor
  102.   (Atil::ImagePixel& color) const
  103. {
  104.   ImageFilter::convertColor(color);
  105.   switch  ( color.type )
  106.   {
  107.   case  Atil::DataModelAttributes::PixelType::kRgba:
  108.     {
  109.       Atil::RgbColor rgb( color.value.rgba );
  110.       if ( rgb.rgba.red == 255
  111.         && rgb.rgba.blue == 0
  112.         && rgb.rgba.green == 0)
  113.       { // Устанавливаем Альфа в 0 только для красного цвета
  114.         rgb.packed = rgb.packed;
  115.         rgb.rgba.alpha = 0;
  116.         color.value.rgba = rgb;
  117.       }
  118.       break ;
  119.     }
  120.   }
  121. }
  122.  
  123. static bool CreateAtilImage(AcGsView *pView,
  124.                             int width, int height,
  125.                             int colorDepth, int paletteSize,
  126.                             ACHAR *pFileName)
  127. {
  128.  
  129.   // Используем фильтр
  130.   Atil::RgbModel rgbModel(Atil::RgbModelAttributes::k4Channels,
  131.     Atil::DataModelAttributes::kRedGreenBlueAlpha);
  132.   Atil::ImagePixel initialColor(Atil::DataModelAttributes::PixelType::kRgba);
  133.  
  134.   initialColor.setToZero();
  135.   initialColor.type = Atil::DataModelAttributes::kRgba;
  136.   initialColor.value.rgba = 0xff000000;
  137.   Atil::Image imgSource(Atil::Size(width, height), &rgbModel, initialColor);
  138.  
  139.   // Получаем снимок GsView
  140.  
  141.   pView->getSnapShot(&imgSource, screenRect.m_min);
  142.  
  143.   Atil::RowProviderInterface *pPipe = imgSource.read(
  144.     imgSource.size(),  Atil::Offset(0,0), Atil::kBottomUpLeftRight);
  145.  
  146.   if (pPipe != NULL)
  147.   {
  148.     Atil::RgbColor aColors[1];
  149.     COLORREF crBkg = RGB(255, 0, 0);
  150.  
  151.     aColors[0] = Atil::RgbColor(
  152.       GetRValue(crBkg),
  153.       GetGValue(crBkg & 0xffff),
  154.       GetBValue(crBkg), 0);
  155.  
  156.     pPipe = new  MyRgbaTransparency( pPipe, 1, aColors);
  157.  
  158.     if  (pPipe != NULL && pPipe->isValid())
  159.     {
  160.       TCHAR drive[_MAX_DRIVE];
  161.       TCHAR dir[_MAX_DIR];
  162.       TCHAR fname[_MAX_FNAME];
  163.       TCHAR ext[_MAX_EXT];    
  164.  
  165.       // Находим расширение
  166.       _tsplitpath_s( pFileName, drive, dir, fname, ext);
  167.  
  168.       Atil::ImageFormatCodec *pCodec = NULL;
  169.       if  (CString(ext) == _T(".png" ))
  170.         pCodec = new  PngFormatCodec();
  171.  
  172.       if  (pCodec != NULL)
  173.       {
  174.         // Оно совместимо
  175.         if  (Atil::FileWriteDescriptor::isCompatibleFormatCodec(
  176.           pCodec, &(pPipe->dataModel()),
  177.           pPipe->size()))
  178.         {
  179.           // Создаем новый выходной файл
  180.           Atil::FileWriteDescriptor fileWriter(pCodec);
  181.           Atil::FileSpecifier fs(
  182.             Atil::StringBuffer((lstrlen(pFileName)+1)
  183.             * sizeof (TCHAR),
  184.             (const  Atil::Byte *)pFileName,
  185.             Atil::StringBuffer::kUTF_16),
  186.             Atil::FileSpecifier::kFilePath);
  187.  
  188.           // Если файл уже существует
  189.           // лучше его предварительно удалить, в противном случае setFileSpecifier
  190.           // закончится с ошибкой
  191.  
  192.           _tremove(pFileName);
  193.  
  194.           if  (fileWriter.setFileSpecifier(fs))
  195.           {
  196.             fileWriter.createImageFrame(
  197.               pPipe->dataModel(),
  198.               pPipe->size());
  199.  
  200.             // Получаем свойство сжатия и меняем его на нужное нам
  201.  
  202.             Atil::FormatCodecPropertyInterface *pProp = fileWriter.getProperty(
  203.               Atil::FormatCodecPropertyInterface::kCompression);
  204.  
  205.             if  (pProp != NULL)
  206.             {
  207.               if  (CString(ext) == _T(".png" ))
  208.               {
  209.                 PngCompression *pComp = dynamic_cast <PngCompression*>(pProp);
  210.                 if  (pComp != NULL)
  211.                 {
  212.                   pComp->selectCompression(PngCompressionType::kHigh);
  213.                   fileWriter.setProperty(pComp);
  214.                 }
  215.               }
  216.  
  217.               // чистим
  218.  
  219.               delete  pProp;
  220.  
  221.               pProp = NULL;
  222.  
  223.             }
  224.  
  225.           }
  226.  
  227.           Atil::FormatCodecPropertySetIterator* pPropsIter = fileWriter.newPropertySetIterator();
  228.  
  229.           if  (pPropsIter)
  230.           {
  231.             for  (pPropsIter->start(); !pPropsIter->endOfList(); pPropsIter->step())
  232.             {
  233.               Atil::FormatCodecPropertyInterface* pProp  = pPropsIter->openProperty();
  234.               if  (pProp->isRequired())
  235.               {
  236.                 fileWriter.setProperty(pProp);
  237.               }
  238.               pPropsIter->closeProperty();
  239.             }
  240.             delete  pPropsIter;
  241.           }
  242.  
  243.           Atil::FormatCodecPropertyInterface *pTransparencyProp = fileWriter.getProperty(
  244.             Atil::FormatCodecPropertyInterface::kTransparency);
  245.           if (pTransparencyProp)
  246.           {
  247.             fileWriter.setProperty(pTransparencyProp);
  248.           }
  249.  
  250.           // Готовы записывать файл
  251.  
  252.           fileWriter.writeImageFrame(pPipe);
  253.  
  254.           done = true ;
  255.  
  256.         }
  257.  
  258.       }
  259.  
  260.       delete  pCodec;
  261.  
  262.     }
  263.  
  264.   }
  265.  
  266. }

 

Источник: http://adndevblog.typepad.com/autocad/2015/03/creating-transparent-image-using-atil.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=2579

Опубликовано 21.03.2015