GDI+ 原生支援 JPEG/BMP 互轉。合併兩張 JPG 的流程:
① 將兩張 JPG 解碼為 Image 物件(內部即為位圖);
② 建立目標 Bitmap,使用 Graphics::DrawImage 繪製拼貼;
③ 以 JPEG 編碼器儲存結果。
// 取得編碼器 CLSID
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
UINT num = 0, size = 0;
GetImageEncodersSize(&num, &size);
if (size == 0) return -1;
ImageCodecInfo* pInfo = (ImageCodecInfo*)malloc(size);
GetImageEncoders(num, size, pInfo);
for (UINT i = 0; i < num; ++i) {
if (wcscmp(pInfo[i].MimeType, format) == 0) {
*pClsid = pInfo[i].Clsid;
free(pInfo); return i;
}
}
free(pInfo); return -1;
}
// 通用轉換:srcPath → dstPath,format 如 L"image/jpeg" 或 L"image/bmp"
BOOL ConvertPic(const WCHAR* format, const CString& dstPath, const CString& srcPath) {
CLSID clsid;
if (GetEncoderClsid(format, &clsid) < 0) return FALSE;
Image img(srcPath); // GDI+ Image 可直接讀取 JPG/BMP/PNG 等
return img.Save(dstPath, &clsid, NULL) == Ok;
}
void MergeTwoJpg(const CString& file1, const CString& file2, const CString& outFile) {
GdiplusStartupInput gdiSI; ULONG_PTR gdiToken;
GdiplusStartup(&gdiToken, &gdiSI, NULL);
Image img1(file1), img2(file2);
// 假設水平拼接,高度取較大者
int w = img1.GetWidth() + img2.GetWidth();
int h = max(img1.GetHeight(), img2.GetHeight());
Bitmap bmp(w, h, PixelFormat24bppRGB);
Graphics g(&bmp);
g.Clear(Color::White);
g.DrawImage(&img1, 0, 0);
g.DrawImage(&img2, img1.GetWidth(), 0);
CLSID clsid; GetEncoderClsid(L"image/jpeg", &clsid);
// 可設定品質
EncoderParameters ep; ep.Count = 1;
ep.Parameter[0].Guid = EncoderQuality;
ep.Parameter[0].Type = EncoderParameterValueTypeLong;
ep.Parameter[0].NumberOfValues = 1;
ULONG quality = 90; ep.Parameter[0].Value = &quality;
bmp.Save(outFile, &clsid, &ep);
GdiplusShutdown(gdiToken);
}
gdiplus.lib,且 stdafx.h 包含 <gdiplus.h> 並 using namespace Gdiplus;。GdiplusStartup/Shutdown 必須成對呼叫,建議在 CWinApp 初始化/結束時處理。Bitmap 建構子指定像素格式減少記憶體。