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

22/01/2014

Вставка растрового изображения с использованием буфера изображения

Можно использовать метод AcDbRasterImageDef::setImage в случае если вы не хотите указывать путь к файлу растрового изображения при вставке изображения. Это можно считать еще одним подходм для выполнения того, что объясняется в этой статье. Методу AcDbRasterImageDef::setImage требуется указатель на ATIL изображение. В этом примере кода буфер изображения читается из растрового файла и используется для создания ATIL изображения. Указатель на ATIL изображение используется методом AcDbRasterImageDef::setImage для создания определения растрового изображения. Чтобы создать arx-файл на основе этого примера необходимо включить заголовочные файлы и библиотеки из каталога ObjectARX SDK с именем "\utils\Atil".

Код - C++: [Выделить]
  1. static void AdskInsertImage(void)
  2. {
  3.     // Путь к файлу изображения для создания RasterImageDef
  4.     AcString imagePath(ACRX_T("C:\\Temp\\Test.png"));
  5.  
  6.     // Загружаем изображение для получения доступа к буферу изображения
  7.     AcTcImage tc;
  8.     tc.Load(imagePath);
  9.  
  10.     HBITMAP bmp=0;
  11.     tc.GetHBITMAP(RGB(0xff,0xff,0xff),bmp);
  12.  
  13.     if (bmp == NULL)
  14.         return;
  15.  
  16.     BITMAP _bmp = {0};
  17.     GetObject(bmp,sizeof BITMAP,&_bmp);
  18.  
  19.     HDC hdcScr = GetDC(NULL);
  20.     HDC    hdcMem = CreateCompatibleDC(hdcScr);
  21.     SelectObject(hdcMem,bmp);
  22.  
  23.     // Создаем Atil::Image.
  24.     // Его требует метод AcDbRasterImageDef::setImage
  25.     Atil::ImagePixel initialImage;
  26.     initialImage.setToZero();
  27.     initialImage.type = Atil::DataModelAttributes::kRgba;
  28.     initialImage.value.rgba = 0xff000000;
  29.  
  30.     Atil::Size size(_bmp.bmWidth, _bmp.bmHeight);
  31.     const Atil::RgbModel *pDm = new Atil::RgbModel(
  32.         Atil::RgbModelAttributes::k4Channels,
  33.         Atil::DataModelAttributes::kBlueGreenRedAlpha);
  34.  
  35.     Atil::Image *pAtilImage = new Atil::Image(
  36.                                      size, pDm, initialImage);
  37.  
  38.     // Записываем данные изображения в Atil изображение
  39.     // Используем Image Context
  40.     Atil::Offset upperLeft(0,0);
  41.     Atil::ImageContext *pImgContext
  42.         = pAtilImage->createContext(
  43.                                     Atil::ImageContext::kWrite,
  44.                                     size,
  45.                                     upperLeft
  46.                                     );
  47.     if (pImgContext != NULL)
  48.     {
  49.         for (int xf=0;xf<_bmp.bmWidth;xf++)
  50.         {
  51.             for (int yf=0;yf<_bmp.bmHeight;yf++)
  52.             {
  53.                 BYTE alpha=0x0;
  54.  
  55.                 COLORREF pix=GetPixel(hdcMem,xf,yf);
  56.  
  57.                 BYTE rr = (pix & 0xff);
  58.                 BYTE gg = (pix>>8) & 0xff;
  59.                 BYTE bb = (pix>>16) & 0xff;
  60.  
  61.                 // Альфа-канал для вычисления прозрачности
  62.                 if ((rr != 0xff) || (gg != 0xff) || (bb != 0xff))
  63.                     alpha = 0xff;
  64.  
  65.                 Atil::RgbColor p;
  66.                 p.set(rr, gg, bb, alpha);
  67.                 pImgContext->put32(xf, yf, p);
  68.             }
  69.         }
  70.  
  71.     }
  72.     pImgContext->flush();
  73.     delete pImgContext;
  74.  
  75.     bool isImageValid = pAtilImage->isValid();
  76.     ASSERT(isImageValid);
  77.  
  78.     // Создаем RasterImageDef и устанавливаем изображение на основе
  79.     // Atil изображения
  80.     AcDbRasterImageDef *pImageDef = new AcDbRasterImageDef();
  81.     Acad::ErrorStatus es = pImageDef->setImage(
  82.                                             pAtilImage, NULL);
  83.  
  84.     // Вставляем RasterImageDef и создаем RasterImage
  85.     // на его основе
  86.     es = InsertImageInDwg(pImageDef);
  87.     if(es != Acad::eOk)
  88.     {
  89.         delete pImageDef;
  90.         return;
  91.     }
  92.  
  93.     // Очищаем мусор
  94.     DeleteDC(hdcMem);
  95.     ReleaseDC(NULL,hdcScr);
  96.  
  97.     DeleteObject( bmp);
  98. }
  99.  
  100. static Acad::ErrorStatus InsertImageInDwg(
  101.                                 AcDbRasterImageDef *pImageDef)
  102. {
  103.     Acad::ErrorStatus es;
  104.     if(! pImageDef->isLoaded())
  105.     {
  106.         es = pImageDef->load();
  107.         if(es != Acad::eOk)
  108.             return es;
  109.     }
  110.  
  111.     AcApDocument *pActiveDoc = acDocManager->mdiActiveDocument();
  112.     AcDbDatabase *pDB = pActiveDoc->database();
  113.  
  114.     // Получаем словарь растров
  115.     // или создаем его если его еще нет
  116.     AcDbObjectId dictID
  117.                     = AcDbRasterImageDef::imageDictionary(pDB);
  118.     if(dictID == AcDbObjectId::kNull)
  119.     {
  120.         es = AcDbRasterImageDef::createImageDictionary(
  121.                                                   pDB, dictID);
  122.         if(es != Acad::eOk)
  123.             return es;
  124.     }
  125.  
  126.     AcDbDictionary* pDict;
  127.     es = acdbOpenObject(pDict, dictID, AcDb::kForWrite);
  128.     if(es != Acad::eOk)
  129.             return es;
  130.  
  131.     ACHAR *DICT_NAME = ACRX_T("ISM_RASTER_IMAGE_DICT_VIEW");
  132.     BOOL bExist = pDict->has(DICT_NAME);
  133.     AcDbObjectId objID = AcDbObjectId::kNull;
  134.     if (!bExist)
  135.     {
  136.         es = pDict->setAt(DICT_NAME, pImageDef, objID);
  137.         if(es != Acad::eOk)
  138.             return es;
  139.     }
  140.     else
  141.     {
  142.         pDict->getAt(DICT_NAME,
  143.                     (AcDbObject*&)pImageDef,
  144.                     AcDb::kForWrite);
  145.         objID = pImageDef->objectId();
  146.     }
  147.  
  148.     // Закрываем словарь и RasterImageDef.
  149.     pDict->close();
  150.     pImageDef->close();
  151.  
  152.     // Создаем RasterImage на основе RasterImageDef
  153.     AcDbRasterImage* pImage = new AcDbRasterImage;
  154.     es = pImage->setImageDefId(objID);
  155.     if (es != Acad::eOk)
  156.     {
  157.         delete pImage;
  158.         return es;
  159.     }
  160.  
  161.     // Добавляем растр к пространству Модели
  162.     AcDbBlockTable* pBlockTable;
  163.     AcDbBlockTableRecord* pBTRecord;
  164.     es = acdbCurDwg()->getBlockTable(pBlockTable,
  165.                                      AcDb::kForRead);
  166.     assert(es == Acad::eOk);
  167.     es = pBlockTable->getAt(ACDB_MODEL_SPACE,
  168.                             pBTRecord,
  169.                             AcDb::kForWrite);
  170.     assert(es == Acad::eOk);
  171.  
  172.     es = pBTRecord->appendAcDbEntity(pImage);
  173.     assert(es == Acad::eOk);
  174.  
  175.     pBTRecord->close();
  176.     pBlockTable->close();
  177.  
  178.     AcDbObjectId entID = pImage->objectId();
  179.  
  180.     // Устанавливаем свойство прозрачности
  181.     pImage->setDisplayOpt(    AcDbRasterImage::kTransparent,
  182.                             Adesk::kTrue);
  183.  
  184.     pImage->setImageTransparency(true);
  185.     pImage->setDisplayOpt(AcDbRasterImage::kShow, Adesk::kTrue);
  186.  
  187.     AcDbObjectPointer<AcDbRasterImageDefReactor>
  188.                                         rasterImageDefReactor;
  189.     rasterImageDefReactor.create();
  190.  
  191.     es = rasterImageDefReactor->setOwnerId(pImage->objectId());
  192.     if (es == Acad::eOk)
  193.     {
  194.         AcDbObjectId defReactorId;
  195.         es = curDoc()->database()->addAcDbObject(
  196.                             defReactorId,
  197.                             rasterImageDefReactor.object());
  198.  
  199.         if (es == Acad::eOk)
  200.         {
  201.             pImage->setReactorId(defReactorId);
  202.             AcDbObjectPointer<AcDbRasterImageDef> rasterImagedef
  203.                       (pImage->imageDefId(), AcDb::kForWrite);
  204.             if (rasterImagedef.openStatus() == Acad::eOk)
  205.             {
  206.                 rasterImagedef->addPersistentReactor
  207.                                                (defReactorId);
  208.             }
  209.         }
  210.     }
  211.  
  212.     pImageDef->close();
  213.     pImage->close();
  214. }

 

Источник: http://adndevblog.typepad.com/autocad/2013/11/inserting-rasterimage-using-image-buffer.html

 

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

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