از کدهای زیر برای مقایسه استفاده کنید:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ShowChanges();
Application.Exit();
}
private void ShowChanges()
{
DateTime dt = DateTime.Now;
Bitmap b1 = new Bitmap("1.jpg");
Bitmap b2 = new Bitmap("2.jpg");
int iLength = b1.Size.Width;
int jLength = b1.Size.Height;
int differents = 0;
float percent;
if (b1.Size == b2.Size)
{
for (int i = 0; i < iLength; i++)
for (int j = 0; j < jLength; j++)
if (b1.GetPixel(i, j).ToArgb() != b2.GetPixel(i, j).ToArgb())
differents++;
}
percent = (float)differents / b1.Size.Width / b1.Size.Height * 100;
TimeSpan ts = DateTime.Now - dt;
MessageBox.Show(ts.TotalSeconds.ToString("00.00") + " Second\n\n" + percent.ToString("00.00") + "%");
}
}
}
اما کدهای فوق، اصلا سریع نیستند، برای مقایسه دو تصویر 400 در 300 باید حدود 10 ثانیه منتظر بمانید...
بهرحال از کدهای فوق استفاه نکنید بهتره!
اما برخلاف کدهای فوق، کدهای زیر آنچنان با سرعت عملیات مقایسه را انجام می دهند که گویا اصلا مقایسه ائی صورت نگرفته! برای مقایسه دو تصویر 400 در 300 توسط کدهای زیر، تنها 0.05 ثانیه (5 صدم ثانیه!) منتظر خواهید ماند! و به این می گن سرعت استفاده از اشاره گرها!
نمی دونم چرا خیلی ها اشاره گرها رو نادیده می گیرند و جزئی از قابلیتهای سی شارپ به حساب نمی آورند ولی ...
بهر حال، توسط کدهای زیر، دو تصویر رو مورد مقایسه قرار بدید که تنها 0.05 ثانیه زمان میگیره.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ShowChanges();
Application.Exit();
}
private unsafe void ShowChanges()
{
DateTime dt = DateTime.Now;
Bitmap b1 = new Bitmap("1.jpg");
Bitmap b2 = new Bitmap("2.jpg");
int iLength = b1.Size.Width;
int jLength = b1.Size.Height;
int differents = 0;
float percent;
UnsafeBitmap ub1 = new UnsafeBitmap(b1);
UnsafeBitmap ub2 = new UnsafeBitmap(b2);
ub2.LockBitmap();
ub1.LockBitmap();
if (b1.Size == b2.Size)
{
for (int i = 0; i < iLength; i++)
for (int j = 0; j < jLength; j++)
if (ub1.PixelAt(i, j)->blue != ub2.PixelAt(i, j)->blue && ub1.PixelAt(i, j)->green != ub2.PixelAt(i, j)->green && ub1.PixelAt(i, j)->red != ub2.PixelAt(i, j)->red)
differents++;
}
ub1.UnlockBitmap();
ub2.UnlockBitmap();
percent = (float)differents / b1.Size.Width / b1.Size.Height * 100;
TimeSpan ts = DateTime.Now - dt;
MessageBox.Show(ts.TotalSeconds.ToString("00.00") + " Second\n\n" + percent.ToString("00.00") + "%");
}
}
public unsafe class UnsafeBitmap
{
Bitmap bitmap;
// three elements used for MakeGreyUnsafe
int width;
BitmapData bitmapData = null;
Byte* pBase = null;
public UnsafeBitmap(Bitmap bitmap)
{
this.bitmap = new Bitmap(bitmap);
}
public UnsafeBitmap(int width, int height)
{
this.bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
}
public void Dispose()
{
bitmap.Dispose();
}
public Bitmap Bitmap
{
get
{
return (bitmap);
}
}
private Point PixelSize
{
get
{
GraphicsUnit unit = GraphicsUnit.Pixel;
RectangleF bounds = bitmap.GetBounds(ref unit);
return new Point((int)bounds.Width, (int)bounds.Height);
}
}
public void LockBitmap()
{
GraphicsUnit unit = GraphicsUnit.Pixel;
RectangleF boundsF = bitmap.GetBounds(ref unit);
Rectangle bounds = new Rectangle((int)boundsF.X, (int)boundsF.Y, (int)boundsF.Width, (int)boundsF.Height);
// Figure out the number of bytes in a row
// This is rounded up to be a multiple of 4
// bytes, since a scan line in an image must always be a multiple of 4 bytes
// in length.
width = (int)boundsF.Width * sizeof(PixelData);
if (width % 4 != 0)
{
width = 4 * (width / 4 + 1);
}
bitmapData = bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
pBase = (Byte*)bitmapData.Scan0.ToPointer();
}
public void UnlockBitmap()
{
bitmap.UnlockBits(bitmapData);
bitmapData = null;
pBase = null;
}
public PixelData* PixelAt(int x, int y)
{
return (PixelData*)(pBase + y * width + x * sizeof(PixelData));
}
}
public struct PixelData
{
public byte blue;
public byte green;
public byte red;
}
}
فقط برای اینکه بتونید از کدهای فوق استفاده کنید، باید برنامه را در حالت unsafe mode کامپایل کنید.
در کدهای فوق، یک کلاس جدید پیاده سازی شده، که قبلا هم معرفیش کرده بودم، لینک منبع این کلاس هم اینه:
http://www.dreamincode.net/forums/in...6&#entry144886