📄 geooperator.cpp
字号:
// 距离当前点最近的四个点坐标
int x1, x2, y1, y2;
x1 = (int)x;
x2 = x1 + 1;
y1 = (int)y;
y2 = y1 + 1;
// 对应四个坐标像素的取值
BYTE clr1, clr2, clr3, clr4;
double u, v;
u = x - x1;
v = y - y1;
// 对于32位真彩色需要分别计算三原色
for (int k = 0; k < 3; k++)
{
// 如果坐标在图像的右下角
if ( (x >= width - 1) && (y >= height - 1) )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
objPixel[k] = clr1;
}
// 如果图像在最后一列外侧
else if ( x >= width - 1 )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr3 = pixel[(y2 * width + x1) * 4 + k]; // (x1, y2)
objPixel[k] = (BYTE)(clr1 * (1 - v) + clr3 * v);
}
// 如果图像在最后一行外侧
else if ( y >= height - 1 )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr2 = pixel[(y1 * width + x2) * 4 + k]; // (x2, y1)
objPixel[k] = (BYTE)(clr1 * (1 - u) + clr2 * u);
}
else
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr2 = pixel[(y1 * width + x2) * 4 + k]; // (x2, y1)
clr3 = pixel[(y2 * width + x1) * 4 + k]; // (x1, y2)
clr4 = pixel[(y2 * width + x2) * 4 + k]; // (x2, y2)
double f1, f2;
f1 = clr1 * (1 - u) + clr2 * u;
f2 = clr3 * (1 - u) + clr4 * u;
objPixel[k] = (BYTE)(f1 * (1 - v) + f2 * v);
}
}
}
}
}
/******************************************************************************
* 作用: 图像的旋转函数(最临近插值法)
* 参数:
* pixel 原始像素数组
* tempPixel 保存变换后图像的像素数组
* width 原始图像宽度
* height 原始图像高度
* outWidth [out]输出图像的宽度
* outHeight [out]输出图像的高度
* angle 旋转度数,以弧度表示
******************************************************************************/
void RotateNormal(BYTE* pixel, BYTE*& tempPixel, int width, int height,
UINT& outWidth, UINT& outHeight, double angle)
{
// 原始图像四个角的坐标
int srcX1, srcX2, srcX3, srcX4;
int srcY1, srcY2, srcY3, srcY4;
srcX1 = 0;
srcY1 = 0;
srcX2 = width - 1;
srcY2 = 0;
srcX3 = 0;
srcY3 = height - 1;
srcX4 = width - 1;
srcY4 = height - 1;
// 计算旋转角度的正弦和余弦值
double fSin = sin(angle);
double fCos = cos(angle);
// 图像经过旋转后四个角的坐标
double tranX1, tranX2, tranX3, tranX4;
double tranY1, tranY2, tranY3, tranY4;
tranX1 = fCos * srcX1 + fSin * srcY1;
tranY1 = -fSin * srcX1 + fCos * srcY1;
tranX2 = fCos * srcX2 + fSin * srcY2;
tranY2 = -fSin * srcX2 + fCos * srcY2;
tranX3 = fCos * srcX3 + fSin * srcY3;
tranY3 = -fSin * srcX3 + fCos * srcY3;
tranX4 = fCos * srcX4 + fSin * srcY4;
tranY4 = -fSin * srcX4 + fCos * srcY3;
// 计算旋转后图像的大小
outWidth = (UINT)( max( fabs(tranX4-tranX1), fabs(tranX3-tranX2) ) + 1.5 );
outHeight = (UINT)( max( fabs(tranY4-tranY1), fabs(tranY3-tranY2) ) + 1.5 );
tempPixel = new BYTE[outWidth * outHeight * 4];
memset(tempPixel, 255, outWidth * outHeight * 4);
// 计算两个常量
double num1 = -0.5*outWidth*fCos - 0.5*outHeight*fSin + 0.5*width;
double num2 = 0.5*outWidth*fSin - 0.5*outHeight*fCos + 0.5*height;
BYTE* copyPixel = NULL; // 指向原始图像中需要拷贝像素的起始位置
BYTE* objPixel = NULL; // 指向被复制像素的起始位置
int x = 0; // 变换后的像素横坐标
int y = 0; // 变换后的像素纵坐标
for (long j = 0; j < (long)outHeight; j++)
{
for (long i = 0; i < (long)outWidth; i++)
{
x = (int)(i * fCos + j * fSin + num1 + 0.5);
y = (int)(-i * fSin + j * fCos + num2 + 0.5);
// 修正坐标
if (x == width)
x--;
if (y == height)
y--;
copyPixel = pixel + y * width * 4 + x * 4;
objPixel = tempPixel + j * outWidth * 4 + i * 4;
if (x >= 0 && x < width && y >= 0 && y < height)
memcpy(objPixel, copyPixel, 4);
}
}
}
/******************************************************************************
* 作用: 图像的旋转函数(双线性插值法)
* 参数:
* pixel 原始像素数组
* tempPixel 保存变换后图像的像素数组
* width 原始图像宽度
* height 原始图像高度
* outWidth [out]输出图像的宽度
* outHeight [out]输出图像的高度
* angle 旋转度数,以弧度表示
******************************************************************************/
void RotateInterpolation(BYTE* pixel, BYTE*& tempPixel, int width, int height,
UINT& outWidth, UINT& outHeight, double angle)
{
// 原始图像四个角的坐标
int srcX1, srcX2, srcX3, srcX4;
int srcY1, srcY2, srcY3, srcY4;
srcX1 = 0;
srcY1 = 0;
srcX2 = width - 1;
srcY2 = 0;
srcX3 = 0;
srcY3 = height - 1;
srcX4 = width - 1;
srcY4 = height - 1;
// 计算旋转角度的正弦和余弦值
double fSin = sin(angle);
double fCos = cos(angle);
// 图像经过旋转后四个角的坐标
double tranX1, tranX2, tranX3, tranX4;
double tranY1, tranY2, tranY3, tranY4;
tranX1 = fCos * srcX1 + fSin * srcY1;
tranY1 = -fSin * srcX1 + fCos * srcY1;
tranX2 = fCos * srcX2 + fSin * srcY2;
tranY2 = -fSin * srcX2 + fCos * srcY2;
tranX3 = fCos * srcX3 + fSin * srcY3;
tranY3 = -fSin * srcX3 + fCos * srcY3;
tranX4 = fCos * srcX4 + fSin * srcY4;
tranY4 = -fSin * srcX4 + fCos * srcY3;
// 计算旋转后图像的大小
outWidth = (UINT)( max( fabs(tranX4-tranX1), fabs(tranX3-tranX2) ) + 1.5 );
outHeight = (UINT)( max( fabs(tranY4-tranY1), fabs(tranY3-tranY2) ) + 1.5 );
tempPixel = new BYTE[outWidth * outHeight * 4];
memset(tempPixel, 255, outWidth * outHeight * 4);
//计算矩阵(2.9)中的两个常数,这样不用以后每次都计算了
double num1 = -0.5*outWidth*fCos - 0.5*outHeight*fSin + 0.5*width;
double num2 = 0.5*outWidth*fSin - 0.5*outHeight*fCos + 0.5*height;
BYTE* copyPixel = NULL; // 指向原始图像中需要拷贝像素的起始位置
BYTE* objPixel = NULL; // 指向被复制像素的起始位置
double x = 0.0; // 变换后的像素横坐标
double y = 0.0; // 变换后的像素纵坐标
long tempJ = 0; // 存储中间值,提高函数速度
for (long j = 0; j < (long)outHeight; j++)
{
tempJ = j * outWidth * 4;
for (long i = 0; i < (long)outWidth; i++)
{
x = i * fCos + j * fSin + num1;
y = -i * fSin + j * fCos + num2;
// 超界则计算下一个像素
if (x > width || x < 0 || y > height || y < 0)
continue;
objPixel = tempPixel + tempJ + i * 4;
// 距离当前点最近的四个点坐标
int x1, x2, y1, y2;
x1 = (int)x;
x2 = x1 + 1;
y1 = (int)y;
y2 = y1 + 1;
// 对应四个坐标像素的取值
BYTE clr1, clr2, clr3, clr4;
double u, v;
u = x - x1;
v = y - y1;
// 对于32位真彩色需要分别计算三原色
for (int k = 0; k < 3; k++)
{
// 如果坐标在图像的右下角
if ( (x >= width - 1) && (y >= height - 1) )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
objPixel[k] = clr1;
}
// 如果图像在最后一列外侧
else if ( x >= width - 1 )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr3 = pixel[(y2 * width + x1) * 4 + k]; // (x1, y2)
objPixel[k] = (BYTE)(clr1 * (1 - v) + clr3 * v);
}
// 如果图像在最后一行外侧
else if ( y >= height - 1 )
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr2 = pixel[(y1 * width + x2) * 4 + k]; // (x2, y1)
objPixel[k] = (BYTE)(clr1 * (1 - u) + clr2 * u);
}
else
{
clr1 = pixel[(y1 * width + x1) * 4 + k]; // (x1, y1)
clr2 = pixel[(y1 * width + x2) * 4 + k]; // (x2, y1)
clr3 = pixel[(y2 * width + x1) * 4 + k]; // (x1, y2)
clr4 = pixel[(y2 * width + x2) * 4 + k]; // (x2, y2)
double f1, f2;
f1 = clr1 * (1 - u) + clr2 * u;
f2 = clr3 * (1 - u) + clr4 * u;
objPixel[k] = (BYTE)(f1 * (1 - v) + f2 * v);
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -