画像をズームしてdpiを設定する

5192 ワード

ここ数日需要に出会って、ピクチャーを拡大・縮小することを要求して、しかしピクチャーのdpiを変えることができなくて、opencvでだめで、そこでネット上で探して、しかし長い間関連する情報を探し当てていないで、ただ1篇の招待状はGdiplusを使ってこの需要を満たすことができると言って、ついにGdiplusのインタフェースを研究して、ついにGdiplus::Bitmap::SetResolutionのこの方法を探し当てて、新しい技能Get!
完全なコードは次のとおりです.
#pragma comment(lib, "Gdiplus.lib")

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    /*
     *            class id
     */

    UINT num = 0;  // number of image encoders 
    UINT size = 0;  // size of the image encoder array in bytes 

    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

    Gdiplus::GetImageEncodersSize(&num, &size);
    if (size == 0)
    {
        return -1;
    }

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
    {
        return -1;
    }

    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT j = 0; j < num; ++j)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;
        }
    }

    free(pImageCodecInfo);
    return -1;
}

bool GdiplusUtils::resizeImage(const std::string &sourceImagePath,
    const std::string &targetImagePath,
    int targetImageWidth,
    int targetImageHeight,
    const std::string &targetImageEncoder,
    Gdiplus::PixelFormat targetImagePixelFormat,
    bool remainResolution)
{
    /*
    * Load source image and get information
    */

    Gdiplus::Bitmap sourceImage(StringUtils::MB2WC(sourceImagePath).c_str(), FALSE);

    /*
    * Rescale and set resolution
    */

    // rescale
    Gdiplus::Bitmap targetImage(targetImageWidth, targetImageHeight, targetImagePixelFormat);
    Gdiplus::Graphics graphics(&targetImage);
    graphics.DrawImage(&sourceImage, 0, 0, targetImageWidth, targetImageHeight);

    // set resolution
    if (remainResolution)
    {
        auto hResolution = sourceImage.GetHorizontalResolution();
        auto vResolution = sourceImage.GetVerticalResolution();
        targetImage.SetResolution(hResolution, vResolution);
    }

    /*
    * Save Image
    */
    CLSID clsid;
    GetEncoderClsid(StringUtils::MB2WC(targetImageEncoder).c_str(), &clsid);
    targetImage.Save(StringUtils::MB2WC(targetImagePath).c_str(), &clsid);

    return true;
}

Gdiplusを導入する必要があることに注意してください.libは、GdiplusをGdiplus::GdiplusStartupおよびGdiplus::GdiplusShutdownによって初期化および逆初期化する必要がある.これらの内容は上記のコードに現れず、読者は適切な位置で自分で追加する必要がある.
最後に、コードのStringUtils::MB2WCは、マルチバイト文字をワイドバイト文字に変換する補助関数であり、コードは以下の通りである.
std::wstring StringUtils::MB2WC(const std::string &mb)
{
    int lenWC = ::MultiByteToWideChar(CP_ACP, 0, mb.c_str(), mb.length(), NULL, 0);
    std::unique_ptr<wchar_t> wc(new wchar_t[lenWC]());
    ::MultiByteToWideChar(CP_ACP, 0, mb.c_str(), mb.length(), wc.get(), lenWC);
    return std::wstring(wc.get(), lenWC);
}