使用L_SaveFileOffset保存多页TIFF文件

时间:2015-12-22 23:24:11

标签: c++ leadtools-sdk

我需要使用L_SaveFileOffset保存多页TIFF文件,因为我需要确保包括Windows本身在内的其他进程无法在保存页面的过程中访问该文件,据我所知{{1 }}是保存在 LeadTools 中的唯一API,允许使用文件句柄保存图像。问题是,无论我做什么,只保存最后一页。请帮助。

L_SaveFileOffset

以上只是一个示例,可能会有1000个页面保存到TIFF文件中。

问题表明,如果用户打开 Windows资源管理器并导航到保存文件的目录,您可以看到窗口正在尝试重新绘制每个页面之间文件的图标保存,如果我使用HANDLE hFile = ::CreateFile(L"ColorMaps.tif", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL != hFile) { const wchar_t pathTemplate[] = {L"ColorMap%d.bmp"}; wchar_t tPath[sizeof(pathTemplate) / sizeof(pathTemplate[0])]; FILEINFO PageInfo; SAVEFILEOPTION so; LOADFILEOPTION tlo; int i; HDC hDc; BITMAPHANDLE tBmp; __int64 tSize; memset(&tlo, 0, sizeof(LOADFILEOPTION)); tlo.uStructSize = sizeof(LOADFILEOPTION); L_GetDefaultLoadFileOption(&tlo, sizeof(LOADFILEOPTION)); tlo.Flags |= ELO_ROTATED; hDc = ::GetDC(NULL); tlo.XResolution = ::GetDeviceCaps(hDc, LOGPIXELSX); tlo.YResolution = ::GetDeviceCaps(hDc, LOGPIXELSY); ::ReleaseDC(NULL, hDc); memset(&so, 0, sizeof(SAVEFILEOPTION)); so.uStructSize = sizeof(SAVEFILEOPTION); so.Flags = ESO_INSERTPAGE; memset(&tBmp, 0, sizeof(BITMAPHANDLE)); tBmp.uStructSize = sizeof(BITMAPHANDLE); for(i = 1; i < 7; i++) { ::StringCbPrintf(tPath, sizeof(tPath), pathTemplate, i); L_FileInfo(tPath, &PageInfo, sizeof(FILEINFO), 0, &tlo); L_LoadBitmap(tPath, &tBmp, sizeof(BITMAPHANDLE), 0, ORDER_RGBORGRAY, &tlo, &PageInfo); if (TOP_LEFT != tBmp.ViewPerspective) L_ChangeBitmapViewPerspective(NULL, &tBmp, sizeof(BITMAPHANDLE), TOP_LEFT); L_SaveFileOffset((L_HFILE)hFile, 0, &tSize, &tBmp, FILE_TIF_PACKBITS, PageInfo.BitsPerPixel, 0, SAVEFILE_MULTIPAGE, NULL, NULL, &so); so.PageNumber = i + 1; } ::CloseHandle(hFile); } L_SaveBitmap,有时他们会返回 -14 ,因为Windows正在读取文件而 LeadTools 无法锁定它。

P.S。 L_SaveFile为所有网页返回 1 SUCCESS ),我正在使用 LeadTools文档映像版本17.5

谢谢

1 个答案:

答案 0 :(得分:0)

山姆,
完全控制文件句柄的一种方法是使用重定向的IO。锁定整个6页的TIFF文件所需的代码将是这样的:

// 2 global variables
L_HFILE hFileMyTiff = NULL;
bool reallyClose = false;
L_HFILE EXT_CALLBACK MyOpen(L_TCHAR* pFile, L_INT nMode, L_INT nShare, L_VOID* pUserData)
{
   if(!hFileMyTiff) //only open the file if it's not already open
      hFileMyTiff = (L_HFILE)::CreateFile(pFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
   return hFileMyTiff;
}
L_UINT EXT_CALLBACK MyRead(L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID *pUserData)
{
   DWORD dwRead = 0;
   ::ReadFile(FD, pBuf, uCount, &dwRead, NULL);
   return dwRead;
}
L_UINT EXT_CALLBACK MyWrite(L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID* pUserData)
{
   DWORD dwWritten = 0;
   ::WriteFile(FD, pBuf, uCount, &dwWritten, NULL);
   return dwWritten;
}
L_SSIZE_T EXT_CALLBACK MySeek(L_HFILE FD, L_SSIZE_T nPos, L_INT nOrigin, L_VOID* pUserData)
{
   return ::SetFilePointer(FD, nPos, NULL, nOrigin);
}
L_INT EXT_CALLBACK MyClose (L_HFILE FD, L_VOID* pUserData)
{
   if(reallyClose)
   {
      ::CloseHandle(FD);
      hFileMyTiff = NULL;
   }
   else
      ::SetFilePointer(FD, 0, NULL, FILE_BEGIN);
   return TRUE;
}
void tst()
{
   const wchar_t pathTemplate[] = {L"ColorMap%d.bmp"};
   wchar_t tPath[sizeof(pathTemplate) / sizeof(pathTemplate[0])];
   FILEINFO PageInfo;
   LOADFILEOPTION tlo;
   int i;
   HDC hDc;
   BITMAPHANDLE tBmp;
   __int64 tSize;

   memset(&tlo, 0, sizeof(LOADFILEOPTION));
   tlo.uStructSize = sizeof(LOADFILEOPTION);
   L_GetDefaultLoadFileOption(&tlo, sizeof(LOADFILEOPTION));
   tlo.Flags |= ELO_ROTATED;
   hDc = ::GetDC(NULL);
   tlo.XResolution = ::GetDeviceCaps(hDc, LOGPIXELSX);
   tlo.YResolution = ::GetDeviceCaps(hDc, LOGPIXELSY);
   ::ReleaseDC(NULL, hDc);

   memset(&tBmp, 0, sizeof(BITMAPHANDLE));
   tBmp.uStructSize = sizeof(BITMAPHANDLE);
   for(i = 1; i < 7; i++)
   {
      ::StringCbPrintf(tPath, sizeof(tPath), pathTemplate, i);
      L_FileInfo(tPath, &PageInfo, sizeof(FILEINFO), 0, &tlo);
      L_LoadBitmap(tPath, &tBmp, sizeof(BITMAPHANDLE), 0, ORDER_RGBORGRAY, &tlo, &PageInfo);
      if (TOP_LEFT != tBmp.ViewPerspective)
         L_ChangeBitmapViewPerspective(NULL, &tBmp, sizeof(BITMAPHANDLE), TOP_LEFT);

      if(i==6) //only allow closing after the last page is saved
         reallyClose = true;
      else
         reallyClose = false;
      L_RedirectIO(MyOpen, MyRead, MyWrite, MySeek, MyClose, NULL); //use our own file I/O functions
      L_SaveFile(L"ColorMaps.tif", &tBmp, FILE_TIF_PACKBITS, PageInfo.BitsPerPixel, 0, SAVEFILE_MULTIPAGE, NULL, NULL, NULL);
      L_RedirectIO(NULL, NULL, NULL, NULL, NULL, NULL); //reset to default I/O so as not affect loading
   }
}

为简单起见,请注意使用2个全局变量。更简洁的方法可能是定义您自己的数据结构并将其地址传递给L_RedirectIO的pUserData参数。
我们已经使用v17.5对此解决方案进行了测试,并验证了它是否正常运行。如果它不适合您的特定情况,请联系LEADTOOLS支持服务,我们将讨论其他替代方案。

更新:LEADTOOLS v19的最新版本现在支持使用L_SaveFileOffset()函数将页面附加到TIFF文件。