C++ 使用L_SaveFileOffset保存多页TIFF文件

C++ 使用L_SaveFileOffset保存多页TIFF文件,c++,leadtools-sdk,C++,Leadtools Sdk,我需要使用 LySaveFielOffice < /COD>保存多页TIFF文件,因为我需要确保没有其他进程,包括Windows本身可以访问保存页中间的文件,而据我所知,代码> LySaveFielOffice 是唯一的保存在 LeDeaveSt>中的API,允许使用文件保存图像。手柄问题是,无论我做什么,只保存最后一页。请帮忙 HANDLE hFile = ::CreateFile(L"ColorMaps.tif", GENERIC_READ | GENERIC_WRITE, FILE_SHA

我需要使用<代码> LySaveFielOffice < /COD>保存多页TIFF文件,因为我需要确保没有其他进程,包括Windows本身可以访问保存页中间的文件,而据我所知,<>代码> LySaveFielOffice 是唯一的保存在<强> LeDeaveSt>中的API,允许使用文件保存图像。手柄问题是,无论我做什么,只保存最后一页。请帮忙

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);
}
HANDLE-hFile=::CreateFile(L“ColorMaps.tif”,GENERIC_-READ | GENERIC_-WRITE,FILE_-SHARE_-READ,NULL,CREATE_-ALWAYS,FILE_-ATTRIBUTE_-NORMAL,NULL);
如果(NULL!=hFile)
{
常量wchar_t路径模板[]={L“ColorMap%d.bmp”};
wchar_t tPath[sizeof(pathTemplate)/sizeof(pathTemplate[0]);
文件信息页面信息;
这样做;
加载文件选项tlo;
int i;
HDC-HDC;
位图句柄tBmp;
__int64-tSize;
memset(&tlo,0,sizeof(LOADFILEOPTION));
tlo.uStructSize=sizeof(LOADFILEOPTION);
L_GetDefaultLoadFileOption(&tlo,sizeof(LOADFILEOPTION));
tlo.标志|=ELO|U旋转;
hDc=::GetDC(NULL);
tlo.x分辨率=::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(位图句柄);
对于(i=1;i<7;i++)
{
::StringCbPrintf(tPath,sizeof(tPath),pathTemplate,i);
L_FileInfo(tPath、PageInfo、sizeof(FileInfo)、0和tlo);
L_LoadBitmap(tPath、tBmp、sizeof(bitmapphandle)、0、ORDER_RGBORGRAY、tlo和PageInfo);
if(左上角!=tBmp.ViewPerspective)
L_ChangeBitmapViewPerspective(NULL,&tBmp,sizeof(BITMAPHANDLE),左上角);
L_SaveFileOffset((L_HFILE)HFILE,0,&tSize,&tBmp,FILE_TIF_PACKBITS,PageInfo.BitsPerPixel,0,SAVEFILE_MULTIPAGE,NULL,NULL,&so);
so.PageNumber=i+1;
}
::闭合手柄(hFile);
}
以上只是一个示例,可能有1000页被保存到TIFF文件中

如果用户打开Windows资源管理器并导航到正在保存文件的目录,则问题会自动出现。如果我使用
L\u SaveBitmap
L\u SaveFile
,则可以看到Windows正在尝试在每次页面保存之间为文件重新绘制图标,有时他们返回-14,因为windows正在读取文件,而LeadTools无法锁定该文件

p.S.
L_SaveFileOffset
返回所有页面的1(成功),我正在使用LeadTools Documents imaging 17.5版

谢谢你

萨姆,
完全控制文件句柄的一种方法是使用重定向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_HFILE hFileMyTiff=NULL;
bool reallyClose=false;
L_HFILE EXT_回调MyOpen(L_TCHAR*pFile、L_INT nMode、L_INT nShare、L_VOID*pUserData)
{
if(!hFileMyTiff)//仅在文件尚未打开时打开该文件
hFileMyTiff=(L_HFILE)::创建文件(pFile,通用读取,通用写入,文件共享读取,NULL,创建总是,文件属性正常,NULL);
返回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);
返回dwRead;
}
L_UINT EXT_CALLBACK MyWrite(L_HFILE FD、L_UCHAR*pBuf、L_UINT uCount、L_VOID*pUserData)
{
DWORD DWWRITED=0;
::WriteFile(FD、pBuf、uCount和dwwrited,NULL);
书面回复;
}
L_-SSIZE\T EXT\u 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)
{
如果(reallyClose)
{
::闭合手柄(FD);
hFileMyTiff=NULL;
}
其他的
::SetFilePointer(FD,0,NULL,文件开始);
返回TRUE;
}
无效tst()
{
常量wchar_t路径模板[]={L“ColorMap%d.bmp”};
wchar_t tPath[sizeof(pathTemplate)/sizeof(pathTemplate[0]);
文件信息页面信息;
加载文件选项tlo;
int i;
HDC-HDC;
位图句柄tBmp;
__int64-tSize;
memset(&tlo,0,sizeof(LOADFILEOPTION));
tlo.uStructSize=sizeof(LOADFILEOPTION);
L_GetDefaultLoadFileOption(&tlo,sizeof(LOADFILEOPTION));
tlo.标志|=ELO|U旋转;
hDc=::GetDC(NULL);
tlo.x分辨率=::GetDeviceCaps(hDc,LOGPIXELSX);
tlo.YResolution=::GetDeviceCaps(hDc,LOGPIXELSY);
::ReleaseDC(NULL,hDc);
memset(&tBmp,0,sizeof(BITMAPHANDLE));
tBmp.uStructSize=sizeof(位图句柄);
对于(i=1;i<7;i++)
{
::StringCbPrintf(tPath,sizeof(tPath),pathTemplate,i);
L_FileInfo(tPath、PageInfo、sizeof(FileInfo)、0和tlo);
L_LoadBitmap(tPath、tBmp、sizeof(bitmapphandle)、0、ORDER_RGBORGRAY、tlo和PageInfo);
if(左上角!=tBmp.ViewPerspective)
L_ChangeBitmapViewPerspective(NULL,&tBmp,sizeof(BITMAPHANDLE),左上角);
if(i==6)//仅允许在保存最后一页后关闭
reallyClose=true;
其他的
reallyClose=false;
L_RedirectIO(MyOpen、MyRead、MyWrite、MySeek、MyClose、NULL);//使用我们自己的文件I/O函数
L_SaveFile(L“ColorMaps.tif”,&tBmp,FILE_tif_PACKBITS,PageInfo.BitsPerPixel,0,SaveFile_多页,NULL,NULL,NULL);
L_RedirectIO(NULL,NULL,NULL,NULL,NULL,NULL);//重置为默认I/O,以免影响加载
}
}
为了简单起见,请注意使用了2个全局变量。一种更简洁的方法可能是定义自己的数据结构,并在L_RedirectIO的pUserData参数中传递其地址。
我们测试了t