Вы можете рассчитать MD5 / SHA1 изображения и сохранить его в отдельном столбце таблицы, затем, когда вы придете, чтобы проверить, существует ли изображение, вы рассчитаете MD5 / SHA1 текущего изображения, а затем убедитесь, что оно соответствуетв базе данных.Максимальный размер MD5 / SHA1 должен составлять около 50 символов, и он должен быть уникальным для каждого изображения (столкновения MD5 наблюдались, и я думаю, что SHA1 также имел место, но вряд ли вы вставите миллионы изображений в вашу БД).
Ваша таблица будет выглядеть следующим образом:
ID INT
Image VARBINARY(MAX)
ImageHash VARCHAR(50)
плюс любые другие необходимые вам столбцы.
Чтобы рассчитать MD5 / SHA1 для изображения, вы будете использовать это:
public string CalculateHash(string filename)
{
SHA1CryptoServiceProvider crypt = new SHA1CryptoServiceProvider();
//MD5CryptoServiceProvider crypt = new MD5CryptoServiceProvider();
string hash = string.Empty;
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
byte[] checksum = crypt.ComputeHash(fs);
foreach (byte b in checksum)
hash += b.ToString("X2");
}
return(hash);
}
Приведенный выше метод использует криптографический расчет SHA1.Если вы предпочитаете использовать MD5 (немного быстрее), закомментируйте строку SHA1 и раскомментируйте строку MD5.
Call it with:
string filehash = CalculateHash(@"C:\myimagefile.jpg");
Затем, когда вы хотите проверить, вставлено ли ваше изображение, вы можете использовать запрос:
SELECT COUNT(0) FROM employee_product WHERE ImageHash = @ImageHash
Установите параметр вашего запроса на:
cmd.Parameters.Add("@ImageHash", SqlDbType.Varchar, 50);
cmd.Parameters["@ImageHash"].Value = filehash;
Затем вызовите:
int result = (int)cmd.ExecuteScalar();
if (result == 0)
{
// Insert your image, don't forget to insert the filehash into the ImageHash column or subsequent checks will always fail.
}
Это гораздо более быстрый способ проверить, что изображениесуществует, поскольку вы отправляете в базу данных только 50 символов для проверки, а не целое изображение.
Таким образом, вы создадите новый метод для поиска в базе данных наличия изображения:
public bool ImageExists(string filehash)
{
bool result = false;
using (SqlConnection connection = SQLConnection.GetConnection())
{
using (SqlCommand cmd = new SqlCommand("SELECT COUNT(0) FROM employee_product WHERE ImageHash = @ImageHash", connection))
{
connection.Open();
int imagecount = (int)cmd.ExecuteScalar();
result = imagecount == 0;
connection.Close();
}
}
return(result);
}
Затем в вашем методе AddProduct непосредственно перед этой строкой:
using (var select = new SqlCommand("Insert into employee_product (Image, ID, Supplier, Codeitem, Itemdescription, Date, Quantity, Unitcost) Values (@Image, @ID, @Supplier, @Codeitem, @Itemdescription, @Date, @Quantity, @Unitcost)", con))
Вы можете вставить:
string filehash = CalculateHash(imagefilename);
if (ImageExists(filehash)
{
MessageBox.Show("Image already exists");
return;
}
// the rest of your code goes here including adding a parameter to take the ImageHash.
Когда вы читаете файл образа с диска (я предполагаю, что этооткуда вы получаете изображение), тогда вы можете сохранить имя файла в объекте PictureBox.Tag.Затем извлеките это имя файла (включая путь) из PictureBox.Tag и передайте его в ImageExists:
string filehash = CalculateHash(pictureBox1.Tag.ToString());
Чтобы поместить имя файла в поле для рисунков, используйте:
using(OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(ofd.FileName);
pictureBox1.Tag = ofd.FileName;
}
}
В качестве альтернативы вы можетеВыполните вычисление хеша, когда пользователь загружает изображение и сохраняет его в теге:
using(OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(ofd.FileName);
pictureBox1.Tag = CalculateHash(ofd.FileName);
}
}
Затем при вызове ImageExists
используйте:
if (ImageExists(pictureBox1.Tag.ToString()))
{
MessageBox.Show("image exists");
return;
}