程序的目的是把一段16bit的黑白bitmap对象按位转成一个byte[],代码如下:
private void PrintBitmap(ref Bitmap bmp, bool start, int start_sleep, bool stop, int stop_sleep)
{
int btsLenght=(104 + 104 / 2) * bmp.Width;
if (PrintString)
btsLenght *= 2;
byte[] bts = new byte[btsLenght];
int DataLenght = 0;
byte[] OrBytes = new byte[8];
for (int i = 7; i >= 0; i--)
{
OrBytes[i] = (byte)(1 << i);
}
int TempBufferLenght = PrintDataLength * 3 / 2;
byte[] TempBuffer = new byte[TempBufferLenght]; int bmp_width = bmp.Width;
int bmp_height = bmp.Height; Rectangle rect = new Rectangle(0, 0, bmp_width, bmp_height); //下面用非托管代码,指针操作
unsafe
{
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
short* ptr_begin = (short*)bmpData.Scan0;
short* ptr = ptr_begin; Stopwatch wc = new Stopwatch();
wc.Start();//开始测试执行时间
for (int x_value = 0; x_value < bmp_width; x_value++)
{
int i = 0;
int j = 0;
Array.Clear(TempBuffer, 0, TempBufferLenght);
TempBuffer[j] = 0xfe;//头
TempBuffer[j + 1] = 0x01;//打印属性标志
j += 2; for (int y_value = 0; y_value < BitmapHeight; y_value++)
{
ptr = ptr_begin;
ptr += (y_value * bmp_width + x_value);//当前像素的地址
if (*ptr == 0)
{
TempBuffer[j] |= OrBytes[i];
if ((TempBuffer[j] == 0xfd) || (TempBuffer[j] == 0xfe) || (TempBuffer[j] == 0xff))
{
TempBuffer[j + 1] = (byte)(TempBuffer[j] ^ 0x20);
TempBuffer[j] = 0xfd;
j++;
}
}
i++;
if (i == 8)
{
j++;
i = 0;
}
}
TempBuffer[j] = 0xff;
byte[] DataBuffer = new byte[j + 1];
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
if (PrintString)
{
DataLenght += (j + 1);
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
}
DataLenght += (j + 1);
}
bmp.UnlockBits(bmpData);
wc.Stop();//结束测试执行时间
MessageBox.Show(wc.ElapsedMilliseconds.ToString());
PrintSerial.WritePort(bts, DataLenght);
}
}在2440平台上测试运行时间为:1700多ms 如果改成下面的代码,速度就提高到400多ms ,难道C#访问内存速度会如此之慢?真是难以理解。按说用指针直接访问内存不会有那么大的差别呀。(为了提速,指针访问方式是从short[]访问方式改过来的,托管方式一样慢)
private void PrintBitmap(ref Bitmap bmp, bool start, int start_sleep, bool stop, int stop_sleep)
{
int btsLenght=(104 + 104 / 2) * bmp.Width;
if (PrintString)
btsLenght *= 2;
byte[] bts = new byte[btsLenght];
int DataLenght = 0;
byte[] OrBytes = new byte[8];
for (int i = 7; i >= 0; i--)
{
OrBytes[i] = (byte)(1 << i);
}
int TempBufferLenght = PrintDataLength * 3 / 2;
byte[] TempBuffer = new byte[TempBufferLenght]; int bmp_width = bmp.Width;
int bmp_height = bmp.Height; Rectangle rect = new Rectangle(0, 0, bmp_width, bmp_height);
//下面用非托管代码,指针操作
unsafe
{
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
short* ptr_begin = (short*)bmpData.Scan0;
short* ptr = ptr_begin; Stopwatch wc = new Stopwatch();
wc.Start();//开始测试执行时间
for (int x_value = 0; x_value < bmp_width; x_value++)
{
int i = 0;
int j = 0;
Array.Clear(TempBuffer, 0, TempBufferLenght);
TempBuffer[j] = 0xfe;//头
TempBuffer[j + 1] = 0x01;//打印属性标志
j += 2; for (int y_value = 0; y_value < BitmapHeight; y_value++)
{
ptr = ptr_begin;
ptr += (y_value * bmp_width + x_value);//当前像素的地址
int iii = 1000;// *ptr;//
if (iii == 0)
{
TempBuffer[j] |= OrBytes[i];
if ((TempBuffer[j] == 0xfd) || (TempBuffer[j] == 0xfe) || (TempBuffer[j] == 0xff))
{
TempBuffer[j + 1] = (byte)(TempBuffer[j] ^ 0x20);
TempBuffer[j] = 0xfd;
j++;
}
}
i++;
if (i == 8)
{
j++;
i = 0;
}
}
TempBuffer[j] = 0xff;
byte[] DataBuffer = new byte[j + 1];
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
if (PrintString)
{
DataLenght += (j + 1);
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
}
DataLenght += (j + 1);
}
bmp.UnlockBits(bmpData);
wc.Stop();//结束测试执行时间
PrintSerial.WritePort(bts, DataLenght);
}
}
private void PrintBitmap(ref Bitmap bmp, bool start, int start_sleep, bool stop, int stop_sleep)
{
int btsLenght=(104 + 104 / 2) * bmp.Width;
if (PrintString)
btsLenght *= 2;
byte[] bts = new byte[btsLenght];
int DataLenght = 0;
byte[] OrBytes = new byte[8];
for (int i = 7; i >= 0; i--)
{
OrBytes[i] = (byte)(1 << i);
}
int TempBufferLenght = PrintDataLength * 3 / 2;
byte[] TempBuffer = new byte[TempBufferLenght]; int bmp_width = bmp.Width;
int bmp_height = bmp.Height; Rectangle rect = new Rectangle(0, 0, bmp_width, bmp_height); //下面用非托管代码,指针操作
unsafe
{
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
short* ptr_begin = (short*)bmpData.Scan0;
short* ptr = ptr_begin; Stopwatch wc = new Stopwatch();
wc.Start();//开始测试执行时间
for (int x_value = 0; x_value < bmp_width; x_value++)
{
int i = 0;
int j = 0;
Array.Clear(TempBuffer, 0, TempBufferLenght);
TempBuffer[j] = 0xfe;//头
TempBuffer[j + 1] = 0x01;//打印属性标志
j += 2; for (int y_value = 0; y_value < BitmapHeight; y_value++)
{
ptr = ptr_begin;
ptr += (y_value * bmp_width + x_value);//当前像素的地址
if (*ptr == 0)
{
TempBuffer[j] |= OrBytes[i];
if ((TempBuffer[j] == 0xfd) || (TempBuffer[j] == 0xfe) || (TempBuffer[j] == 0xff))
{
TempBuffer[j + 1] = (byte)(TempBuffer[j] ^ 0x20);
TempBuffer[j] = 0xfd;
j++;
}
}
i++;
if (i == 8)
{
j++;
i = 0;
}
}
TempBuffer[j] = 0xff;
byte[] DataBuffer = new byte[j + 1];
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
if (PrintString)
{
DataLenght += (j + 1);
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
}
DataLenght += (j + 1);
}
bmp.UnlockBits(bmpData);
wc.Stop();//结束测试执行时间
MessageBox.Show(wc.ElapsedMilliseconds.ToString());
PrintSerial.WritePort(bts, DataLenght);
}
}在2440平台上测试运行时间为:1700多ms 如果改成下面的代码,速度就提高到400多ms ,难道C#访问内存速度会如此之慢?真是难以理解。按说用指针直接访问内存不会有那么大的差别呀。(为了提速,指针访问方式是从short[]访问方式改过来的,托管方式一样慢)
private void PrintBitmap(ref Bitmap bmp, bool start, int start_sleep, bool stop, int stop_sleep)
{
int btsLenght=(104 + 104 / 2) * bmp.Width;
if (PrintString)
btsLenght *= 2;
byte[] bts = new byte[btsLenght];
int DataLenght = 0;
byte[] OrBytes = new byte[8];
for (int i = 7; i >= 0; i--)
{
OrBytes[i] = (byte)(1 << i);
}
int TempBufferLenght = PrintDataLength * 3 / 2;
byte[] TempBuffer = new byte[TempBufferLenght]; int bmp_width = bmp.Width;
int bmp_height = bmp.Height; Rectangle rect = new Rectangle(0, 0, bmp_width, bmp_height);
//下面用非托管代码,指针操作
unsafe
{
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
short* ptr_begin = (short*)bmpData.Scan0;
short* ptr = ptr_begin; Stopwatch wc = new Stopwatch();
wc.Start();//开始测试执行时间
for (int x_value = 0; x_value < bmp_width; x_value++)
{
int i = 0;
int j = 0;
Array.Clear(TempBuffer, 0, TempBufferLenght);
TempBuffer[j] = 0xfe;//头
TempBuffer[j + 1] = 0x01;//打印属性标志
j += 2; for (int y_value = 0; y_value < BitmapHeight; y_value++)
{
ptr = ptr_begin;
ptr += (y_value * bmp_width + x_value);//当前像素的地址
int iii = 1000;// *ptr;//
if (iii == 0)
{
TempBuffer[j] |= OrBytes[i];
if ((TempBuffer[j] == 0xfd) || (TempBuffer[j] == 0xfe) || (TempBuffer[j] == 0xff))
{
TempBuffer[j + 1] = (byte)(TempBuffer[j] ^ 0x20);
TempBuffer[j] = 0xfd;
j++;
}
}
i++;
if (i == 8)
{
j++;
i = 0;
}
}
TempBuffer[j] = 0xff;
byte[] DataBuffer = new byte[j + 1];
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
if (PrintString)
{
DataLenght += (j + 1);
Buffer.BlockCopy(TempBuffer, 0, bts, DataLenght, j + 1);
}
DataLenght += (j + 1);
}
bmp.UnlockBits(bmpData);
wc.Stop();//结束测试执行时间
PrintSerial.WritePort(bts, DataLenght);
}
}
if (iii == 0)
是否if (*ptr == 0)这个条件实际成立了,而下面的是始终不成立的。
和int iii = 1000;// ;//
if (iii == 0)
对于*ptr 你的像素有白色的 就会成立的另外图片 还有空白空间的
你可以使用*ptr
当然 需要真实的环境中去运行的,如果在模拟器中运行的话。ptr肯定慢点、。