您的位置:首页 > 其它

图片内存复制性能对比

2016-06-15 16:41 218 查看
在绘图过程中,可能存在局部绘制,需要把一个图片区域块 copy 到另一图形内部。
针对常用的几种操作方式对比。

本次比较对象为 BitBlt 与 LockBits 方式

BitBlt 实现:

private void SnapShot(Bitmap des, Bitmap bitmapsrc)
{
IntPtr dc;
IntPtr dc1;
IntPtr dcbitmap;
Graphics g;

//绘制目标区域
Graphics g1 = System.Drawing.Graphics.FromImage(des);
dc1 = g1.GetHdc();

//源图与设备关联
g = System.Drawing.Graphics.FromImage(bitmapsrc);
dc = CreateCompatibleDC(g.GetHdc());
IntPtr pOrig = SelectObject(dc, dcbitmap = bitmapsrc.GetHbitmap());

for (int i = 0; i < redraw; i++)
BitBlt(dc1, 0, 0, bitmapsrc.Width, bitmapsrc.Height, dc, 0, 0, TernaryRasterOperations.SRCCOPY);

DeleteDC(dc);
DeleteObject(dcbitmap);
g1.ReleaseHdc(dc1);
g1.Dispose();
}


调用代码:

private void button4_Click(object sender, EventArgs e)
{
Bitmap bitmapCopy = new Bitmap(bitmap.Width, bitmap.Height);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
SnapShot(bitmapCopy, bitmap);
stopWatch.Stop();
Console.WriteLine("bitblt 时间刻度:{0} {1}ms", stopWatch.ElapsedTicks, stopWatch.ElapsedMilliseconds);
bitmapCopy.Save(@"C:\Users\zhoupeng\Pictures\testbitblt.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}


LockBits 方式实现:

private void CopyImage(Bitmap des, Bitmap bitmapsrc) {
Rectangle rect = new Rectangle(0, 0, des.Width, des.Height);
System.Drawing.Imaging.BitmapData bmpData =
des.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bitmapsrc.PixelFormat);

System.Drawing.Imaging.BitmapData bmpDataSrc =
bitmapsrc.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bitmapsrc.PixelFormat);

unsafe
{
for (int j = 0; j < redraw; j++)
{
byte* ptrdes = (byte*)bmpData.Scan0;
byte* ptrsrc = (byte*)bmpDataSrc.Scan0;
int width = bmpDataSrc.Stride;
for (int i = 0; i < rect.Height; i++)
{
for (int l = 0; l < width; l++)
{
ptrdes[l] = ptrsrc[l];
}

ptrdes += width;
ptrsrc += width;
}
}
}
bitmapsrc.UnlockBits(bmpDataSrc);
des.UnlockBits(bmpData);

}


LockBits 方式 调用:

private void button5_Click(object sender, EventArgs e)
{
Bitmap bitmapCopy = new Bitmap(bitmap.Width, bitmap.Height);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
CopyImage(bitmapCopy, bitmap);
stopWatch.Stop();
Console.WriteLine("bit copy 时间刻度:{0} {1}ms", stopWatch.ElapsedTicks, stopWatch.ElapsedMilliseconds);

bitmapCopy.Save(@"C:\Users\zhoupeng\Pictures\testbitcopy.jpg", System.Drawing.Imaging.ImageFormat.Bmp);
}


由于两种方式 初使化方式不一样,本例尝试乎略这些步骤,这里使用 redraw 变量差异化工作量,分别测试两种性能.

redraw = 1 结果:
bitblt 时间刻度:818184 81ms
bit copy 时间刻度:401926 40ms

redraw = 2 结果:
bitblt 时间刻度:652939 65ms
bit copy 时间刻度:588758 58ms

redraw = 3 结果:
bitblt 时间刻度:689693 68ms
bit copy 时间刻度:804597 80ms

redraw = 5 结果:
bitblt 时间刻度:858016 85ms
bit copy 时间刻度:1196078 119ms

redraw = 15 结果:
bitblt 时间刻度:1062028 106ms
bit copy 时间刻度:3279949 327ms

redraw = 100 结果:
bitblt 时间刻度:1707719 170ms
bit copy 时间刻度:19362181 1936ms
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: