easyx 拉伸IMAGE对象,调整到目标尺寸
[編輯] [转简体] (简体译文)
|
作者:huidong
| 分類:【編程】EasyX
[
9 瀏覽
0 評論
2 贊
2 踩
]
概要
ImageToSize函数,帮你拉伸IMAGE对象,缩放(zoomImage)
正文
// 图片拉伸 // 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()]);