图像的平移
private void translationBtn_Click(object sender, EventArgs e)
{
if (curBitmap != null)
{
//实例化translation窗口体
translation traForm = new translation();
if (traForm.ShowDialog() == DialogResult.OK)
{
Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect,
System.Drawing.Imaging.ImageLockMode.ReadWrite,
curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * curBitmap.Height;//图像的跨度curBitmap.Width并不一定是其实际像素宽度
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
//得到两个方向的图像平移量
int x = Convert.ToInt32(traForm.GetXOffset);
int y = Convert.ToInt32(traForm.GetYOffset);
byte[] tempArray = new byte[bytes];
//临时数组初始化为白色像素
for (int i = 0; i < bytes; i++)
{
tempArray[i] = 255;
}
//平移运算
for (int i = 0; i < curBitmap.Height; i++)
{
//保证纵向平移不出界
if ( (i + y) < curBitmap.Height && (i + y) > 0 )
{
for (int j = 0; j < bmpData.Stride; j++)
{
//保证横向不出界
if ((j + x) < bmpData.Stride && (j + x) > 0)
{
//应用公式
tempArray[(j + x) + (i + y) * bmpData.Stride] =
grayValues[j + i * bmpData.Stride];
}
}
}
}
//数组复制,返回平移后的图像
grayValues = (byte[])tempArray.Clone();
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
Invalidate();
}
}
//图像镜像变换
private void mirrorBtn_Click(object sender, EventArgs e)
{
if (curBitmap != null)
{
//实例化mirror窗口体
Mirror mirForm = new Mirror();
if (mirForm.ShowDialog() == DialogResult.OK)
{
Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect,
System.Drawing.Imaging.ImageLockMode.ReadWrite,
curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmpData.Height;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
//水平中轴
int halfWidth = bmpData.Stride / 2;
//垂直中轴
int halfHeight = curBitmap.Height / 2;
byte temp;
if (mirForm.GetMirror)
{
//水平镜像处理
for (int i = 0; i < curBitmap.Height; i++)
{
for (int j = 0; j < halfWidth; j++)
{
//以水平中轴为对称轴, 两边的像素值互换
temp = grayValues[i * bmpData.Stride + j];
grayValues[i * bmpData.Stride + j] =
grayValues[(i + 1) * bmpData.Stride - j - 1];
grayValues[(i + 1) * bmpData.Stride - 1 - j] = temp;
}
}
}
else
{
//垂直镜像处理
for (int i = 0; i < bmpData.Stride; i++)
{
for (int j = 0; j < halfHeight; j++)
{
//以垂直中轴为对称轴, 两边的像素值互换
temp = grayValues[j * bmpData.Stride + i];
grayValues[j * bmpData.Stride + i] =
grayValues[(curBitmap.Height - j - 1) * bmpData.Stride + i];
grayValues[(curBitmap.Height - j - 1) * bmpData.Stride + i] =
temp;
}
}
}
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
Invalidate();
}
}
//图像缩放
private void zoomBtn_Click(object sender, EventArgs e)
{
if (curBitmap != null)
{
//实例化zoom窗口
zoom zoomForm = new zoom();
if (zoomForm.ShowDialog() == DialogResult.OK)
{
Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
System.Drawing.Imaging.BitmapData bmpdata = curBitmap.LockBits(rect,
System.Drawing.Imaging.ImageLockMode.ReadWrite,
curBitmap.PixelFormat);
IntPtr ptr = bmpdata.Scan0;
int bytes = bmpdata.Stride * curBitmap.Height;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
//得到横纵缩放量
double x = Convert.ToDouble(zoomForm.GetXZoom);
double y = Convert.ToDouble(zoomForm.GetYZoom);
//图像的几何中心
int halfWidth = (int)Convert.ToDouble(bmpdata.Stride / 2);
int halfHeight = (int)Convert.ToDouble(curBitmap.Height / 2);
int xz = 0;
int yz = 0;
int tempWidth = 0;
int tempHeight = 0;
byte[] tempArray = new byte[bytes];
if (zoomForm.GetNearOrBil == true)
{
//最近邻插值法
for (int i = 0; i < curBitmap.Height; i++)
{
for (int j = 0; j < bmpdata.Stride; j++)
{
//以图像的几何中心为坐标原点进行坐标变化
//按逆向映射法得到输入图像坐标
tempHeight = i - halfHeight;
tempWidth = j - halfWidth;
//在不同象限里进行四舍五入处理,得到缩放后像素点到中心点的距离
if (tempWidth > 0)
{
xz = (int)(tempWidth / x + 0.5);
}
else
{
xz = (int)(tempWidth / x - 0.5);
}
if (tempHeight > 0)
{
yz = (int)(tempHeight / y + 0.5);
}
else
{
yz = (int)(tempHeight / y - 0.5);
}
//坐标变换,得到缩放后像素的位置
tempWidth = xz + halfWidth;
tempHeight = yz + halfHeight;
//得到输出图像像素值
if (tempWidth < 0 || tempWidth >= bmpdata.Stride ||
tempHeight < 0 || tempHeight >= curBitmap.Height)
{
//缩放后留下的空白部分用白色像素代替
tempArray[i * bmpdata.Stride + j] = 255;
}
else
{
tempArray[i * bmpdata.Stride + j] =
grayValues[tempHeight * bmpdata.Stride + tempWidth];
}
}
}
}
else
{
//双线性插值法
double tempX, tempY, p, q;
for (int i = 0; i < curBitmap.Height; i++)
{
for (int j = 0; j < bmpdata.Stride; j++)
{
//以图像的几何中心为坐标原点进行坐标变化
//按逆向映射法的到输入图像的坐标
tempHeight = i - halfHeight;
tempWidth = j - halfWidth;
tempX = tempWidth / x;
tempY = tempHeight / y;
//在不同象限进行取整处理
if (tempWidth > 0)
{
xz = (int)tempX;
}
else
{
xz = (int)(tempX - 1);
}
if (tempHeight > 0)
{
yz = (int)tempY;
}
else
{
yz = (int)(tempY - 1);
}
//得到公式中的变量p和q
p = tempX - xz;
q = tempY - yz;
//坐标变换
tempWidth = xz + halfWidth;
tempHeight = yz + halfHeight;
if (tempWidth < 0 || (tempWidth + 1) >= bmpdata.Stride ||
tempHeight < 0 || (tempHeight + 1) >= curBitmap.Height)
{
//缩放后留下的空白部分用白色像素代替
tempArray[i * bmpdata.Stride + j] = 255;
}
else
{
//应用公式得到双线性插值
tempArray[i * bmpdata.Stride + j] =
(byte)(
(1.0 - q) * (
(1.0 - p) * grayValues[tempHeight * bmpdata.Stride + tempWidth]
+
p * grayValues[tempHeight * bmpdata.Stride + tempWidth + 1]
)
+
q *
(
(1.0 - q) * grayValues[(tempHeight + 1) * bmpdata.Stride + tempWidth]
+
p * grayValues[(tempHeight + 1) * bmpdata.Stride + 1 + tempWidth]
)
);
}
}
}
}
grayValues = (byte[])tempArray.Clone();
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpdata);
}
Invalidate();
}