- 积分
- 31055
- 明经币
- 个
- 注册时间
- 2007-4-24
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 gzxl 于 2025-8-18 16:02 编辑
这两期属于搬砖形式 ,使用 ObjectARX Atil 工具屏幕截图
以前见到一个有意思的贴子,不想让贴子沉没。
http://adndevblog.typepad.com/au ... sing-objectarx.html
包含目录
D:\ObjectARXSDK\ObjectARX 2025\utils\Atil\Inc
D:\ObjectARXSDK\ObjectARX 2025\utils\Atil\Inc\format_codecs
D:\ObjectARXSDK\ObjectARX 2025\utils\Atil\Inc\codec_properties
库目录
D:\ObjectARXSDK\ObjectARX 2025\utils\Atil\Lib-x64
头文件:
#include "AtilDefs.h"
#include "Image.h"
#include "RgbModel.h"
#include "RgbPaletteModel.h"
#include " ngCustomProperties.h"
#include "BitonalModel.h"
#include "atilformats.h"
#include "JFIFFormatCodec.h"
#include "TiffFormatCodec.h"
#include "TiffCustomProperties.h"
#include "BmpFormatCodec.h"
#include "FileSpecifier.h"
#include "FileWriteDescriptor.h"
#include "FileReadDescriptor.h"
#include "RowProviderInterface.h"
项目依赖项
#pragma comment (lib ,"AdImaging.lib")
#pragma comment (lib ,"AdIntImgServices.lib")
enum eFormatType
{
kJPG,
kPNG,
kTIF,
kBMP
};
 - /*
- bool bSuccess = false;
- eFormatType formatType = kJPG;
- wchar_t const *pFileName = NULL;
- double fieldWidth = 800.0, fieldHeight = 600.0;
- AcGePoint3d position, target;
- AcGeVector3d upVector(AcGeVector3d::kZAxis);
- pFileName = _T("C:\\temp\\atil.bmp");
- bSuccess = RecordViewDetails(kBMP, fieldWidth, fieldHeight, position, target, upVector, pFileName);
- pFileName = _T("C:\\temp\\atil.png");
- bSuccess = RecordViewDetails(kPNG, fieldWidth, fieldHeight, position, target, upVector, pFileName);
- pFileName = _T("C:\\temp\\atil.jpg");
- bSuccess = RecordViewDetails(kJPG, fieldWidth, fieldHeight, position, target, upVector, pFileName);
- */
- AcGePoint3d pt1, pt2;
- if (RTNORM != acedGetPoint(NULL, _T("\n拾取屏幕截图左下角点:"), asDblArray(pt1)))
- return;
- if (RTNORM != acedGetCorner(asDblArray(pt1), _T("\n拾取屏幕截图右上角点:"), asDblArray(pt2)))
- return;
- double fieldWidth = fabs(pt2.x - pt1.x);
- double fieldHeight = fabs(pt2.y - pt1.y);
- AcGePoint3d target;
- AcGeVector3d upVector(AcGeVector3d::kZAxis);
- AcApDocument *pDoc = acDocManager->curDocument();
- CString file = pDoc->fileName();
- int nPosDot = file.ReverseFind('.');
- CString csFileNameWithoutExt = file.Left(nPosDot);
- acedInitGet(0, _T("A B C"));
- ACHAR kword[255];
- int res = acedGetKword(_T("输出图像类型[bmp(A)/png(B)/jpg(C)]:"), kword);
- if (res == RTNORM)
- {
- if (_tcscmp(kword, _T("A")) == 0)
- {
- CString pFileName = csFileNameWithoutExt + _T(".bmp");
- RecordViewDetails(kBMP, fieldWidth, fieldHeight, pt1, target, upVector, pFileName);
- }
- else if (_tcscmp(kword, _T("B")) == 0)
- {
- CString pFileName = csFileNameWithoutExt + _T(".png");
- RecordViewDetails(kBMP, fieldWidth, fieldHeight, pt1, target, upVector, pFileName);
- }
- else if (_tcscmp(kword, _T("C")) == 0)
- {
- CString pFileName = csFileNameWithoutExt + _T(".jpg");
- RecordViewDetails(kBMP, fieldWidth, fieldHeight, pt1, target, upVector, pFileName);
- }
- else
- {
- acutPrintf(_T("无效的输入\n"));
- }
- }
// get the current vp
static int getCVPort()
{
struct resbuf rb;
ads_getvar(_T("CVPORT"), &rb);
return rb.resval.rint;
}
static Atil::DataModel* colorSpace(char *&pRGBData, int colorDepth, int paletteSize)
{
_ASSERT(NULL != pRGBData);
// Setup a color space, with palette if needed
Atil::DataModel *pDm = NULL;
if (colorDepth == 8)
{
Atil::RgbColor space[256];
Atil::RgbPaletteModel *pPM = new Atil::RgbPaletteModel();
_ASSERT(NULL != pPM);
if (!pPM)
return NULL;
pDm = pPM;
char *palette = pRGBData;
pRGBData += paletteSize;
for (int i = 0; i < paletteSize; i += 4)
space[i / 4] = Atil::RgbColor(palette[i + 2], palette[i + 1], palette, 255);
pPM->setEntries(0, 256, (Atil::RgbColor *)&space);
}
else
pDm = new Atil::RgbModel(32);
_ASSERT(NULL != pDm);
return pDm;
}
static Atil::Image *constructAtilImg(char *pRGBData, unsigned long bufferSize, unsigned long rowBytes, unsigned long xSize, unsigned long ySize, int colorDepth, int paletteSize)
{
if ((8 != colorDepth) && (32 != colorDepth))
{
return NULL;
}
if (paletteSize)
{
if ((paletteSize < 0) || (paletteSize > 255))
{
return NULL;
}
}
if ((xSize <= 0) || (ySize <= 0))
{
return NULL;
}
Atil::Image *pImg = NULL;
Atil::Size size(xSize, ySize);
// construct the Atil::Image object
if (pRGBData)
{
// Check the buffer for size and definition
if (bufferSize)
{
if (!rowBytes)
{
return NULL;
}
// did they allocate enough?
if (rowBytes * ySize > bufferSize)
{
return NULL;
}
}
else
{
return NULL;
}
Atil::DataModel *pM = colorSpace(pRGBData, colorDepth, paletteSize);
_ASSERT(NULL != pM);
if (NULL == pM)
return NULL;
try
{
// BEWARE: pRGBData may be moved in colorSpace
pImg = new Atil::Image(pRGBData, bufferSize, rowBytes, size, pM);
}
catch (Atil::ATILException* pExpCon)
{
// image construction failure
delete pExpCon;
delete pM;
pImg = NULL;
_ASSERT(FALSE);
return NULL;
}
delete pM;
}
else
{
Atil::RgbModel rgbM(32);
Atil::RgbGrayModel gM;
Atil::ImagePixel initialColor(colorDepth == 32 ? Atil::DataModelAttributes::kRgba : Atil::DataModelAttributes::kGray);
initialColor.setToZero();
try
{
pImg = new Atil::Image(size, colorDepth == 32 ? &rgbM : &gM, initialColor);
}
catch (Atil::ATILException* pExpCon)
{
// image construction failure
delete pExpCon;
pImg = NULL;
_ASSERT(FALSE);
return NULL;
}
}
_ASSERT(NULL != pImg);
return pImg;
}
static bool writeImageFile(Atil::Image *pImageSource, eFormatType formatType, wchar_t const *pFileName)
{
_ASSERT(NULL != pImageSource);
if (NULL == pImageSource)
return false;
_ASSERT(pImageSource->isValid());
if (!pImageSource->isValid())
return false;
if (PathFileExists(pFileName))
DeleteFile(pFileName);
/*if(PathFileExists(pFileName))
{
if(IsFileReadOnly(pFileName))
{
RemoveReadonlyAttribute(pFileName);
DeleteFile(pFileName);
}
}*/
if (PathFileExists(pFileName))
return false;
Atil::RowProviderInterface* pPipe = pImageSource->read(pImageSource->size(),
Atil::Offset(0, 0));
_ASSERTE(NULL != pPipe);
if (!pPipe)
return false;
Atil::FileWriteDescriptor *pFWD = NULL;
Atil::ImageFormatCodec *pCodec = NULL;
if (formatType == kJPG)
pCodec = new JfifFormatCodec();
else if (formatType == kPNG)
pCodec = new PngFormatCodec();
else if (formatType == kTIF)
pCodec = new TiffFormatCodec();
else if (formatType == kBMP)
pCodec = new BmpFormatCodec();
_ASSERTE(NULL != pCodec);
if (NULL == pCodec)
return false;
if (!Atil::FileWriteDescriptor::isCompatibleFormatCodec(pCodec, &(pPipe->dataModel()), pPipe->size()))
{
delete pCodec;
return false;
}
pFWD = new Atil::FileWriteDescriptor(pCodec);
_ASSERTE(NULL != pFWD);
#ifdef UNICODE
#ifndef _ADESK_MAC_
Atil::FileSpecifier fs(Atil::StringBuffer((lstrlen(pFileName) + 1) * sizeof(TCHAR),
(const Atil::Byte *) pFileName, Atil::StringBuffer::kUTF_16),
Atil::FileSpecifier::kFilePath);
#else
Atil::FileSpecifier fs(Atil::StringBuffer((lstrlen(pFileName) + 1) * sizeof(TCHAR),
(const Atil::Byte *) pFileName, Atil::StringBuffer::kUTF_32),
Atil::FileSpecifier::kFilePath);
#endif
#else
Atil::FileSpecifier fs(Atil::StringBuffer(lstrlen(pFileName) + 1,
(const Atil::Byte *) pFileName, Atil::StringBuffer::kASCII),
Atil::FileSpecifier::kFilePath);
#endif
if (!pFWD->setFileSpecifier(fs))
return false;
pFWD->createImageFrame(pPipe->dataModel(), pPipe->size());
if (formatType == kPNG)
{
Atil::FormatCodecPropertyInterface* pProp = pFWD->getProperty(Atil::FormatCodecPropertyInterface::kCompression);
if (pProp != NULL)
{
PngCompression* pPngComp = (PngCompression*)(pProp);
if (pPngComp != NULL)
{
// Why not compress all we can?
pPngComp->selectCompression(PngCompressionType::kHigh);
pFWD->setProperty(pPngComp);
}
delete pProp;
pProp = NULL;
}
}
else if (formatType == kTIF)
{
Atil::FormatCodecPropertyInterface* pProp = pFWD->getProperty(Atil::FormatCodecPropertyInterface::kCompression);
if (pProp != NULL)
{
TiffCompression* pComp = (TiffCompression*)(pProp);
if (pComp != NULL)
{
// G4 is only valid for 1 bit images.
if (pComp->selectCompression(TiffCompressionType::kCCITT_FAX4) == false)
{
// So if that fails, resort to LZW now that it is patent free
if (pComp->selectCompression(TiffCompressionType::kLZW) == false)
{
// If that fails (and is shouldn't, be) then set none.
pComp->selectCompression(TiffCompressionType::kNone);
}
}
pFWD->setProperty(pComp);
}
delete pProp;
pProp = NULL;
}
}
//TB141111 this was missing:
int iRet = pFWD->writeImageFrame(pPipe);
delete pFWD;
pFWD = NULL;
return true;
}
static bool snapGSView(eFormatType fmt, AcGsView *pView, int width, int height, double &fieldWidth,
double &fieldHeight, AcGePoint3d &position, AcGePoint3d &target, AcGeVector3d &upVector, const TCHAR *imagePath)
{
Atil::Size size(width, height);
int nBytesPerRow = Atil::DataModel::bytesPerRow(width, Atil::DataModelAttributes::k32);
unsigned long nBufferSize = height * nBytesPerRow;
// Create an ATIL image for accepting the rendered image.
//std::auto_ptr apCharBuffer = std::auto_ptr(new char[nBufferSize]);
std::auto_ptr<char> apCharBuffer = std::auto_ptr<char>(new char[nBufferSize]);
char *pSnapshotData = apCharBuffer.get(); // auto_ptr still owns the buffer.
// in shaded mode (from GS)
Atil::Image * pImage = NULL;
pImage = constructAtilImg(pSnapshotData, nBufferSize, nBytesPerRow, width, height, 32, 0);
//std::auto_ptr autodeleter = std::auto_ptr(pImage); // auto_ptr now owns the image
std::auto_ptr<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage);
pView->getSnapShot(pImage, AcGsDCPoint(0, 0));
// add a temp image to invert the image. do we have a better way to turn an image around?
Atil::Image imgTempForInverted(pImage->read(pImage->size(), Atil::Offset(0, 0), Atil::kBottomUpLeftRight));
*pImage = imgTempForInverted;
if (!writeImageFile(pImage, fmt, imagePath))
{
acutPrintf(_T("\nFailed to write image file %s"), imagePath);
return false;
}
else
acutPrintf(_T("\nSuccessfully written %s"), imagePath);
// record the view data
fieldHeight = pView->fieldHeight();
fieldWidth = pView->fieldWidth();
position = pView->position();
target = pView->target();
upVector = pView->upVector();
return true;
}
static bool getTempImgFile(TCHAR * fileName)
{
// Here we create a temp bmp file as a transitional file
TCHAR tempDic[MAX_PATH];
::memset(tempDic, 0, MAX_PATH);
DWORD nRetSize = ::GetTempPath(MAX_PATH, tempDic);
if (nRetSize > MAX_PATH || nRetSize == 0)
{
const TCHAR * tempStr = _T("C:\\temp");
if (wcscpy_s(tempDic, tempStr) != 0)
{
return false;
}
if (::PathFileExists(tempStr) == FALSE && ::CreateDirectory(tempStr, NULL) == FALSE)
{
return false;
}
}
// create the temp file whose prefix is "img"
if (::GetTempFileName(tempDic, _T("tmp"), 0, fileName) == 0)
{
return false;
}
// now split the filepath into its individual components
TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
_tsplitpath(fileName, drive, dir, fname, ext);
_stprintf(fileName, _T("%s%s%s.bmp"), drive, dir, fname);
return true;
}
// by Fenton Webb, DevTech, 1/30/2013
// screen shoots the view details as a BMP
static bool RecordViewDetails(eFormatType fmt, double &fieldWidth, double &fieldHeight, AcGePoint3d &position, AcGePoint3d &target, AcGeVector3d &upVector, const TCHAR *imagePath)
{
int iVP = getCVPort();
// Compute the viewport dimensions.
int nLeft, nBottom, nRight, nTop;
int iImageWidth, iImageHeight;
acgsGetViewportInfo(iVP, nLeft, nBottom, nRight, nTop);
iImageWidth = nRight - nLeft + 1;
iImageHeight = nTop - nBottom + 1;
Atil::Size size(iImageWidth, iImageHeight);
int nBytesPerRow = Atil::DataModel::bytesPerRow(iImageWidth,
Atil::DataModelAttributes::k32);
unsigned long nBufferSize = iImageHeight * nBytesPerRow;
// Create an ATIL image for accepting the rendered image.
//std::auto_ptr autoBuff = std::auto_ptr(new char[nBufferSize]);
std::auto_ptr<char> autoBuff = std::auto_ptr<char>(new char[nBufferSize]);
char *pSnapshotData = autoBuff.get();
Atil::Image * pImage = NULL;
// see if there is a GS view created
//AcGsView *pView = acgsGetGsView(iVP, false);
resbuf cvport;
acedGetVar(L"CVPORT", &cvport);
AcGsView *pView = acgsGetCurrent3dAcGsView(cvport.resval.rint);
// if not
if (NULL == pView)
{
// then we must be in 2D wireframe mode, so use acgsGetScreenShot
//std::auto_ptr autoScreenShot(acgsGetScreenShot(iVP));
std::auto_ptr<AcGsScreenShot> autoScreenShot(acgsGetScreenShot(iVP));
AcGsScreenShot* screenShot = autoScreenShot.get(); // auto_ptr still owns the pointer.
if (screenShot)
{
int w = 0, h = 0, d = 0;
screenShot->getSize(w, h, d);
char* pBufTemp = pSnapshotData;
for (int row = 0; row < h; row++)
{
memcpy(pBufTemp, screenShot->getScanline(0, row), nBytesPerRow);
// convert from RGBA to BGRA
char* pColor = pBufTemp;
for (int i = 0; i < w; i++) // Slow but it works
{
char temp = *pColor;
*pColor = *(pColor + 2);
*(pColor + 2) = temp;
pColor += 4;
}
pBufTemp += nBytesPerRow;
}
//pImage = constructAtilImg(reinterpret_cast(pSnapshotData), nBufferSize, nBytesPerRow, w, h, 32, 0);
pImage = constructAtilImg(reinterpret_cast<char*>(pSnapshotData),
nBufferSize, nBytesPerRow, w, h, 32, 0);
//std::auto_ptr autodeleter = std::auto_ptr(pImage); // auto_ptr now owns the image
std::auto_ptr<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage);
if (!writeImageFile(pImage, fmt, imagePath))
{
acutPrintf(_T("\nFailed to write image file %s"), imagePath);
return false;
}
else
acutPrintf(_T("\nSuccessfully written %s"), imagePath);
}
return true;
}
else
{
return snapGSView(fmt, pView, iImageWidth, iImageHeight, fieldHeight, fieldWidth, position, target, upVector, imagePath);
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|