如何使用 Win32 Imaging API (Windows Mobile 6+) 将 HBITMAP 保存为 JPG?

发布于 2024-10-29 04:47:12 字数 13242 浏览 2 评论 0原文

我已经创建了将窗口屏幕截图保存到文件的程序。它适用于 PNG 和 BMP,但不适用于 JPG(和 GIF)。 这是用于捕获 HBITMAP 的代码:

HBITMAP Signature::getScreenHBITMAP() {
// get screen rectangle 
RECT windowRect; 
GetWindowRect(getMainWnd(), &windowRect); 

// bitmap dimensions 
int bitmap_dx = windowRect.right - windowRect.left; 
int bitmap_dy = windowRect.bottom - windowRect.top; 

// create bitmap info header 
BITMAPINFOHEADER infoHeader; 
infoHeader.biSize          = sizeof(infoHeader); 
infoHeader.biWidth         = bitmap_dx; 
infoHeader.biHeight        = bitmap_dy; 
infoHeader.biPlanes        = 1; 
infoHeader.biBitCount      = 24;
infoHeader.biCompression   = BI_RGB; 
infoHeader.biSizeImage     = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed       = 0;
infoHeader.biClrImportant  = 0;

// dibsection information 
BITMAPINFO info; 
info.bmiHeader = infoHeader; 
HDC winDC = GetWindowDC(getMainWnd()); 
HDC memDC = CreateCompatibleDC(winDC); 
BYTE* memory = 0; 
HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0); 
SelectObject(memDC, bitmap); 
// Copies screen upside down (as it is already upside down) - if need normal layout, change to BitBlt function call
StretchBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, bitmap_dy, bitmap_dx, bitmap_dy * -1, SRCCOPY); 
DeleteDC(memDC); 
ReleaseDC(getMainWnd(), winDC); 

return bitmap;
}

这是用于图像保存的代码:

HRESULT Imaging_SaveToFile(HBITMAP handle, LPTSTR filename, LPCTSTR format){
HRESULT res;

res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ((res == S_OK) || (res == S_FALSE)) {
    IImagingFactory* factory=NULL;
    if (CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&factory) == S_OK) {
        UINT count;
        ImageCodecInfo* imageCodecInfo=NULL;
        if (factory->GetInstalledEncoders(&count, &imageCodecInfo) == S_OK) {
            // Get the particular encoder to use
            LPTSTR formatString;
            if (wcscmp(format, L"png") == 0) {
                formatString = _T("image/png");
            } else if (wcscmp(format, L"jpg") == 0) {
                formatString = _T("image/jpeg");
            } else if (wcscmp(format, L"gif") == 0) {
                formatString = _T("image/gif");
            } else if (wcscmp(format, L"bmp") == 0) {
                formatString = _T("image/bmp");
            } else {
                CoUninitialize();
                return S_FALSE;
            }
            CLSID encoderClassId;
            if (count == 0) {
                CoUninitialize();
                return S_FALSE;
            }
            for(int i=0; i < (int)count; i++) {
                if (wcscmp(imageCodecInfo[i].MimeType, formatString) == 0) {
                    encoderClassId= imageCodecInfo[i].Clsid;
                    free(imageCodecInfo);
                    break;
                } else {
                    continue;
                }
                CoUninitialize();
                return S_FALSE;
            } 
            IImageEncoder* imageEncoder=NULL;
            if (factory->CreateImageEncoderToFile(&encoderClassId, filename, &imageEncoder) == S_OK) {
                IImageSink* imageSink = NULL;
                res = imageEncoder->GetEncodeSink(&imageSink);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                BITMAP bm;
                GetObject (handle, sizeof(BITMAP), &bm);

                ImageInfo* imageInfo = new ImageInfo();
                imageInfo->Width = bm.bmWidth;
                imageInfo->Height = bm.bmHeight;
                imageInfo->RawDataFormat = IMGFMT_MEMORYBMP; //ImageFormatMemoryBMP;
                imageInfo->Flags |= SinkFlagsTopDown | SinkFlagsFullWidth;
                // Get pixel format from hBitmap
                PixelFormatID pixelFormat;
                int numColors = 0;
                switch (bm.bmBitsPixel) {
                    case 1: {
                        pixelFormat = PixelFormat1bppIndexed;
                        numColors = 1;
                        break;
                    }
                    case 4: {
                        pixelFormat = PixelFormat4bppIndexed;
                        numColors = 16;
                        break;
                    }
                    case 8: {
                        pixelFormat = PixelFormat8bppIndexed;
                        numColors = 256;
                        break;
                    }
                    case 24: {
                        pixelFormat = PixelFormat24bppRGB;
                        break;
                    }
                    default: {
                        pixelFormat = PixelFormat32bppARGB;
                        numColors = 3; // according to MSDN 16 and 32 bpp numColors should be 3
                        break;
                    }
                }
                imageInfo->PixelFormat = pixelFormat;
                if (pixelFormat == PixelFormat32bppARGB) imageInfo->Flags |= SinkFlagsHasAlpha;
                res = imageSink->BeginSink(imageInfo, NULL);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                ColorPalette* palette = NULL;
                if (numColors > 0) {
                    palette = (ColorPalette*)malloc(sizeof(ColorPalette) + (numColors - 1) * sizeof(ARGB));
                    palette->Count = numColors;
                    for (int i=0; i<numColors; i++) {
                        int rgb = i*64;
                        int red = rgb & 0x00FF;
                        int green = (rgb >> 8) & 0x00FF;
                        int blue = (rgb >> 16) & 0x00FF;
                        palette->Entries[i] = MAKEARGB(0, red, green, blue);
                    }
                } else {
                    palette = (ColorPalette*)malloc(sizeof(ColorPalette));
                    palette->Count = 0;
                    if (pixelFormat == PixelFormat32bppARGB) palette->Flags = PALFLAG_HASALPHA;
                }
                res = imageSink->SetPalette(palette);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                BitmapData* bmData = new BitmapData();
                bmData->Height = bm.bmHeight;
                bmData->Width = bm.bmWidth;
                bmData->Scan0 = bm.bmBits;
                bmData->PixelFormat = pixelFormat;

                UINT bitsPerLine = imageInfo->Width * bm.bmBitsPixel;
                UINT bitAlignment = sizeof(LONG) * 8;
                UINT bitStride = bitAlignment * (bitsPerLine / bitAlignment);   // The image buffer is always padded to LONG boundaries
                if ((bitsPerLine % bitAlignment) != 0) bitStride += bitAlignment; // Add a bit more for the leftover values
                bmData->Stride = (bitStride / 8);

                RECT rect;
                rect.top = 0;
                rect.bottom = bm.bmHeight;
                rect.left = 0;
                rect.right = bm.bmWidth;

                res = imageSink->PushPixelData(&rect, bmData, TRUE);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                res = imageSink->EndSink(S_OK);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                imageSink->Release();
                res = imageEncoder->TerminateEncoder();
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
            }
        }
    }
    CoUninitialize();
} else {
    return res;
}

return res;
}

我使用了 Koders.com 作为示例并尝试遵循 修改此示例时图像编码的 MSDN 描述

还发现其他人也有类似的问题,但没有答案:

social.msdn.microsoft.com/Forums/en-US/windowsmobiledev/thread/1c368cc1-cc5b-419e-a7d2-2a39c90ae83d/

groups.google.com/group/microsoft .public.windowsce.embedded.vc/browse_thread/thread/8cd67e16ac29627b/9242e82721c48ace?hl=hu&pli=1

我还找到了使用 GDI+ 包装器的解决方案:

www.ernzo.com/LibGdiplus.aspx

www.codeproject.com/KB/ windows/gdiplusandwinmobile.aspx

但我无法使用这个 GDI+ 库。而且我不需要整个 GDI+。尝试创建与此包装器类似的保存过程,但没有成功。

编辑

这是固定且有效的解决方案(感谢 PhilMY 的回答):

HRESULT Imaging_SaveToFile(HBITMAP handle, LPTSTR filename, LPCTSTR format){
HRESULT res;

res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ((res == S_OK) || (res == S_FALSE)) {
    IImagingFactory* factory=NULL;
    if (CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&factory) == S_OK) {
        UINT count;
        ImageCodecInfo* imageCodecInfo=NULL;
        if (factory->GetInstalledEncoders(&count, &imageCodecInfo) == S_OK) {
            // Get the particular encoder to use
            LPTSTR formatString;
            if (wcscmp(format, L"png") == 0) {
                formatString = _T("image/png");
            } else if (wcscmp(format, L"jpg") == 0) {
                formatString = _T("image/jpeg");
            } else if (wcscmp(format, L"gif") == 0) {
                formatString = _T("image/gif");
            } else if (wcscmp(format, L"bmp") == 0) {
                formatString = _T("image/bmp");
            } else {
                CoUninitialize();
                return S_FALSE;
            }
            CLSID encoderClassId;
            if (count == 0) {
                CoUninitialize();
                return S_FALSE;
            }
            for(int i=0; i < (int)count; i++) {
                if (wcscmp(imageCodecInfo[i].MimeType, formatString) == 0) {
                    encoderClassId= imageCodecInfo[i].Clsid;
                    free(imageCodecInfo);
                    break;
                } else {
                    continue;
                }
                CoUninitialize();
                return S_FALSE;
            } 
            IImageEncoder* imageEncoder=NULL;
            if (factory->CreateImageEncoderToFile(&encoderClassId, filename, &imageEncoder) == S_OK) {
                IImageSink* imageSink = NULL;
                res = imageEncoder->GetEncodeSink(&imageSink);

                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                BITMAP bm;
                GetObject (handle, sizeof(BITMAP), &bm);
                PixelFormatID pixelFormat;
                switch (bm.bmBitsPixel) {
                    case 1: {
                        pixelFormat = PixelFormat1bppIndexed;
                        break;
                    }
                    case 4: {
                        pixelFormat = PixelFormat4bppIndexed;
                        break;
                    }
                    case 8: {
                        pixelFormat = PixelFormat8bppIndexed;
                        break;
                    }
                    case 24: {
                        pixelFormat = PixelFormat24bppRGB;
                        break;
                    }
                    default: {
                        pixelFormat = PixelFormat32bppARGB;
                        break;
                    }
                }

                BitmapData* bmData = new BitmapData();
                bmData->Height = bm.bmHeight;
                bmData->Width = bm.bmWidth;
                bmData->Scan0 = bm.bmBits;
                bmData->PixelFormat = pixelFormat;

                UINT bitsPerLine = bm.bmWidth * bm.bmBitsPixel;
                UINT bitAlignment = sizeof(LONG) * 8;
                UINT bitStride = bitAlignment * (bitsPerLine / bitAlignment);   // The image buffer is always padded to LONG boundaries
                if ((bitsPerLine % bitAlignment) != 0) bitStride += bitAlignment; // Add a bit more for the leftover values
                bmData->Stride = (bitStride / 8);

                IBitmapImage* pBitmap;
                factory->CreateBitmapFromBuffer(bmData, &pBitmap);
                IImage* pImage;
                pBitmap->QueryInterface(IID_IImage, (void**)&pImage); 
                res = pImage->PushIntoSink(imageSink);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                pBitmap->Release();
                pImage->Release();
                imageSink->Release();
                imageEncoder->TerminateEncoder();
                imageEncoder->Release();
            }
        }
    }
    CoUninitialize();
} else {
    return res;
}

return res;
}

I have created procedures to save window screenshot to file. It works for PNG and BMP, but not for JPG (and GIF).
Here is code for capturing HBITMAP:

HBITMAP Signature::getScreenHBITMAP() {
// get screen rectangle 
RECT windowRect; 
GetWindowRect(getMainWnd(), &windowRect); 

// bitmap dimensions 
int bitmap_dx = windowRect.right - windowRect.left; 
int bitmap_dy = windowRect.bottom - windowRect.top; 

// create bitmap info header 
BITMAPINFOHEADER infoHeader; 
infoHeader.biSize          = sizeof(infoHeader); 
infoHeader.biWidth         = bitmap_dx; 
infoHeader.biHeight        = bitmap_dy; 
infoHeader.biPlanes        = 1; 
infoHeader.biBitCount      = 24;
infoHeader.biCompression   = BI_RGB; 
infoHeader.biSizeImage     = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed       = 0;
infoHeader.biClrImportant  = 0;

// dibsection information 
BITMAPINFO info; 
info.bmiHeader = infoHeader; 
HDC winDC = GetWindowDC(getMainWnd()); 
HDC memDC = CreateCompatibleDC(winDC); 
BYTE* memory = 0; 
HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0); 
SelectObject(memDC, bitmap); 
// Copies screen upside down (as it is already upside down) - if need normal layout, change to BitBlt function call
StretchBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, bitmap_dy, bitmap_dx, bitmap_dy * -1, SRCCOPY); 
DeleteDC(memDC); 
ReleaseDC(getMainWnd(), winDC); 

return bitmap;
}

And here is code for image saving:

HRESULT Imaging_SaveToFile(HBITMAP handle, LPTSTR filename, LPCTSTR format){
HRESULT res;

res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ((res == S_OK) || (res == S_FALSE)) {
    IImagingFactory* factory=NULL;
    if (CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&factory) == S_OK) {
        UINT count;
        ImageCodecInfo* imageCodecInfo=NULL;
        if (factory->GetInstalledEncoders(&count, &imageCodecInfo) == S_OK) {
            // Get the particular encoder to use
            LPTSTR formatString;
            if (wcscmp(format, L"png") == 0) {
                formatString = _T("image/png");
            } else if (wcscmp(format, L"jpg") == 0) {
                formatString = _T("image/jpeg");
            } else if (wcscmp(format, L"gif") == 0) {
                formatString = _T("image/gif");
            } else if (wcscmp(format, L"bmp") == 0) {
                formatString = _T("image/bmp");
            } else {
                CoUninitialize();
                return S_FALSE;
            }
            CLSID encoderClassId;
            if (count == 0) {
                CoUninitialize();
                return S_FALSE;
            }
            for(int i=0; i < (int)count; i++) {
                if (wcscmp(imageCodecInfo[i].MimeType, formatString) == 0) {
                    encoderClassId= imageCodecInfo[i].Clsid;
                    free(imageCodecInfo);
                    break;
                } else {
                    continue;
                }
                CoUninitialize();
                return S_FALSE;
            } 
            IImageEncoder* imageEncoder=NULL;
            if (factory->CreateImageEncoderToFile(&encoderClassId, filename, &imageEncoder) == S_OK) {
                IImageSink* imageSink = NULL;
                res = imageEncoder->GetEncodeSink(&imageSink);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                BITMAP bm;
                GetObject (handle, sizeof(BITMAP), &bm);

                ImageInfo* imageInfo = new ImageInfo();
                imageInfo->Width = bm.bmWidth;
                imageInfo->Height = bm.bmHeight;
                imageInfo->RawDataFormat = IMGFMT_MEMORYBMP; //ImageFormatMemoryBMP;
                imageInfo->Flags |= SinkFlagsTopDown | SinkFlagsFullWidth;
                // Get pixel format from hBitmap
                PixelFormatID pixelFormat;
                int numColors = 0;
                switch (bm.bmBitsPixel) {
                    case 1: {
                        pixelFormat = PixelFormat1bppIndexed;
                        numColors = 1;
                        break;
                    }
                    case 4: {
                        pixelFormat = PixelFormat4bppIndexed;
                        numColors = 16;
                        break;
                    }
                    case 8: {
                        pixelFormat = PixelFormat8bppIndexed;
                        numColors = 256;
                        break;
                    }
                    case 24: {
                        pixelFormat = PixelFormat24bppRGB;
                        break;
                    }
                    default: {
                        pixelFormat = PixelFormat32bppARGB;
                        numColors = 3; // according to MSDN 16 and 32 bpp numColors should be 3
                        break;
                    }
                }
                imageInfo->PixelFormat = pixelFormat;
                if (pixelFormat == PixelFormat32bppARGB) imageInfo->Flags |= SinkFlagsHasAlpha;
                res = imageSink->BeginSink(imageInfo, NULL);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                ColorPalette* palette = NULL;
                if (numColors > 0) {
                    palette = (ColorPalette*)malloc(sizeof(ColorPalette) + (numColors - 1) * sizeof(ARGB));
                    palette->Count = numColors;
                    for (int i=0; i<numColors; i++) {
                        int rgb = i*64;
                        int red = rgb & 0x00FF;
                        int green = (rgb >> 8) & 0x00FF;
                        int blue = (rgb >> 16) & 0x00FF;
                        palette->Entries[i] = MAKEARGB(0, red, green, blue);
                    }
                } else {
                    palette = (ColorPalette*)malloc(sizeof(ColorPalette));
                    palette->Count = 0;
                    if (pixelFormat == PixelFormat32bppARGB) palette->Flags = PALFLAG_HASALPHA;
                }
                res = imageSink->SetPalette(palette);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                BitmapData* bmData = new BitmapData();
                bmData->Height = bm.bmHeight;
                bmData->Width = bm.bmWidth;
                bmData->Scan0 = bm.bmBits;
                bmData->PixelFormat = pixelFormat;

                UINT bitsPerLine = imageInfo->Width * bm.bmBitsPixel;
                UINT bitAlignment = sizeof(LONG) * 8;
                UINT bitStride = bitAlignment * (bitsPerLine / bitAlignment);   // The image buffer is always padded to LONG boundaries
                if ((bitsPerLine % bitAlignment) != 0) bitStride += bitAlignment; // Add a bit more for the leftover values
                bmData->Stride = (bitStride / 8);

                RECT rect;
                rect.top = 0;
                rect.bottom = bm.bmHeight;
                rect.left = 0;
                rect.right = bm.bmWidth;

                res = imageSink->PushPixelData(&rect, bmData, TRUE);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                res = imageSink->EndSink(S_OK);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
                imageSink->Release();
                res = imageEncoder->TerminateEncoder();
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }
            }
        }
    }
    CoUninitialize();
} else {
    return res;
}

return res;
}

I used code from Koders.com as an example and tried to follow MSDN description of image encoding when modified this example.

Found also that others have similar issue, but with no answer:

social.msdn.microsoft.com/Forums/en-US/windowsmobiledev/thread/1c368cc1-cc5b-419e-a7d2-2a39c90ae83d/

groups.google.com/group/microsoft.public.windowsce.embedded.vc/browse_thread/thread/8cd67e16ac29627b/9242e82721c48ace?hl=hu&pli=1

I also found solution which uses GDI+ wrapper:

www.ernzo.com/LibGdiplus.aspx

www.codeproject.com/KB/windows/gdiplusandwinmobile.aspx

But I cannot use this GDI+ lib. Also I do not need whole GDI+. Tried to create similar saving procedure like in this wrapper, but with no success.

EDIT

Here is fixed and working solution (Thanks PhilMY for answer):

HRESULT Imaging_SaveToFile(HBITMAP handle, LPTSTR filename, LPCTSTR format){
HRESULT res;

res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ((res == S_OK) || (res == S_FALSE)) {
    IImagingFactory* factory=NULL;
    if (CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&factory) == S_OK) {
        UINT count;
        ImageCodecInfo* imageCodecInfo=NULL;
        if (factory->GetInstalledEncoders(&count, &imageCodecInfo) == S_OK) {
            // Get the particular encoder to use
            LPTSTR formatString;
            if (wcscmp(format, L"png") == 0) {
                formatString = _T("image/png");
            } else if (wcscmp(format, L"jpg") == 0) {
                formatString = _T("image/jpeg");
            } else if (wcscmp(format, L"gif") == 0) {
                formatString = _T("image/gif");
            } else if (wcscmp(format, L"bmp") == 0) {
                formatString = _T("image/bmp");
            } else {
                CoUninitialize();
                return S_FALSE;
            }
            CLSID encoderClassId;
            if (count == 0) {
                CoUninitialize();
                return S_FALSE;
            }
            for(int i=0; i < (int)count; i++) {
                if (wcscmp(imageCodecInfo[i].MimeType, formatString) == 0) {
                    encoderClassId= imageCodecInfo[i].Clsid;
                    free(imageCodecInfo);
                    break;
                } else {
                    continue;
                }
                CoUninitialize();
                return S_FALSE;
            } 
            IImageEncoder* imageEncoder=NULL;
            if (factory->CreateImageEncoderToFile(&encoderClassId, filename, &imageEncoder) == S_OK) {
                IImageSink* imageSink = NULL;
                res = imageEncoder->GetEncodeSink(&imageSink);

                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                BITMAP bm;
                GetObject (handle, sizeof(BITMAP), &bm);
                PixelFormatID pixelFormat;
                switch (bm.bmBitsPixel) {
                    case 1: {
                        pixelFormat = PixelFormat1bppIndexed;
                        break;
                    }
                    case 4: {
                        pixelFormat = PixelFormat4bppIndexed;
                        break;
                    }
                    case 8: {
                        pixelFormat = PixelFormat8bppIndexed;
                        break;
                    }
                    case 24: {
                        pixelFormat = PixelFormat24bppRGB;
                        break;
                    }
                    default: {
                        pixelFormat = PixelFormat32bppARGB;
                        break;
                    }
                }

                BitmapData* bmData = new BitmapData();
                bmData->Height = bm.bmHeight;
                bmData->Width = bm.bmWidth;
                bmData->Scan0 = bm.bmBits;
                bmData->PixelFormat = pixelFormat;

                UINT bitsPerLine = bm.bmWidth * bm.bmBitsPixel;
                UINT bitAlignment = sizeof(LONG) * 8;
                UINT bitStride = bitAlignment * (bitsPerLine / bitAlignment);   // The image buffer is always padded to LONG boundaries
                if ((bitsPerLine % bitAlignment) != 0) bitStride += bitAlignment; // Add a bit more for the leftover values
                bmData->Stride = (bitStride / 8);

                IBitmapImage* pBitmap;
                factory->CreateBitmapFromBuffer(bmData, &pBitmap);
                IImage* pImage;
                pBitmap->QueryInterface(IID_IImage, (void**)&pImage); 
                res = pImage->PushIntoSink(imageSink);
                if (res != S_OK) {
                    CoUninitialize();
                    return res;
                }

                pBitmap->Release();
                pImage->Release();
                imageSink->Release();
                imageEncoder->TerminateEncoder();
                imageEncoder->Release();
            }
        }
    }
    CoUninitialize();
} else {
    return res;
}

return res;
}

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

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

发布评论

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

评论(1

口干舌燥 2024-11-05 04:47:13

我有一些类似的代码适用于 WinCE 6.0 上的 JPEG。

主要区别是:

  • 我检查 ImageCodecInfo::FormatIDImageFormatJPEG 以匹配编码器
  • 我调用 SetEncoderParameters 来设置 ENCODER_QUALITY >
  • 我将源位图复制到 IBitmapImage 中,然后使用 IImage::PushIntoSink

I have some similar code that worked for JPEGs on WinCE 6.0.

The main differences are:

  • I check ImageCodecInfo::FormatID against ImageFormatJPEG to match an encoder
  • I call SetEncoderParameters to set ENCODER_QUALITY
  • I copy the source bitmap into an IBitmapImage then use IImage::PushIntoSink
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文