|
[code]// by Fenton Webb, DevTech, 1/30/2013
// screen shoots the view details as a BMP
bool RecordViewDetails(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<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);
// if not
if (NULL == pView)
{
// then we must be in 2D wireframe mode, so use acgsGetScreenShot
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<char*>(pSnapshotData),
nBufferSize, nBytesPerRow, w, h, 32, 0);
std::auto_ptr<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage); // auto_ptr now owns the image
if (!writeImageFile(pImage, kBMP, imagePath))
{
acutPrintf(_T("\nFailed to write image file %s"), imagePath);
return false;
}
else
acutPrintf(_T("\nSuccessfully written %s"), imagePath);
}
return true;
}
else
{
return snapGSView(pView, iImageWidth, iImageHeight, fieldHeight, fieldWidth, position, target, upVector, imagePath);
}
}
bool snapGSView(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<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<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage); // auto_ptr now owns the image
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, kBMP, 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;
}
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;
}
}
// get the current vp
int getCVPort()
{
struct resbuf rb;
ads_getvar(_T("CVPORT"), &rb);
return rb.resval.rint;
}
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[i], 255);
pPM->setEntries(0, 256, (Atil::RgbColor *)&space);
} else
pDm = new Atil::RgbModel(32);
_ASSERT(NULL != pDm);
return pDm;
}
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;
}
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;
}[/code] |
|