SetMetadataByName失败,错误0x88982F81 [英] SetMetadataByName fails with error 0x88982F81
问题描述
嗨大家好,
我正在尝试将XMP元数据添加到tiff文件(此时此类型没有元数据)。
不幸的是,操作
hr = piFrameQWriter-> SetMetadataByName(L" /",& value); [见下文]
失败,错误为WINCODEC_ERR_UNSUPPORTEDOPERATION(0x88982F81)。
有任何建议吗?
// AddMetadata.cpp:定义控制台应用程序的入口点。
//
#include
" stdafx.h"
#include
< wincodec.h>
#include
< wincodecsdk.h>
#include
< atlbase.h>
#pragma
评论( lib ,
" windowscodecs.lib" )
void
AddMetadataToFile ();
$
struct
SErrorInfo
{
int < span style ="color:#010001"> nLine ;
HRESULT hr ;
SErrorInfo ():
nLine ( - 1), hr (0){}
SErrorInfo ( int
n , HRESULT
h ): nLine (
n ), hr ( h ){}
};
#define
TESTHR \
如果(! SUCCEEDED (
hr ))\
{\
throw new
SErrorInfo ( __ LINE __ ,
hr ); \
}
$
void
AddMetadataToFile ()
{
//工厂指针
CComPtr < IWICImagingFactory 跨度>>
pFactory ;
//创建COM成像工厂
HRESULT hr =
CoCreateInstance (
CLSID_WICImagingFactory ,
NULL ,
CLSCTX_INPROC_SERVER ,
IID_PPV_ARGS (& pFactory )
);
TESTHR ;
//加载图片
//创建解码器
但是CComPtr 跨度>< IWICBitmapDecoder >
pDecoder ;
hr = < span style ="color:#010001"> pFactory - >
CreateDecoderFromFilename (
TEXT (" .. \\Images\\Green.tif" ),
//要解码的图像
NULL 跨度>,&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
//不喜欢特定供应商
GENERIC_READ ,
// Desired读取文件的访问权
WICDecodeMetadataCacheOnDemand 跨度>,&NBSP;
//需要时缓存元数据
& pDecoder &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
//指向解码器的指针
);
TESTHR ;
//从解码器中检索图像的第一帧
CComPtr < IWICBitmapFrameDecode >
pFrame ;
hr = < span style ="color:#010001"> pDecoder - >
GetFrame (0,&
pFrame );
TESTHR ;
//枚举元数据
获取查询阅读器
CComPtr < IWICMetadataQueryReader >
pQueryReader ;
hr = < span style ="color:#010001"> pFrame - >
GetMetadataQueryReader (&
pQueryReader );
TESTHR ;
//获取枚举器
CComPtr < IEnumString >
pEnum ;
hr = < span style ="color:#010001"> pQueryReader - >
GetEnumerator (&
pEnum );
TESTHR ;
//枚举元数据
hr = pEnum - >
重置();
TESTHR ;
CComBSTR resstr ;
ULONG uFetched = 0;
而(( hr =
pEnum - > 下一步(1,&
resstr ,& uFetched ))==
S_OK &&& style ="color:#010001"> uFetched == 1)
{
wprintf_s ( L "%s \ n" ,(< span style ="color:#0000ff"> const
wchar_t *) resstr );
}
//创建并初始化图像编码器
CComPtr < IWICStream >
piFileStream ;
UINT count = 0;
//创建文件流。
hr = pFactory - >
CreateStream (&
piFileStream );
TESTHR ;
//初始化我们的新文件流。
hr = piFileStream - >
InitializeFromFilename (
L " .. \\Images\\Image2.tif" ,
GENERIC_WRITE );
TESTHR ;
//创建编码器。
CComPtr < IWICBitmapEncoder >
piEncoder ;
hr = pFactory - >
CreateEncoder ( GUID_ContainerFormatTiff ,
NULL ,& piEncoder );
TESTHR ;
//初始化编码器
hr = piEncoder - >
初始化( piFileStream ,
WICBitmapEncoderNoCache );
TESTHR ;
< span style ="color:#008000"> //复制解码的帧信息
CComPtr < IWICBitmapFrameEncode >
piFrameEncode ;
hr = < span style ="color:#010001"> piEncoder - >
CreateNewFrame (&
piFrameEncode , NULL );
TESTHR ;
hr = piFrameEncode - > 初始化( NULL );
TESTHR ;
UINT width ,
height = 0;
hr = pFrame - >
GetSize (& width ,&
height );
TESTHR ;
hr = piFrameEncode - > SetSize ( width ,
height );
TESTHR ;
double dpiX ,
dpiY = 0.0;
pFrame - > GetResolution (&
dpiX ,& dpiY );
TESTHR ;
< span style ="color:#010001"> WICPixelFormatGUID
pixelFormat = {0};
pFrame - > GetPixelFormat (& pixelFormat );
TESTHR ;
hr = piFrameEncode - > SetPixelFormat (& pixelFormat );
TESTHR ;
/ /检查新的帧格式
bool formatsEqual =
FALSE ;
if ( SUCCEEDED ( hr ))
{
GUID srcFormat ;
GUID < span style ="color:#010001"> destFormat ;
hr = pDecoder - >
GetContainerFormat (& srcFormat );
if ( SUCCEEDED ( hr ))
{
hr = piEncoder - > GetContainerFormat (& destFormat );
}
if ( SUCCEEDED ( hr ))
{
if ( srcFormat ==
destFormat )
formatsEqual =
true ;
else
formatsEqual =
false ;
}
}
if (! formatsEqual )
{
hr = HRESULT_FROM_WIN32 (
ERROR_BAD_FORMAT );
}
TESTHR ;
//复制元数据
CComPtr < IWICMetadataBlockReader >
piBlockReader ;
hr = < span style ="color:#010001"> pFrame - >
QueryInterface ( IID_PPV_ARGS (&
piBlockReader ));
TESTHR ;
CComPtr < IWICMetadataBlockWriter >
piBlockWriter ;
hr = < span style ="color:#010001"> piFrameEncode - >
QueryInterface ( IID_PPV_ARGS (&
piBlockWriter ));
TESTHR ;
hr = piBlockWriter - >
InitializeFromBlockReader (
piBlockReader );
TESTHR ;
添加其他元数据
CComPtr < IWICMetadataQueryWriter >
pXMPWriter ;
GUID vendor =
GUID_VendorMicrosoft ;
hr = pFactory - >
CreateQueryWriter (
GUID_MetadataFormatXMP ,& 供应商,&
pXMPWriter );
TESTHR ;
//将元数据写入XMP编写器
PROPVARIANT value ;
PropVariantInit (& value );
value 。 vt =
VT_LPWSTR ;
值。 pwszVal =
L "元数据测试图像。";
hr = pXMPWriter - > SetMetadataByName ( L " / dc:title" ,& value );
PropVariantClear (& 价值);
TESTHR ;
CComPtr < IWICMetadataQueryWriter >
piFrameQWriter ;
hr = < span style ="color:#010001"> piFrameEncode - >
GetMetadataQueryWriter (&
piFrameQWriter );
TESTHR ;
PropVariantInit (& value );
value 。< span style ="color:#010001"> vt =
VT_UNKNOWN ;
value 。 punkVal =
pXMPWriter ;
value 。 punkVal - > AddRef ();
hr = piFrameQWriter - > SetMetadataByName ( L < span style ="color:#a31515">" /" ,& value );
PropVariantClear (& 价值);
TESTHR ;
//完成编码图像
hr = piFrameEncode - >
WriteSource ( static_cast < IWICBitmapSource *>(
pFrame ), NULL );
TESTHR ;
hr = piFrameEncode - > 提交();
TESTHR ;
pFrame = < span style ="color:#010001"> NULL ;
piFrameEncode =
NULL ;
piFrameQWriter =
NULL ;
piEncoder - > 提交();
TESTHR ;
}
$
int
_ tmain ( int
argc , _ TCHAR *
argv [])
{
CoInitialize ( NULL );
尝试
{
AddMetadataToFile ();
}
catch ( SErrorInfo *
p )
{
printf_s ("行%d处的异常,代码为0x%08X \ n \ n ,
p - > nLine ,
p - > hr );
}
catch (...)
{
printf_s (" Exception\\\
\ nn" );
}
CoUninitialize ();
return 0;
}
< blockquote>
我不是元数据专家,但我找到了两个可能完成你想要做的事情的例子。
参见"示例"和"示例"。
的部分内容IWICMetadataQueryWriter接口
另请参阅"第5部分:添加其他元数据"
How-to:Re的部分 - 使用元数据对JPEG图像进行编码
我知道后者是针对JPEG的,但是看看通过TIFF图像尝试得到的结果。
Hi folks,
I'm trying to add XMP metadata to a tiff file (which has no metadata of this type at this point).
Unfortunately, the operation
hr = piFrameQWriter->SetMetadataByName(L"/", &value); [see below]
fails with error WINCODEC_ERR_UNSUPPORTEDOPERATION (0x88982F81).
Any suggestions?
// AddMetadata.cpp : Defines the entry point for the console application.
//
#include
"stdafx.h"
#include
<wincodec.h>
#include
<wincodecsdk.h>
#include
<atlbase.h>
#pragma
comment ( lib, "windowscodecs.lib" )
void
AddMetadataToFile();
struct
SErrorInfo
{
int nLine ;
HRESULT hr ;
SErrorInfo () : nLine ( -1 ), hr ( 0 ) {}
SErrorInfo ( int n, HRESULT h ) : nLine ( n ), hr ( h ) {}
} ;
#define
TESTHR \
if ( ! SUCCEEDED ( hr ) ) \
{ \
throw new SErrorInfo ( __LINE__, hr ) ; \
}
void
AddMetadataToFile()
{
// The factory pointer
CComPtr<IWICImagingFactory> pFactory ;
// Create the COM imaging factory
HRESULT hr = CoCreateInstance ( CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pFactory)
) ;
TESTHR ;
// Load image
// Create a decoder
CComPtr<IWICBitmapDecoder> pDecoder ;
hr = pFactory -> CreateDecoderFromFilename ( TEXT ( "..\\Images\\Green.tif" ), // Image to be decoded
NULL, // Do not prefer a particular vendor
GENERIC_READ, // Desired read access to the file
WICDecodeMetadataCacheOnDemand, // Cache metadata when needed
& pDecoder // Pointer to the decoder
) ;
TESTHR ;
// Retrieve the first frame of the image from the decoder
CComPtr<IWICBitmapFrameDecode> pFrame ;
hr = pDecoder -> GetFrame ( 0, & pFrame ) ;
TESTHR ;
// Enum metadata
// Get the query reader
CComPtr<IWICMetadataQueryReader> pQueryReader ;
hr = pFrame -> GetMetadataQueryReader ( & pQueryReader ) ;
TESTHR ;
// Get enumerator
CComPtr<IEnumString> pEnum ;
hr = pQueryReader -> GetEnumerator ( & pEnum ) ;
TESTHR ;
// Enumerate metadata
hr = pEnum -> Reset() ;
TESTHR ;
CComBSTR resstr ;
ULONG uFetched = 0 ;
while ( ( hr = pEnum -> Next ( 1, & resstr, & uFetched ) ) == S_OK && uFetched == 1 )
{
wprintf_s ( L"%s\n", (const wchar_t*) resstr ) ;
}
// Create and Initialize the Image Encoder
CComPtr<IWICStream> piFileStream ;
UINT count = 0;
// Create a file stream.
hr = pFactory -> CreateStream ( & piFileStream ) ;
TESTHR ;
// Initialize our new file stream.
hr = piFileStream -> InitializeFromFilename ( L"..\\Images\\Image2.tif", GENERIC_WRITE ) ;
TESTHR ;
// Create the encoder.
CComPtr<IWICBitmapEncoder> piEncoder ;
hr = pFactory -> CreateEncoder ( GUID_ContainerFormatTiff, NULL, & piEncoder ) ;
TESTHR ;
// Initialize the encoder
hr = piEncoder -> Initialize ( piFileStream, WICBitmapEncoderNoCache ) ;
TESTHR ;
// Copy Decoded Frame Information
CComPtr<IWICBitmapFrameEncode> piFrameEncode ;
hr = piEncoder -> CreateNewFrame ( & piFrameEncode, NULL ) ;
TESTHR ;
hr = piFrameEncode->Initialize(NULL);
TESTHR ;
UINT width, height = 0;
hr = pFrame -> GetSize ( & width, & height ) ;
TESTHR ;
hr = piFrameEncode->SetSize(width, height);
TESTHR ;
double dpiX, dpiY = 0.0;
pFrame -> GetResolution ( & dpiX, & dpiY ) ;
TESTHR ;
WICPixelFormatGUID pixelFormat = { 0 };
pFrame -> GetPixelFormat(&pixelFormat);
TESTHR ;
hr = piFrameEncode->SetPixelFormat(&pixelFormat);
TESTHR ;
// Check new frame format
bool formatsEqual = FALSE;
if (SUCCEEDED(hr))
{
GUID srcFormat;
GUID destFormat;
hr = pDecoder -> GetContainerFormat(&srcFormat);
if (SUCCEEDED(hr))
{
hr = piEncoder->GetContainerFormat(&destFormat);
}
if (SUCCEEDED(hr))
{
if (srcFormat == destFormat)
formatsEqual = true;
else
formatsEqual = false;
}
}
if ( ! formatsEqual )
{
hr = HRESULT_FROM_WIN32 ( ERROR_BAD_FORMAT ) ;
}
TESTHR ;
// Copy the Metadata
CComPtr<IWICMetadataBlockReader> piBlockReader ;
hr = pFrame-> QueryInterface ( IID_PPV_ARGS ( & piBlockReader ) ) ;
TESTHR ;
CComPtr<IWICMetadataBlockWriter> piBlockWriter ;
hr = piFrameEncode -> QueryInterface ( IID_PPV_ARGS ( & piBlockWriter ) ) ;
TESTHR ;
hr = piBlockWriter -> InitializeFromBlockReader ( piBlockReader ) ;
TESTHR ;
// Add Additional Metadata
CComPtr<IWICMetadataQueryWriter> pXMPWriter ;
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory -> CreateQueryWriter ( GUID_MetadataFormatXMP, & vendor, & pXMPWriter ) ;
TESTHR ;
// Write metadata to the XMP writer
PROPVARIANT value;
PropVariantInit(&value);
value.vt = VT_LPWSTR;
value.pwszVal = L"Metadata Test Image.";
hr = pXMPWriter->SetMetadataByName(L"/dc:title", &value);
PropVariantClear(&value);
TESTHR ;
CComPtr<IWICMetadataQueryWriter> piFrameQWriter ;
hr = piFrameEncode -> GetMetadataQueryWriter ( & piFrameQWriter ) ;
TESTHR ;
PropVariantInit(&value);
value.vt = VT_UNKNOWN;
value.punkVal = pXMPWriter;
value.punkVal->AddRef();
hr = piFrameQWriter->SetMetadataByName(L"/", &value);
PropVariantClear(&value);
TESTHR ;
// Finalize the Encoded Image
hr = piFrameEncode -> WriteSource ( static_cast<IWICBitmapSource*> ( pFrame ), NULL ) ;
TESTHR ;
hr = piFrameEncode->Commit();
TESTHR ;
pFrame = NULL ;
piFrameEncode = NULL ;
piFrameQWriter = NULL ;
piEncoder->Commit();
TESTHR ;
}
int
_tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
try
{
AddMetadataToFile();
}
catch ( SErrorInfo * p )
{
printf_s ( "Exception at line %d with code 0x%08X\n\n", p -> nLine, p -> hr ) ;
}
catch ( ... )
{
printf_s ( "Exception\n\n" ) ;
}
CoUninitialize () ;
return 0;
}
I am not a metadata expert, but I found two examples that might accomplish what you are trying to do.
See the "Example" section of the IWICMetadataQueryWriter interface
See also the "Part 5: Add Additional Metadata" section of How-to: Re-encode a JPEG Image with Metadata
I know the latter is for JPEG, but see what result you get by trying it with your TIFF image.
这篇关于SetMetadataByName失败,错误0x88982F81的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!