我是否错误地设置了 avi 信息以在 C++ 中保存文件? vfw?

发布于 2024-11-14 11:45:05 字数 9666 浏览 2 评论 0原文

我正在使用专门的网络流媒体摄像机,并且尝试将视频流保存在文件中。目前,代码保存了视频,但采用了一种粗俗的 RGB 格式,这种格式会搞乱颜色,然后使用 VFW 保存它。我这样做是否正确,这应该会创建颜色不匹配的 avi,还是我在 BITMAPINFOHEADER 区域设置了错误?

void PvSbProUISampleDlg::OnBnClickedSave()
{
// TODO: Add your control notification handler code here

CString StringValue;
mMovieSave.GetWindowTextW(StringValue);

if (StringValue == L"Save")
{
    CString codecValue;
    mMovieCodecSelected.GetWindowTextW(codecValue);
    if (codecValue.IsEmpty()){
        MessageBox( L"Please select a codec before saving to file",
                    L"Select Codec!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }

    CString fileNameValue;
    mFileName.GetWindowTextW(fileNameValue);
    if (fileNameValue.IsEmpty()){
        MessageBox( L"Please select a file location",
                    L"Select File!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }


    if (!StartMovie())
        return;

    mSavingMovie = true;
    mMovieSave.SetWindowTextW(L"Saving");
}
else
{
    mVideoMutex.Lock();
    PvResult aResult = mVideoCompressor->Stop();
    mSavingMovie = false;
    mVideoMutex.Unlock();
    if (!aResult.IsOK())
    {
        MessageBox( mLocation,
                    L"Can't Stop Video Compressor!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }

    mMovieSave.SetWindowTextW(L"Save");
}

}

我设置了视频流并为我的编解码器选择了未压缩的 AVI。我单击“保存”按钮,然后调用该函数下面的函数

bool PvSbProUISampleDlg::StartMovie()
{
 if ( !mDevice.IsConnected() )
{
    MessageBox( L"Need to connect to device",
                L"Cannot start Video Compressor!",
                MB_OK | MB_ICONEXCLAMATION );
    return false;
}

if (!mPipeline.IsStarted() )
{
    return false;
} 

if (mSavingMovie)
    return false;

PvInt64 width;
PvInt64 height;
PvInt64 bitCount;

if (!GetImageWidth(width).IsOK())
    return false;

if (!GetImageHeight(height).IsOK())
    return false;

if (!GetPixelBitCount(bitCount).IsOK())
    return false;

// Start the movie compressor
if ( !mVideoCompressor->Start( mLocation,
                            width,
                            height,
                            bitCount/8,
                            59).IsOK())
{
    MessageBox( mLocation,
                L"Cannot start Video Compressor!",
                MB_OK | MB_ICONEXCLAMATION );
    return false;
}

return true;
}

获取视频大小信息,然后调用实际压缩来启动

PvResult VideoCompressor::Start(const CString& aFileName, unsigned short aSizeX,      unsigned short aSizeY, unsigned short aBPP, double aFPS)
{
IAVIFile *lAVIFile = NULL;
IAVIStream *lAVIStream = NULL;
IAVIStream *lAVICompressedStream = NULL;
AVISTREAMINFO lAVISTREAMINFO;
AVICOMPRESSOPTIONS lAVICOMPRESSOPTIONS;

// Try to match the image format with the Video Compressor capabilities
BITMAPINFO lTempBI;
lTempBI.bmiHeader.biSize          = sizeof( BITMAPINFO );
lTempBI.bmiHeader.biWidth         = aSizeX;
lTempBI.bmiHeader.biHeight        = aSizeY;
lTempBI.bmiHeader.biPlanes        = 1;
lTempBI.bmiHeader.biBitCount      = aBPP * 8;
lTempBI.bmiHeader.biCompression   = BI_RGB;
lTempBI.bmiHeader.biSizeImage     = aSizeX * aSizeY * aBPP;
lTempBI.bmiHeader.biXPelsPerMeter = 1280;
lTempBI.bmiHeader.biYPelsPerMeter = 720;
lTempBI.bmiHeader.biClrUsed       = 0;
lTempBI.bmiHeader.biClrImportant  = 0;
//lTempBI.bmiHeader.

if( ( mCOMPVARS.hic != NULL ) && // if not the "Full Frames (uncompressed)"
    ( ICCompressQuery( mCOMPVARS.hic, &lTempBI, NULL ) != ICERR_OK ) )
{
    mLastVideoError = "Image format not accepted by compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

// Try to open the stream for writing
if( mTempBuffer )
    delete [] mTempBuffer;

mTempBuffer = new unsigned char[ aSizeX * aSizeY * aBPP ];
if( mTempBuffer == NULL )
{
    mLastVideoError = "Cannot allocate memory for a temporary buffer!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

if( AVIFileOpen( &lAVIFile, aFileName, OF_CREATE | OF_WRITE, NULL ) != 0 )
{
    mLastVideoError = "Cannot open movie file for writing!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

// Fill out AVIStream information
memset( &lAVISTREAMINFO, 0, sizeof( AVISTREAMINFO ) );
lAVISTREAMINFO.fccType               = streamtypeVIDEO;
lAVISTREAMINFO.fccHandler            = mCOMPVARS.fccHandler;
lAVISTREAMINFO.dwFlags               = 0;
lAVISTREAMINFO.dwCaps                = 0;
lAVISTREAMINFO.wPriority             = 0;
lAVISTREAMINFO.wLanguage             = 0;
lAVISTREAMINFO.dwScale               = 100;
lAVISTREAMINFO.dwRate                = (unsigned long)( aFPS * 100.0 );
lAVISTREAMINFO.dwStart               = 0;
lAVISTREAMINFO.dwLength              = 0;
lAVISTREAMINFO.dwInitialFrames       = 0;
lAVISTREAMINFO.dwQuality             = mCOMPVARS.lQ;
lAVISTREAMINFO.dwSuggestedBufferSize = aSizeX * aSizeY * aBPP;
lAVISTREAMINFO.dwSampleSize          = aSizeX * aSizeY * aBPP;
SetRect(&lAVISTREAMINFO.rcFrame, 0, aSizeY, aSizeX, 0);
// Convert to a wchar_t*
char *orig = "Video Stream";
size_t origsize = strlen(orig) + 1;
const size_t newsize = 64;
size_t convertedChars = 0;

mbstowcs_s(&convertedChars, lAVISTREAMINFO.szName, origsize, orig, _TRUNCATE);

if( AVIFileCreateStream( lAVIFile, &lAVIStream, &lAVISTREAMINFO ) != 0 )
{
    mLastVideoError = "Cannot create video stream!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

BITMAPINFOHEADER lBIH;
lBIH.biSize          = sizeof( BITMAPINFOHEADER );
lBIH.biWidth         = aSizeX;
lBIH.biHeight        = aSizeY;
lBIH.biPlanes        = 1;
lBIH.biBitCount      = aBPP * 8;
lBIH.biCompression   = BI_RGB;
lBIH.biSizeImage     = aSizeX * aSizeY * aBPP;
lBIH.biXPelsPerMeter = 1280;
lBIH.biYPelsPerMeter = 720;
lBIH.biClrUsed       = 0;
lBIH.biClrImportant  = 0;

memset( &lAVICOMPRESSOPTIONS, 0, sizeof( AVICOMPRESSOPTIONS ) );
lAVICOMPRESSOPTIONS.fccType           = streamtypeVIDEO;
lAVICOMPRESSOPTIONS.fccHandler        = mCOMPVARS.fccHandler;
lAVICOMPRESSOPTIONS.dwKeyFrameEvery   = 15;
lAVICOMPRESSOPTIONS.dwQuality         = mCOMPVARS.lQ;
lAVICOMPRESSOPTIONS.dwBytesPerSecond  = 0;
lAVICOMPRESSOPTIONS.dwFlags           = AVICOMPRESSF_KEYFRAMES; //|   AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE;
lAVICOMPRESSOPTIONS.lpFormat          = &lBIH;
lAVICOMPRESSOPTIONS.cbFormat          = sizeof( lBIH );
lAVICOMPRESSOPTIONS.lpParms           = 0;
lAVICOMPRESSOPTIONS.cbParms           = 0;
lAVICOMPRESSOPTIONS.dwInterleaveEvery = 0;

HRESULT lR = AVIMakeCompressedStream( &lAVICompressedStream, lAVIStream, &lAVICOMPRESSOPTIONS, NULL);
if( lR == AVIERR_NOCOMPRESSOR )
{
    mLastVideoError = "Cannot find a suitable compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
} 
else if( lR == AVIERR_MEMORY )
{
    mLastVideoError = "Not enough memory to start the compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}
else if( lR == AVIERR_UNSUPPORTED )
{
    mLastVideoError = "Compression is not supported for this image buffer!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

if( AVIStreamSetFormat( lAVICompressedStream, 0, &lBIH, sizeof( lBIH ) ) != 0 )
{
    mLastVideoError = "Cannot set stream format. It probably isn't supported by the Codec!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

///////////////////

HRESULT hr;
//IBaseFilter mux = Null;
//IFileSinkFilter sink = null;

//    Guid x = new Guid( 0xe436eb88, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 );

//ICaptureGraphBuilder2::SetOutputFileName( 



//////////////////

// finishing up
mAVIFile             = lAVIFile;
mAVIStream           = lAVIStream;
mAVICompressedStream = lAVICompressedStream;

mSizeX     = aSizeX;
mSizeY     = aSizeY;
mBPP       = aBPP;
mImageSize = aSizeX * aSizeY * aBPP;

mLastSample = 0;

mCompressing = true;

return PvResult::Code::OK;
}

此压缩流,

PvResult VideoCompressor::Compress(PvBuffer *aPvBuffer)
{
if (!mCompressing)
    return PvResult::Code::GENERIC_ERROR;

ASSERT( mTempBuffer != NULL );

long lSamplesWritten, lBytesWritten;

int numberOfLines = 0;

PvUInt8 * aBuffer = aPvBuffer->GetDataPointer();

for( unsigned short lLine = 0; lLine < mSizeY; lLine++ )
{
    numberOfLines = lLine;
    unsigned char *lCurLine    = (unsigned char *)aBuffer + (lLine             ) * mSizeX * mBPP;
    unsigned char *lCurLineInv = mTempBuffer              + (mSizeY - lLine - 1) * mSizeX * mBPP;
    ::memcpy( lCurLineInv, lCurLine, mSizeX * mBPP );
}

if( AVIStreamWrite( mAVICompressedStream, mLastSample, 1, mTempBuffer, mImageSize, 0, 
        &lSamplesWritten, &lBytesWritten ) != 0 ||
    lSamplesWritten < 1 ||
    lBytesWritten < 1 )
{
    mLastVideoError = "Cannot compress image!";
    return PvResult::Code::GENERIC_ERROR;

}

mLastSample ++;

return PvResult::Code::OK;
}

这应该是这样的: http://i13.photobucket.com/albums/a269/Masterg_/Untitled -16.png

这是它保存的内容(减去那个家伙): http://i13.photobucket.com/albums/a269/Masterg_/vlcsnap-2011-06-07-13h11m34s97.png

I am using a specialized network streaming camera and I am trying to save the video stream off in a file. at the moment the code saves the video but in an ackward RGB format which screws up the color and then saves it using VFW. Am i doing this correctly and this is supposed to create avi with mismatched colors or did i setup something wrong in the BITMAPINFOHEADER areas?

void PvSbProUISampleDlg::OnBnClickedSave()
{
// TODO: Add your control notification handler code here

CString StringValue;
mMovieSave.GetWindowTextW(StringValue);

if (StringValue == L"Save")
{
    CString codecValue;
    mMovieCodecSelected.GetWindowTextW(codecValue);
    if (codecValue.IsEmpty()){
        MessageBox( L"Please select a codec before saving to file",
                    L"Select Codec!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }

    CString fileNameValue;
    mFileName.GetWindowTextW(fileNameValue);
    if (fileNameValue.IsEmpty()){
        MessageBox( L"Please select a file location",
                    L"Select File!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }


    if (!StartMovie())
        return;

    mSavingMovie = true;
    mMovieSave.SetWindowTextW(L"Saving");
}
else
{
    mVideoMutex.Lock();
    PvResult aResult = mVideoCompressor->Stop();
    mSavingMovie = false;
    mVideoMutex.Unlock();
    if (!aResult.IsOK())
    {
        MessageBox( mLocation,
                    L"Can't Stop Video Compressor!",
                    MB_OK | MB_ICONEXCLAMATION );
        return;
    }

    mMovieSave.SetWindowTextW(L"Save");
}

}

I set up the video stream and select uncompressed AVI for my codec. I click "save" button which then calls the function below

bool PvSbProUISampleDlg::StartMovie()
{
 if ( !mDevice.IsConnected() )
{
    MessageBox( L"Need to connect to device",
                L"Cannot start Video Compressor!",
                MB_OK | MB_ICONEXCLAMATION );
    return false;
}

if (!mPipeline.IsStarted() )
{
    return false;
} 

if (mSavingMovie)
    return false;

PvInt64 width;
PvInt64 height;
PvInt64 bitCount;

if (!GetImageWidth(width).IsOK())
    return false;

if (!GetImageHeight(height).IsOK())
    return false;

if (!GetPixelBitCount(bitCount).IsOK())
    return false;

// Start the movie compressor
if ( !mVideoCompressor->Start( mLocation,
                            width,
                            height,
                            bitCount/8,
                            59).IsOK())
{
    MessageBox( mLocation,
                L"Cannot start Video Compressor!",
                MB_OK | MB_ICONEXCLAMATION );
    return false;
}

return true;
}

the function gets the video size info and then calls the actually compression to start

PvResult VideoCompressor::Start(const CString& aFileName, unsigned short aSizeX,      unsigned short aSizeY, unsigned short aBPP, double aFPS)
{
IAVIFile *lAVIFile = NULL;
IAVIStream *lAVIStream = NULL;
IAVIStream *lAVICompressedStream = NULL;
AVISTREAMINFO lAVISTREAMINFO;
AVICOMPRESSOPTIONS lAVICOMPRESSOPTIONS;

// Try to match the image format with the Video Compressor capabilities
BITMAPINFO lTempBI;
lTempBI.bmiHeader.biSize          = sizeof( BITMAPINFO );
lTempBI.bmiHeader.biWidth         = aSizeX;
lTempBI.bmiHeader.biHeight        = aSizeY;
lTempBI.bmiHeader.biPlanes        = 1;
lTempBI.bmiHeader.biBitCount      = aBPP * 8;
lTempBI.bmiHeader.biCompression   = BI_RGB;
lTempBI.bmiHeader.biSizeImage     = aSizeX * aSizeY * aBPP;
lTempBI.bmiHeader.biXPelsPerMeter = 1280;
lTempBI.bmiHeader.biYPelsPerMeter = 720;
lTempBI.bmiHeader.biClrUsed       = 0;
lTempBI.bmiHeader.biClrImportant  = 0;
//lTempBI.bmiHeader.

if( ( mCOMPVARS.hic != NULL ) && // if not the "Full Frames (uncompressed)"
    ( ICCompressQuery( mCOMPVARS.hic, &lTempBI, NULL ) != ICERR_OK ) )
{
    mLastVideoError = "Image format not accepted by compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

// Try to open the stream for writing
if( mTempBuffer )
    delete [] mTempBuffer;

mTempBuffer = new unsigned char[ aSizeX * aSizeY * aBPP ];
if( mTempBuffer == NULL )
{
    mLastVideoError = "Cannot allocate memory for a temporary buffer!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

if( AVIFileOpen( &lAVIFile, aFileName, OF_CREATE | OF_WRITE, NULL ) != 0 )
{
    mLastVideoError = "Cannot open movie file for writing!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

// Fill out AVIStream information
memset( &lAVISTREAMINFO, 0, sizeof( AVISTREAMINFO ) );
lAVISTREAMINFO.fccType               = streamtypeVIDEO;
lAVISTREAMINFO.fccHandler            = mCOMPVARS.fccHandler;
lAVISTREAMINFO.dwFlags               = 0;
lAVISTREAMINFO.dwCaps                = 0;
lAVISTREAMINFO.wPriority             = 0;
lAVISTREAMINFO.wLanguage             = 0;
lAVISTREAMINFO.dwScale               = 100;
lAVISTREAMINFO.dwRate                = (unsigned long)( aFPS * 100.0 );
lAVISTREAMINFO.dwStart               = 0;
lAVISTREAMINFO.dwLength              = 0;
lAVISTREAMINFO.dwInitialFrames       = 0;
lAVISTREAMINFO.dwQuality             = mCOMPVARS.lQ;
lAVISTREAMINFO.dwSuggestedBufferSize = aSizeX * aSizeY * aBPP;
lAVISTREAMINFO.dwSampleSize          = aSizeX * aSizeY * aBPP;
SetRect(&lAVISTREAMINFO.rcFrame, 0, aSizeY, aSizeX, 0);
// Convert to a wchar_t*
char *orig = "Video Stream";
size_t origsize = strlen(orig) + 1;
const size_t newsize = 64;
size_t convertedChars = 0;

mbstowcs_s(&convertedChars, lAVISTREAMINFO.szName, origsize, orig, _TRUNCATE);

if( AVIFileCreateStream( lAVIFile, &lAVIStream, &lAVISTREAMINFO ) != 0 )
{
    mLastVideoError = "Cannot create video stream!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

BITMAPINFOHEADER lBIH;
lBIH.biSize          = sizeof( BITMAPINFOHEADER );
lBIH.biWidth         = aSizeX;
lBIH.biHeight        = aSizeY;
lBIH.biPlanes        = 1;
lBIH.biBitCount      = aBPP * 8;
lBIH.biCompression   = BI_RGB;
lBIH.biSizeImage     = aSizeX * aSizeY * aBPP;
lBIH.biXPelsPerMeter = 1280;
lBIH.biYPelsPerMeter = 720;
lBIH.biClrUsed       = 0;
lBIH.biClrImportant  = 0;

memset( &lAVICOMPRESSOPTIONS, 0, sizeof( AVICOMPRESSOPTIONS ) );
lAVICOMPRESSOPTIONS.fccType           = streamtypeVIDEO;
lAVICOMPRESSOPTIONS.fccHandler        = mCOMPVARS.fccHandler;
lAVICOMPRESSOPTIONS.dwKeyFrameEvery   = 15;
lAVICOMPRESSOPTIONS.dwQuality         = mCOMPVARS.lQ;
lAVICOMPRESSOPTIONS.dwBytesPerSecond  = 0;
lAVICOMPRESSOPTIONS.dwFlags           = AVICOMPRESSF_KEYFRAMES; //|   AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE;
lAVICOMPRESSOPTIONS.lpFormat          = &lBIH;
lAVICOMPRESSOPTIONS.cbFormat          = sizeof( lBIH );
lAVICOMPRESSOPTIONS.lpParms           = 0;
lAVICOMPRESSOPTIONS.cbParms           = 0;
lAVICOMPRESSOPTIONS.dwInterleaveEvery = 0;

HRESULT lR = AVIMakeCompressedStream( &lAVICompressedStream, lAVIStream, &lAVICOMPRESSOPTIONS, NULL);
if( lR == AVIERR_NOCOMPRESSOR )
{
    mLastVideoError = "Cannot find a suitable compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
} 
else if( lR == AVIERR_MEMORY )
{
    mLastVideoError = "Not enough memory to start the compressor!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}
else if( lR == AVIERR_UNSUPPORTED )
{
    mLastVideoError = "Compression is not supported for this image buffer!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

if( AVIStreamSetFormat( lAVICompressedStream, 0, &lBIH, sizeof( lBIH ) ) != 0 )
{
    mLastVideoError = "Cannot set stream format. It probably isn't supported by the Codec!";
    CleanUp(lAVIFile, lAVIStream ,lAVICompressedStream);
    return PvResult::Code::GENERIC_ERROR;
}

///////////////////

HRESULT hr;
//IBaseFilter mux = Null;
//IFileSinkFilter sink = null;

//    Guid x = new Guid( 0xe436eb88, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 );

//ICaptureGraphBuilder2::SetOutputFileName( 



//////////////////

// finishing up
mAVIFile             = lAVIFile;
mAVIStream           = lAVIStream;
mAVICompressedStream = lAVICompressedStream;

mSizeX     = aSizeX;
mSizeY     = aSizeY;
mBPP       = aBPP;
mImageSize = aSizeX * aSizeY * aBPP;

mLastSample = 0;

mCompressing = true;

return PvResult::Code::OK;
}

this compresses the stream

PvResult VideoCompressor::Compress(PvBuffer *aPvBuffer)
{
if (!mCompressing)
    return PvResult::Code::GENERIC_ERROR;

ASSERT( mTempBuffer != NULL );

long lSamplesWritten, lBytesWritten;

int numberOfLines = 0;

PvUInt8 * aBuffer = aPvBuffer->GetDataPointer();

for( unsigned short lLine = 0; lLine < mSizeY; lLine++ )
{
    numberOfLines = lLine;
    unsigned char *lCurLine    = (unsigned char *)aBuffer + (lLine             ) * mSizeX * mBPP;
    unsigned char *lCurLineInv = mTempBuffer              + (mSizeY - lLine - 1) * mSizeX * mBPP;
    ::memcpy( lCurLineInv, lCurLine, mSizeX * mBPP );
}

if( AVIStreamWrite( mAVICompressedStream, mLastSample, 1, mTempBuffer, mImageSize, 0, 
        &lSamplesWritten, &lBytesWritten ) != 0 ||
    lSamplesWritten < 1 ||
    lBytesWritten < 1 )
{
    mLastVideoError = "Cannot compress image!";
    return PvResult::Code::GENERIC_ERROR;

}

mLastSample ++;

return PvResult::Code::OK;
}

this is what it should look like:
http://i13.photobucket.com/albums/a269/Masterg_/Untitled-16.png

this is what it saves as ( minus the guy):
http://i13.photobucket.com/albums/a269/Masterg_/vlcsnap-2011-06-07-13h11m34s97.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

恋你朝朝暮暮 2024-11-21 11:45:05

MSDN 我们有:

语法

DWORD ICCompressQuery(
     hic,
     lpbiInput,
     lpbiOutput );

参数

hic:压缩机句柄。

lpbiInput:指向包含输入格式的 BITMAPINFO 结构的指针

lpbiOutput:指向包含输出格式的 BITMAPINFO 结构的指针。你可以
将此参数指定为零
表示任何输出格式是
可以接受。

我可能是错的,但在我看来,您试图“强制”此输入格式,而不考虑您作为输入传递的实际格式。如果您的输入格式与“强制”格式不匹配,则必然会出现奇怪的结果。
如果您的实际输入格式与您的压缩器不兼容,您可以尝试使用 ColorSpace 转换器过滤器 在压缩器之前。

From MSDN we have:

Syntax

DWORD ICCompressQuery(
     hic,
     lpbiInput,
     lpbiOutput );

Parameters

hic : Handle to a compressor.

lpbiInput : Pointer to a BITMAPINFO structure containing the input format.

lpbiOutput : Pointer to a BITMAPINFO structure containing the output format. You can
specify zero for this parameter to
indicate any output format is
acceptable.

I might be wrong, but it seems to me that you are trying to "force" this input format whitout taking into account the actual format you are passing as input. If your input format does not match the "forced" one, weird result must be expected.
If your actual input format is not compatible with your compressor, you could try usign a ColorSpace converter filter before your compressor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文