根据书上理论基础
图像放大,比如原来是3*3的图像,水平放大2倍,垂直放大2倍,那么原来的一个像素对应的在新图像中的4个像素,如图
那么相应的新,旧坐标对应如下:
//原坐标(x0,y0)->新坐标(x1,y1)
int x0 = i;
int y0 = j;
int x1 = kx*i + ix;
int y1 = ky*j + iy;
然后算法就很明了了,由于像素位大小改变了,所以需要创建一个位图,然后写入新的像素位,对应每一个旧的像素,写入4个新的像素(仍然要注意,每个像素由4个值组成)
算法如下:
//===============函数定义=====================
//图像的放大
//kx水平放大倍数,ky为垂直放大倍数
void magnify(HDC hdc, HDC hMemDC, HBITMAP hBitmap, int Width, int Heigh,int kx,int ky)
{
BITMAP bm;
GetObject(hBitmap, sizeof(bm), &bm);
int WidthRow = bm.bmWidthBytes;//原位图的字节宽(即原位图的每行字节数)
//获取原位图的像素位
BYTE *Pixel = new BYTE[WidthRow*Heigh];
GetBitmapBits(hBitmap, WidthRow*Heigh, (LPVOID)Pixel);
if (kx < 1 || ky < 1)
exit(0);
BYTE *newPixel = new BYTE[kx*ky*WidthRow*Heigh];//存放新的像素位
memset(newPixel,255,kx*ky*WidthRow*Heigh*sizeof(BYTE));
//图像放大,
for (int j = 0; j <Heigh; j++)//行
for (int i = 0; i < Width; i++)//列
{
//将原图中j行i列处像素复制到新图中的ky*j行kx*i列附近的kx*ky个像素
for(int ix=0;ix<kx;ix++)
for (int iy = 0; iy < ky; iy++)
{
//原坐标(x0,y0)->新坐标(x1,y1)
int x0 = i;
int y0 = j;
int x1 = kx*i + ix;
int y1 = ky*j + iy;
//每4个为一个像素位
for (int k = 0; k <4; k++)
{
//新位图宽为kx*Width
newPixel[y1*kx*WidthRow + 4 * x1 + k] =Pixel[y0*WidthRow + 4 * x0 + k];
}
}
}
//创建一个新的位图
HBITMAP hNewBitmap = CreateCompatibleBitmap(hdc,kx*Width,ky*Heigh);
SelectObject(hMemDC, hNewBitmap);//选进内存DC
SetBitmapBits(hNewBitmap, kx*ky*WidthRow*Heigh, newPixel);
BitBlt(hdc, 0, 0, kx*Width, ky*Heigh, hMemDC, 0, 0, SRCCOPY);
DeleteObject(hNewBitmap);
delete[] Pixel;
delete[] newPixel;
}
效果如下(cx为水平放大倍数,cy为垂直放大倍数)
cx=1,cy=3
cx=1,cy=2
cx=2,cy=2
没问题的,但是看书上提供的代码,还是原来的问题,失真了,没处理好像素
缩小与放大差不多,同理
说实话,这本书不怎么好,作者并没有完全实现出来,不过根据书上提供的算法理论基础,自己动手实现出来,才是最重要的,也能提高自己编码能力,要不断学习,持之以恒,共勉
转载自原文链接, 如需删除请联系管理员。
原文链接:图像的放大,转载请注明来源!