private void translation_Click(object sender, EventArgs e) { if (curBitmap != null) { translation traForm = new translation(); #region 简单方法--像素法 //if (traForm.ShowDialog() == DialogResult.OK) //{ // // handleBitmap = (Bitmap) curBitmap.Clone(); // Color curColor; // int ret; // for (int i = 0; i < handleBitmap.Width; i++) // { // for (int j = 0; j < handleBitmap.Height; j++) // { // curColor = handleBitmap.GetPixel(i, j); // //ret = (int) (curColor.R*0.299 + curColor.G*0.587 + curColor.B*0.114); // ret = Convert.ToInt32(tb_FillColor.Text); // handleBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret)); // } // } //} //Invalidate(); //return; #endregion #region 原始方法 if (traForm.ShowDialog() == DialogResult.OK) { // offsetOPbyMemory(traForm); offsetOPbyPointer(traForm); } Invalidate(); #endregion tb_timer.Text = timercount.Duration.ToString("####.##") + " 毫秒"; } }
private void translation_Click(object sender, EventArgs e) { if (curBitmap != null) { 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 = curBitmap.Width * curBitmap.Height; 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]; //Array.Clear(tempArray, 0, 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 < curBitmap.Width; j++) { if ((j + x) < curBitmap.Width && (j + x) > 0) { tempArray[(j + x) + (i + y) * curBitmap.Width] = grayValues[j + i * curBitmap.Width]; } } } } grayValues = (byte[])tempArray.Clone(); System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } }
private void offsetOPbyMemory(translation traForm) { 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); System.Drawing.Imaging.BitmapData handlebmpData = handleBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; IntPtr ptrhandle = handlebmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; 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]; //Array.Clear(tempArray, 0, bytes); for (int i = 0; i < bytes; i++) { tempArray[i] = 195; } for (int i = 0; i < curBitmap.Height; i++) { if ((i + y) < curBitmap.Height && (i + y) > 0) { for (int j = 0; j < curBitmap.Width; j++) { if ((j + x) < curBitmap.Width && (j + x) > 0) { tempArray[(j + x) + (i + y) * curBitmap.Width] = grayValues[j + i * curBitmap.Width]; } } } } grayValues = (byte[])tempArray.Clone(); System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); }
private void offsetOPbyPointer(translation traForm) { #region 使用指针法来操作 handleBitmap = (Bitmap)curBitmap.Clone(); Rectangle rect = new Rectangle(0, 0, handleBitmap.Width, handleBitmap.Height); System.Drawing.Imaging.BitmapData handlebmpData = handleBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, handleBitmap.PixelFormat); byte valueColor = Convert.ToByte(tb_FillColor.Text); int tempbytelength = handlebmpData.Stride * handlebmpData.Height; int x = Convert.ToInt32(traForm.GetXOffset); int y = Convert.ToInt32(traForm.GetYOffset); timercount.ClearTimer(); timercount.Start(); //进入非托管代码模式 unsafe { //tempbyte属于C#中标准的字节数组,属于安全的代码。 byte[] tempbyte = new byte[tempbytelength]; for (int i = 0; i < tempbytelength; i++) { tempbyte[i] = valueColor; } //声明一个byte 指针(byte* 属于不安全的指针,只能用在非托管代码中) ptr ,并获得BitmapData对象的首地址值 byte *ptr = (byte *)(handlebmpData.Scan0); //不进行内存法的复制过程,直接操作内存。循环迭代图像的宽高二维数组 int count = 0; int startP = y * handlebmpData.Stride + x * pixeldepth; //背景已经准备好,进行复制 for (int i = y; i < handlebmpData.Height; i++) { for (int j = x; j < handlebmpData.Width; j++) { for (int k = 0; k < pixeldepth; k++) { tempbyte[startP + count + k] = ptr[k]; } ptr += pixeldepth; count += pixeldepth; #region 简单的方法 //if (pixeldepth==1) //{ // tempbyte[startP + count] = ptr[0]; // ptr += 1; // count += 1; //} //if (pixeldepth == 3) //{ // tempbyte[startP + count] = ptr[0]; // tempbyte[startP + count + 1] = ptr[1]; // tempbyte[startP + count + 2] = ptr[2]; // ptr += 3; // count += 3; //} //if (pixeldepth == 4) //{ // tempbyte[startP + count] = ptr[0]; // tempbyte[startP + count + 1] = ptr[1]; // tempbyte[startP + count + 2] = ptr[2]; // tempbyte[startP + count + 3] = ptr[3]; // ptr += 4; // count += 4; //} #endregion } ptr = (byte *)(handlebmpData.Scan0); ptr += handlebmpData.Stride * (i - y + 1); count = handlebmpData.Stride * (i - y + 1); //下面这句很重要,但完成一次Width方向的内循环时,ptr指针该如何增加?Width应该是4的整数倍,否则将会被舍入到4的整数倍 //例如: 1024*3=3072 可以被4整除 ptr+0即可, 但1023*3=3069不能被4整除,这时候其实需要使用BitmapData.stride 属性获得被4除的跨距宽度,减去实际图像的字节宽度。 //下面的计算表达式对于实际图像像宽为4的整数倍的图片来说,结果为0. } //将背景部分再复制回来 count = 0; ptr = (byte *)(handlebmpData.Scan0); for (int i = 0; i < tempbyte.Length; i++) { ptr[i] = tempbyte[i]; } //for (int i = 0; i < handlebmpData.Height; i++) //{ // for (int j = 0; j < handlebmpData.Width; j++) // { // ptr[0] = tempbyte[count]; // ptr[1] = tempbyte[count+1]; // ptr[2] = tempbyte[count+2]; // ptr += 3; // count = +3; // //byte temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]); // //ptr[0] = ptr[1] = ptr[2] = temp; // //ptr += 3; // } // ptr += increased; // //下面这句很重要,但完成一次Width方向的内循环时,ptr指针该如何增加?Width应该是4的整数倍,否则将会被舍入到4的整数倍 // //例如: 1024*3=3072 可以被4整除 ptr+0即可, 但1023*3=3069不能被4整除,这时候其实需要使用BitmapData.stride 属性获得被4除的跨距宽度,减去实际图像的字节宽度。 // //下面的计算表达式对于实际图像像宽为4的整数倍的图片来说,结果为0. //} } //非托管代码执行完毕后,BitmapData对象需要切换回托管模式 handleBitmap.UnlockBits(handlebmpData); timercount.Stop(); #endregion }