您的位置:首页 > 其它

基于mfc数字图像处理的小软件pdd-改变图片的大小

2014-12-09 17:46 555 查看
在前面我们已经介绍了基于MFC处理图像,使图像通过RGB通道,彩色图像变为灰度,黑白的处理,这次我们介绍怎么改变图片的大小,我们这里有用到双线性内插的方法来处理图像,使它变换,其实只要加上鼠标处理,那么图片应该是可以自由变换的,但是我这个小软件只是单纯的将一张图片放大缩小,改变size,在窗口上进行显示而已(原谅为什么这么low,因为作业只要求到这里)。

先看一个效果图吧~!





这是将左边这个图变为300*200右边这个图的效果。

首先,还是在菜单上加入按钮,我的按钮很简单,那么现在就为按钮添加事件相应函数,其实和前面一样,可以参考前面的。这里我再贴一下:

void CpddView::OnSize192()
{
reload();
Invalidate(TRUE);
int iWidth = m_MyImage.GetWidth();
int iHeight = m_MyImage.GetHeight();

m_MyImage.ScaleAny(pathName,//int宽,//int高);

}

然后ScaleAny的主要实现如下:

void ChangeColor::ScaleAny(CString path, int width, int height)
{
ChangeColor ChangeSize;
ChangeSize.Load(path);
this->Destroy();
this->Create(width, height, ChangeSize.GetBPP());
Change_Size2(ChangeSize);
}


然后,其中Change_Size2的主要实现如下:

/*
双线性内插值算法描述如下:
srcX=dstX* (srcHeight/dstHeight) , srcY = dstY * (srcWidth/dstWidth);
对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i + u, j + v) (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0, 1)区间的浮点数),则这个像素得值 f(i + u, j + v) 可由原图像中坐标为(i, j)、(i + 1, j)、(i, j + 1)、(i + 1, j + 1)所对应的周围四个像素的值决定,即:

f(i + u, j + v) = (1 - u)(1 - v)f(i, j) + (1 - u)vf(i, j + 1) + u(1 - v)f(i + 1, j) + uvf(i + 1, j + 1)                          公式1

其中f(i, j)表示源图像(i, j)处的的像素值,以此类推。
*/
void ChangeColor::Change_Size2(ChangeColor ChangeSize)
{
int i, j;//循环目标矩阵的计数器
double a, b;//目标矩阵映射在源矩阵的坐标,也作小数部分
int c, d;//目标矩阵的整数部分
int nRowBytes = ChangeSize.GetPitch();//图像每一行的字节数,注意这个值一般是负数
int nR = GetPitch();
double sWidth = (double)ChangeSize.GetWidth();
double dWidth = (double)GetWidth();
double sHeight = (double)ChangeSize.GetHeight();
double dHeight = (double)GetHeight();
int nClrs = ChangeSize.GetBPP() / 8;
int nC = GetBPP() / 8;
LPBYTE p = (LPBYTE)ChangeSize.GetBits();
LPBYTE pp = (LPBYTE)GetBits();
for (i = 0; i < dHeight; i++) //第i行
{
for (j = 0; j < dWidth; j++) //第j列
{
a = (double)i * (sHeight / dHeight);
b = (double)j * (sWidth / dWidth);
c = (int)a;
d = (int)b;
a =  a - c;
b = b - d;
if ((c + 1 < sHeight) && (d + 1 < sWidth))
{
pp[i*nR + j*nC + 0] = (1 - a)*(1 - b)*p[c*nRowBytes + d*nClrs + 0] + (1 - a)*b*p[c*nRowBytes + (d + 1)*nClrs + 0] + a*(1 - b)*p[(c + 1)*nRowBytes + d*nClrs + 0] + a*b*p[(c + 1)*nRowBytes + (d + 1)*nClrs + 0];
pp[i*nR + j*nC + 1] = (1 - a)*(1 - b)*p[c*nRowBytes + d*nClrs + 1] + (1 - a)*b*p[c*nRowBytes + (d + 1)*nClrs + 1] + a*(1 - b)*p[(c + 1)*nRowBytes + d*nClrs + 1] + a*b*p[(c + 1)*nRowBytes + (d + 1)*nClrs + 1];
pp[i*nR + j*nC + 2] = (1 - a)*(1 - b)*p[c*nRowBytes + d*nClrs + 2] + (1 - a)*b*p[c*nRowBytes + (d + 1)*nClrs + 2] + a*(1 - b)*p[(c + 1)*nRowBytes + d*nClrs + 2] + a*b*p[(c + 1)*nRowBytes + (d + 1)*nClrs + 2];
}
}
}
}


双线性插值 的介绍看上面的算法描述,其实上面的代码很简单,看不懂的都可以在我前面的文章中可以看懂了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐