每个样本的位/像素 libtiff 与 WIC

BIts Per Sample / Pixel libtiff vs WIC

TIFF *TiffImage;
uint16 photo, bps, spp, fillorder;
uint32 width,height;
unsigned long stripSize;
unsigned long imageOffset, result;
int stripMax, stripCount;
unsigned char *buffer, tempbyte;
unsigned short *buffer16;
unsigned int *buffer32;
unsigned long bufferSize, count;
bool success = true;
int shiftCount = 0;


//read image to InData
const char *InFileName = fileName.c_str();

if((TiffImage = TIFFOpen(InFileName, "r")) == NULL){
    ErrMsg("Could not open incoming image\n");
    return false;
}
// Check that it is of a type that we support
if(TIFFGetField(TiffImage, TIFFTAG_BITSPERSAMPLE, &bps) == 0) {
   ErrMsg("Either undefined or unsupported number of bits per sample\n");
   return false;
}
TBitPrecision bitPrecision = (TBitPrecision)bps;

char* imageDesc = NULL;
TIFFGetField(TiffImage, TIFFTAG_IMAGEDESCRIPTION, &imageDesc);

// Get actual bit precision for CP Images
if (bps > 8 && bps <= 16)
{
    if (GetCpTiffTag(imageDesc, CP_TIFFTAG_BITPRECISION, (uint32*)&bitPrecision) == true)
    {
        shiftCount = 16 - bitPrecision;
    }
}

在我的 libtiff 实现中,我使用了每像素图像 12 位和 10 bpp 在 libtiff

中设置此信息非常容易

我在 WIC 中找不到类似的方法

uint16_t photo, bps, spp, fillorder;
uint32_t width,height;
unsigned long stripSize;
unsigned long imageOffset, result;
int stripMax, stripCount;
unsigned char *buffer, tempbyte;
unsigned short *buffer16;
unsigned int *buffer32;
unsigned long bufferSize, count;
bool success = true;
int shiftCount = 0;

 //read image to InData
const char *InFileName = fileName.c_str();
 IWICImagingFactory* piFactory = NULL;

// Create WIC factory
  HRESULT hr = CoCreateInstance(
  CLSID_WICImagingFactory,
  NULL,
  CLSCTX_INPROC_SERVER,
  IID_PPV_ARGS(&piFactory)
);
 // Create a decoder
IWICBitmapDecoder *pIDecoder = NULL;
IWICBitmapFrameDecode *pIDecoderFrame  = NULL;

std::wstring ws;
ws.assign(fileName.begin(), fileName.end());
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();

   hr = piFactory->CreateDecoderFromFilename(
   pcwstr,                      // Image to be decoded
   NULL,                            // Do not prefer a particular vendor
   GENERIC_READ,                    // Desired read access to the file
   WICDecodeMetadataCacheOnDemand,  // Cache metadata when needed
   &pIDecoder                        // Pointer to the decoder
   );
      // Retrieve the first bitmap frame.
if (SUCCEEDED(hr))
{
    hr = pIDecoder->GetFrame(0, &pIDecoderFrame);
}
else
{
     ErrMsg("Could not open incoming image\n");
}
return true;

我应该使用 EXIF 还是 XMP?我如何找到 WIC 的 TIFFTAG?

DirectXTex 库有很多从 C++ 使用 WIC 的例子。

你需要这样的东西:

using Microsoft::WRL::ComPtr;


ComPtr<IWICMetadataQueryReader> metareader;
hr = pIDecoderFrame->GetMetadataQueryReader(metareader.GetAddressOf());
if (SUCCEEDED(hr))
{
    PROPVARIANT value;
    PropVariantInit(&value);

    if (SUCCEEDED(metareader->GetMetadataByName(L"/ifd/{ushort=258}", &value))
        && value.vt == VT_UI2)
    {
        // BitsPerSample is in value.uiVal
    }

    PropVariantClear(&value);    
}

You should get in the habit of using a smart-pointer like ComPtr rather than using raw interface pointers to keep the ref counts correct.