Тема: Переход с IeImg на Atil

Помогите разобратся – как используя Atil узнать RGB пикселя изображения загруженого в акад. Делаю так:
#include "AtilDefs.h"
#include "Image.h"
#include "RowProviderInterface.h"
#include "DataBuffer.h"
. . . . .
ads_name ss;
ads_point p1,p2;
ACHAR * prompt[2];
ACHAR *st1=_T("Выберите рисунок для обработки:");
ACHAR *st2=_T("");
prompt[0]=st1;
prompt[1]=st2;
if(acedSSGet(_T("_:$"),prompt,NULL,NULL,ss)!=RTNORM)
return;
ads_name en1;
AcDbObjectId id1;
acedSSName(ss,0,en1);
acdbGetObjectId(id1,en1);
AcDbObjectPointer<AcDbObject> pObjS(id1,AcDb::kForRead);
if(_tcscmp(pObjS->isA()->name(),_T("AcDbRasterImage")))
{MessageBox(GetFocus(),_T("Выбранный объект не является растровым изображением!"),_T("Ошибка выбора растра"),MB_OK|MB_ICONERROR);pObjS->close();return;}
pObjS->close();acedSSFree(ss);       
AcDbObjectPointer<AcDbRasterImage> pRImg(id1,AcDb::kForRead);
pRImg->imageDefId();
AcDbObjectPointer<AcDbRasterImageDef> pImgDef(pRImg->imageDefId(),AcDb::kForRead);
pRImg->close();
Atil::RowProviderInterface *row;
Atil::Size *size1=new Atil::Size(100,100);
Atil::Offset *offset1=new Atil::Offset(0,0);
Atil::Image *iii=pImgDef->imageCopy();
pImgDef->close();
row=iii->read(*size1,*offset1);
Atil::DataBuffer *data1=new Atil::DataBuffer(10);
На последней строчке ошыбка:
acrxEntryPoint.obj : error LNK2019: unresolved external symbol "public: __thiscall Atil::DataBuffer::DataBuffer(int)" (??0DataBuffer@Atil@@QAE@H@Z) referenced in function "public: static void __cdecl CArxProject111App::Dp28ArxProject111_a(void)" (?Dp28ArxProject111_a@CArxProject111App@@SAXXZ)
Ну и как дальше?
row->getNextRow(*data1);?
AutoCAD Civil 3D 2008 B.51.0 (UNICODE)
ARX08x32

Re: Переход с IeImg на Atil

> Bleach
Подключи AdImaging.lib к проекту.

Re: Переход с IeImg на Atil

> Bleach
Кстати, мне эти переходы надоели очень быстро, особенно как представил, что это может и повториться. Выход я нашел при помощи gdiplus.h
Средствами акада получаешь растр, точку(X,Y) растра или еще что тебе нужно а дальше работает библиотека GDIPlus (кстати она поставляется вместе со студией, так что ничего искать не прийдется). Не знаю поможет мой пост или нет, но это очень неплохая альтернатива.

Re: Переход с IeImg на Atil

> Александр Ривилис
Имелось ввиду в options\vc++ directories Library files задать путь к папка_арх08\Atil\Lib?
Задано.

> Николай
"Средствами акада получаешь растр, точку(X,Y) растра" - до акада 08 точку растра загруженого в акад (ну если не отслеживать путь и самому не работать с файлом с диска..) можно было получить только используя IeImg. В 08 кроме atil других путей не нашёл...

Re: Переход с IeImg на Atil

Александр Ривилис (2007-11-05 21:16:58)    

> Bleach
Подключи AdImaging.lib к проекту.
Упс. Неправильно понял пост. Подключил в Project properties->Linker->Additional Dependencies - скомпилировалось. Спасибо

Re: Переход с IeImg на Atil

Ну почему, ни атил, ни IESDK не нужны для того чтоб получить реальные (X,Y) растра.

...
ads_name entImage; ads_point p;
AcDbRasterImage * pImage;        
AcDbObjectId eId;
AcGeVector3d n1,n2;
// выбираем рисунок
while (TRUE)
{
 switch (acedEntSel(_T("\nУкажите растровое изображение: "), entImage, p))
 {
  case RTCAN :
   return;
  case RTERROR :
   continue;
  case RTNORM :
   if (acdbGetObjectId(eId,entImage) != Acad::eOk) return;        
   if (acdbOpenObject(pImage, eId, AcDb::kForRead) != Acad::eOk) return;
   if (pImage == NULL) continue;
   pImage->close();
   break;
 }
}
// получаем имя файла
AcDbObjectPointer<AcDbRasterImageDef> pDef(pImage->imageDefId(),AcDb::kForWrite);
if (pDef.openStatus() != Acad::eOk) return;
ACHAR FILENAME[1024]=_T("");
strcpy(FILENAME,pDef->activeFileName());// или wcscpy для VS2005
// дальше клацаем по экрану над рисунком и получаем координату в МСК
// описывать не буду это можно и самому.
AcGePoint3d MyTP; // <- запишем ее сюда
// а теперь самое интересное :)
// получаем точку растра (X,Y)
AcGeMatrix3d mat;
pImage->getPixelToModelTransform(mat);
AcGeMatrix3d mat_inverse = mat.inverse();
MyTP = mat_inverse*MyTP; //<- теперь в MyPT хранятся координаты рисунка

В итоге у нас есть имя файла FILENAME и точка файла MyPT и все это без помощи IESDK или Atil.
А дальше работает GDIPlus :)
PS: Кстати, пример на работоспособность не проверял, т.к. выбирал интересующие куски из своего кода. Может нехватать какой-то переменной. Хотя на первый взгляд должно работать.

Re: Переход с IeImg на Atil

А чуть не забыл, GDIPlus не считывает полностью файл в память без необходимости, а просто бинарно ищет ту точку какую ей указать. И работает это все в куче проыентов на 20-30 быстрее чем IESDK. Увы на Atil не проверял.

Re: Переход с IeImg на Atil

> Николай
Спасибо за ответ. Но работу с изображением (используя путь к файлу) не Autodesk граф. библиотеками (пробовал CxImage) отверг, так как:
1)    размер обрабатываемых файлов больше 100 Мб (как правило ~350 Мб) и все точки изображения должны быть обработаны – перерасход памяти
2)    при таком подходе надо разбиратся со всеми форматами и кодеками граф. файлов, поддерживаемых акадом

Re: Переход с IeImg на Atil

CxImage мне тоже не понравился :)
По поводу форматов файлов, то GDI работает с основными и наиболее часто используемыми: bmp, jpg, png, tif Не думаю, что еще кто-то использует pcx или pct :)
А по поводу размера файлов, так я и говорю, что GDIPlus быстрее.
Тестирование на примере, правда размер файла был поменьше :) :
- две команды. Одна с использованием IESDK, вторая с GDIPlus
- файл 1000x2000 точек.
- задание пробежать по всем точкам и инвертировать цвет.
- отобразить результат.
IESDK около 45 секунд.
GDIPlus около 35 секунд.

Re: Переход с IeImg на Atil

> Николай
Мда. Есть над чем подумать.
Но сечас буду использовать Atil. Потому что остро стоит проблема нехватки памяти:
https://www.caduser.ru/forum/topic38534.html

Re: Переход с IeImg на Atil

Может кому пригодится. RGB первых 5х5 точек изображения:
//pImgDef - AcDbObjectPointer<AcDbRasterImageDef>
const long wX=5;const long wY=5;
Atil::Size *size1=new Atil::Size(wX,wY);
Atil::Offset *offset1=new Atil::Offset(0,0);
Atil::Image *iii=pImgDef->imageCopy();
pImgDef->close();
Atil::RowProviderInterface *row;
row=iii->read(*size1,*offset1);
Atil::DataBuffer *data1=new Atil::DataBuffer(row->bytesPerRow());
unsigned char *pBuf=data1->dataPtr();
int i,q;
for(q=0;q<wY;q++)
{
   row->getNextRow(*data1);
   for(i=0;i<wX*4;)
   {
    acutPrintf(_T("\n(%i:%i)- R:%i G:%i B:%i"),(int)i/4,q,pBuf[i],pBuf[i+1],pBuf[i+2]);
    i+=4;
   }
}