huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章


// 图片拉伸
// width, height 拉伸后的图片大小
// img 原图像
void ImageToSize(int width, int height, IMAGE* img)
{
    IMAGE* pOldImage = GetWorkingImage();
    SetWorkingImage(img);

    IMAGE temp_image(width,height);

    StretchBlt(
            GetImageHDC(&temp_image), 0, 0, width, height,
            GetImageHDC(img), 0, 0,
            getwidth(), getheight(),
            SRCCOPY
        );

    Resize(img,width,height);
    putimage(0,0,&temp_image);

    SetWorkingImage(pOldImage);
}



示例:

    IMAGE img;
    loadimage(&img,"./img.jpg");
    ImageToSize(200,200,&img);
    putimage(0,0,&img);


注意:

由于 StretchBlt 函数是有损的,所以请每次拉伸图像时使用原图,否则会越来越糊!


上面这个函数借用了 win32 的 StretchBlt 函数,拉伸效果并不太好,还有下面这个双线性插值法实现的:

备注:这个函数如果拉伸高度为 1 的图像会什么也得不到……

/*
 *    参考自 http://tieba.baidu.com/p/5218523817
 *    参数说明:pImg 是原图指针,width1 和 height1 是目标图片的尺寸。
 *    函数功能:将图片进行缩放,返回目标图片。可以自定义宽高;也可以只给宽度,程序自动计算高度
 *    返回目标图片
*/
IMAGE zoomImage(IMAGE* pImg, int newWidth, int newHeight = 0)
{
    // 防止越界
    if (newWidth < 0 || newHeight < 0) {
        newWidth = pImg->getwidth();
        newHeight = pImg->getheight();
    }

    // 当参数只有一个时按比例自动缩放
    if (newHeight == 0) {
        // 此处需要注意先*再/。不然当目标图片小于原图时会出错
        newHeight = newWidth * pImg->getheight() / pImg->getwidth();
    }

    // 获取需要进行缩放的图片
    IMAGE newImg(newWidth, newHeight);

    // 分别对原图像和目标图像获取指针
    DWORD* oldDr = GetImageBuffer(pImg);
    DWORD* newDr = GetImageBuffer(&newImg);

    // 赋值 使用双线性插值算法
    for (int i = 0; i < newHeight - 1; i++) {
        for (int j = 0; j < newWidth - 1; j++) {
            int t = i * newWidth + j;
            int xt = j * pImg->getwidth() / newWidth;
            int yt = i * pImg->getheight() / newHeight;
            newDr[i * newWidth + j] = oldDr[xt + yt * pImg->getwidth()];
            // 实现逐行加载图片
            byte r = (GetRValue(oldDr[xt + yt * pImg->getwidth()]) +
                GetRValue(oldDr[xt + yt * pImg->getwidth() + 1]) +
                GetRValue(oldDr[xt + (yt + 1) * pImg->getwidth()]) +
                GetRValue(oldDr[xt + (yt + 1) * pImg->getwidth() + 1])) / 4;
            byte g = (GetGValue(oldDr[xt + yt * pImg->getwidth()]) +
                GetGValue(oldDr[xt + yt * pImg->getwidth()] + 1) +
                GetGValue(oldDr[xt + (yt + 1) * pImg->getwidth()]) +
                GetGValue(oldDr[xt + (yt + 1) * pImg->getwidth()]) + 1) / 4;
            byte b = (GetBValue(oldDr[xt + yt * pImg->getwidth()]) +
                GetBValue(oldDr[xt + yt * pImg->getwidth()] + 1) +
                GetBValue(oldDr[xt + (yt + 1) * pImg->getwidth()]) +
                GetBValue(oldDr[xt + (yt + 1) * pImg->getwidth() + 1])) / 4;
            newDr[i * newWidth + j] = RGB(r, g, b);
        }
    }

    return newImg;
}


注意,若不想使用双线性插值,可以将 rgb 的计算公式替换为:

byte r = GetRValue(oldDr[xt + yt * pImg->getwidth()]);
byte g = GetGValue(oldDr[xt + yt * pImg->getwidth()]);
byte b = GetBValue(oldDr[xt + yt * pImg->getwidth()]);




返回首页


Copyright (C) 2018-2024 huidong