WIC增加了TIFF图像的大小

时间:2016-03-01 05:49:10

标签: c++ image-processing tiff wic

情境: 加载TIFF图像并提取tiff图像的帧并将其保存在本地。 将提取的帧组合到输出TIFF图像。 当我尝试组合帧时,输出tiff图像的大小正在急剧增加。例如,如果我的输入大小为40 MB,则输出增加到300 MB。 以下是解释方案的代码,

    void readTiff()
    {
        HRESULT hr;
        IWICBitmapFrameDecode *frameDecode = NULL;
        IWICFormatConverter *formatConverter = NULL;
        IWICBitmapEncoder *encoder = NULL;
        IWICStream *pOutStream = NULL;
        IWICBitmapFrameEncode *frameEncode = NULL;
        IWICImagingFactory* m_pWICFactory;


        hr = CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(&m_pWICFactory)
            );

        IWICBitmapDecoder *pIDecoder = NULL;

        hr = m_pWICFactory->CreateDecoderFromFilename(
            L"D:\\test28\\Multitiff_files\\300dpiTIFF40MB_WATER.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
            &pIDecoder                      // Pointer to the decoder
            );


        UINT frameCount = 0;
        pIDecoder->GetFrameCount(&frameCount);

        for (int i = 0; i < frameCount; i++)
        {
            wchar_t temp[200];
            int j = i;
            swprintf_s(temp, 200, L"D:\\test28\\Multitiff_files\\out\\filename_png%d.jpeg", i);

            if (SUCCEEDED(hr))
                hr = m_pWICFactory->CreateStream(&pOutStream);
            if (SUCCEEDED(hr))
                hr = pOutStream->InitializeFromFilename(temp, GENERIC_WRITE);

            if (SUCCEEDED(hr))
                hr = m_pWICFactory->CreateEncoder(GUID_ContainerFormatJpeg, NULL, &encoder);
            if (SUCCEEDED(hr))
                hr = encoder->Initialize(pOutStream, WICBitmapEncoderNoCache);

            hr = pIDecoder->GetFrame(i, &frameDecode);      

            if (SUCCEEDED(hr))
                hr = m_pWICFactory->CreateFormatConverter(&formatConverter);

            hr = formatConverter->Initialize(
                frameDecode,                     // Source frame to convert
                GUID_WICPixelFormat8bppIndexed,     // The desired pixel format
                WICBitmapDitherTypeNone,         // The desired dither pattern
                NULL,                            // The desired palette 
                0.f,                             // The desired alpha threshold
                WICBitmapPaletteTypeMedianCut       // Palette translation type
                );
            IPropertyBag2 *pPropertybag = NULL;
            //Create a new frame..
            hr = encoder->CreateNewFrame(&frameEncode, &pPropertybag);
            //PROPBAG2 option = { 0 };
            //option.pstrName = L"ImageQuality";
            //VARIANT varValue;
            //VariantInit(&varValue);
            //varValue.vt = VT_R4;
            //varValue.fltVal = 0.01f;
            //hr = pPropertybag->Write(
            //  1, // number of properties being set
            //  &option,
            //  &varValue);

            WICPixelFormatGUID pixelFormat;
            hr = frameEncode->Initialize(pPropertybag);

            //pixelFormat = GUID_WICPixelFormat8bppIndexed;

            frameDecode->GetPixelFormat(&pixelFormat);
            hr = frameEncode->SetPixelFormat(&pixelFormat);

            hr = frameEncode->WriteSource(formatConverter, NULL);
            frameEncode->Commit();
            encoder->Commit();

            if (formatConverter)
                formatConverter->Release();

            if (frameDecode)
                frameDecode->Release();

            if (frameEncode)
                frameEncode->Release();

            if (pOutStream)
                pOutStream->Release();

            if (encoder)
                encoder->Release();     
        }
        if (m_pWICFactory)
            m_pWICFactory->Release();

        pIDecoder->Release();
    }

void combineFile(int count)
{
    HRESULT hr;
    IWICImagingFactory *pFactory = NULL;
    IWICStream *pInStream = NULL;
    IWICBitmapDecoder *decoder = NULL;
    IWICBitmapFrameDecode *frameDecode = NULL;
    IWICFormatConverter *formatConverter = NULL;
    IWICBitmapEncoder *encoder = NULL;
    IWICStream *pOutStream = NULL;
    IWICBitmapFrameEncode *frameEncode = NULL;

    hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory);

    if (!SUCCEEDED(hr)) {
        hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory);
    }

    if (SUCCEEDED(hr))
        hr = pFactory->CreateStream(&pOutStream);

    if (SUCCEEDED(hr))
        hr = pOutStream->InitializeFromFilename(L"D:\\test28\\Multitiff_files\\out\\out.tiff", GENERIC_WRITE);
    if (SUCCEEDED(hr))
        hr = pFactory->CreateEncoder(GUID_ContainerFormatWmp, NULL, &encoder);
    if (SUCCEEDED(hr))
        hr = encoder->Initialize(pOutStream, WICBitmapEncoderNoCache);


    for (int i = 0; i < count; i++)
    {
        wchar_t temp[200];

        swprintf_s(temp, 200, L"D:\\test28\\Multitiff_files\\out\\filename_png%d.jpeg", i);
        if (SUCCEEDED(hr))
            hr = pFactory->CreateStream(&pInStream);
        if (SUCCEEDED(hr))
            hr = pInStream->InitializeFromFilename(temp, GENERIC_READ);
        if (SUCCEEDED(hr))
            hr = pFactory->CreateDecoderFromStream(pInStream, NULL, WICDecodeMetadataCacheOnLoad, &decoder);
        if (SUCCEEDED(hr))
            hr = pFactory->CreateFormatConverter(&formatConverter);


        hr = decoder->GetFrame(0, &frameDecode);

        //hr = formatConverter->Initialize(

        //  frameDecode,                     // Source frame to convert
        //  GUID_WICPixelFormat8bppIndexed,     // The desired pixel format
        //  WICBitmapDitherTypeNone,         // The desired dither pattern
        //  NULL,                            // The desired palette 
        //  0.f,                             // The desired alpha threshold
        //  WICBitmapPaletteTypeMedianCut       // Palette translation type
        //  );

        WICPixelFormatGUID pixelFormat;
        frameDecode->GetPixelFormat(&pixelFormat);

        IPropertyBag2 *pPropertybag = NULL;
        //Create a new frame..
        hr = encoder->CreateNewFrame(&frameEncode, &pPropertybag);
        PROPBAG2 option = { 0 };
        option.pstrName = L"TiffCompressionMethod";
        VARIANT varValue;
        VariantInit(&varValue);
        varValue.vt = VT_UI1;
        varValue.bVal = WICTiffCompressionOption::WICTiffCompressionZIP;
        hr = pPropertybag->Write(1, &option, &varValue);


        hr = frameEncode->Initialize(pPropertybag);
        hr = frameEncode->SetPixelFormat(&pixelFormat);

        hr = frameEncode->WriteSource(formatConverter, NULL);
        hr = frameEncode->Commit();

        if (pInStream)
            pInStream->Release();
        if (decoder)
            decoder->Release();
        if (formatConverter)
            formatConverter->Release();
        if (frameEncode)
            frameEncode->Release();
        //if (frameDecode)
        //frameDecode->Release();
    }
    encoder->Commit();

    if (pFactory)
        pFactory->Release();

    if (encoder)
        encoder->Release();

    if (pOutStream)
        pOutStream->Release();
}

1 个答案:

答案 0 :(得分:1)

调试此类问题的一种简单方法是使用安装在大多数Linux发行版上的ImageMagick,可用于OSX和Windows。首先使用套件中的identify实用程序及其verbose选项,在之前找到关于的所有内容,然后在之后找到的所有内容:

# Find out all we know about first image and put in file "1.txt"
identify -verbose image1.tif > 1.txt

# Find out all we know about second image and put in file "2.txt"
identify -verbose image2.tif > 2.txt

现在使用您最喜欢的文件比较工具来查看差异:

opendiff 1.txt 2.txt

enter image description here