Как хранить фото в бд

Хранение изображений в сетевом каталоге

Как хранить фото в бд
Попробую сделать такой функционал в типовой конфигурации УПП (УТ, КА) Опишу вкратце действия шаг за шагом но если что-то сложно написал, заранее прошу прощения.    

1. Создаю константу ПутьККартинкамНаСервере. В нее пишу полный путь к сетевому каталогу. Выполняем код: Константы.ПутьККартинкамНаСервере.Установить(“\\ВашПуть\”);

2. Создаю регистр сведений  ИзображенияНоменклатуры с двумя измерениями Объект (Справочник.Номенклатура), Путь (Строка, 255) и реквизитом Основное (Булево).

3. В регистр сведений  ИзображенияНоменклатуры добавляю основную форму записи. После на форму кнопку ИзменитьКартинку. В модуль формы пишу код листинга 1.0 и привяжем событие Нажатие на кнопку.//листинг 1.0 Функция КоличествоКартинок(Объект) Запрос = Новый Запрос; Запрос.Текст = “ВЫБРАТЬ | ИзображенияНоменклатуры.Объект КАК Объект |ИЗ | РегистрСведений.ИзображенияНоменклатуры КАК ИзображенияНоменклатуры |ГДЕ | ИзображенияНоменклатуры.Объект = &Объект”; Запрос.УстановитьПараметр(“Объект”,Объект); Результат = Запрос.Выполнить().Выгрузить(); Возврат Результат.Количество(); КонецФункции Функция ПолучитьЧастьСтрокиОтделеннойСимволом(Знач ИсходнаяСтрока, Знач СимволПоиска) ПозицияСимвола = СтрДлина(ИсходнаяСтрока); Пока ПозицияСимвола >= 1 Цикл Если Сред(ИсходнаяСтрока, ПозицияСимвола, 1) = СимволПоиска Тогда Возврат Сред(ИсходнаяСтрока, ПозицияСимвола + 1); КонецЕсли; ПозицияСимвола = ПозицияСимвола – 1; КонецЦикла; Возврат “”; КонецФункции Процедура ИзменитьКартинкуНажатие(Элемент) СтандартнаяОбработка = ложь; ПутьКСерверу = Константы.ПутьККартинкамНаСервере.Получить(); ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); ДиалогОткрытияФайла.Заголовок = “Выберите файл с изображением”; ДиалогОткрытияФайла.ПолноеИмяФайла = “”; ДиалогОткрытияФайла.ПредварительныйПросмотр = Истина; Фильтр = “(*.jpg)|*.jpg,(*.png)|*.png”; Если ДиалогОткрытияФайла.Выбрать() Тогда ВыбранноеИзображение = ДиалогОткрытияФайла.ПолноеИмяФайла; Иначе Возврат; КонецЕсли; Артикул = Объект.Артикул; КолКарт = КоличествоКартинок(Объект); Расширение = ПолучитьЧастьСтрокиОтделеннойСимволом(ДиалогОткрытияФайла.ПолноеИмяФайла,”.”); Имякартинки = “NPhoto_”; Если КолКарт = 0 тогда ИмяНаСервере = Строка(Имякартинки)+СокрЛП(Артикул)+”.”+Расширение; Иначе ИмяНаСервере = Строка(Имякартинки)+СокрЛП(Артикул)+”_”+Строка(КолКарт)+”.”+Расширение; КонецЕсли; КопироватьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла, ПутьКСерверу+ИмяНаСервере); ПутьККартинке = ИмяНаСервере; Путь = ПутьККартинке; КонецПроцедуры 4. Добавляю общую форму ФормаИзображения с полем картинки ОсновноеИзображение и табличное поле Изображения которое будет содержать список для редактирования изображения. В модуле пишу листинг 2.0.  Далее в свойстве табличного поля указываю ТипЗначения: РегистрСведенийСписок.ИзображенияНоменклатуры и событие ИзображенияОбработкаЗаписиНовогоОбъекта. И обязательно привязать одноименное событие формы ПриОткрытии.  

//листинг 2.0 Перем мКартинки; Перем ПутьКСерверу; Процедура ПриОткрытии() УстОтбор(Изображения.Отбор,,”Объект”, ВладелецФормы.Ссылка, Истина); мКартинки = Добавленные.ПолучитьКартинкиИзРегистра(ВладелецФормы.Ссылка); Если мКартинки.количество() > 0 тогда ФайлКартинки = новый Файл(ПутьКСерверу+мКартинки[0].Путь); Если ФайлКартинки.Существует() и СтрДлина(мКартинки[0].Путь) > 0 тогда ЭлементыФормы.ОсновноеИзображение.картинка = новый Картинка(ПутьКСерверу+мКартинки[0].Путь); КонецЕсли; Иначе ЭлементыФормы.ОсновноеИзображение.картинка = новый Картинка(); КонецЕсли; ТекущиеИзображение = 0; КонецПроцедуры Процедура УстОтбор(Отбор,НастройкаОтбора=0,Поле=”Объект”,Значение,ОтключатьПустое=Ложь) Экспорт Если Отбор.Найти(Поле) = Неопределено Тогда Отбор.Добавить(Поле); КонецЕсли; Попытка Отбор[Поле].ВидСравнения=ВидСравнения.Равно; Исключение Отбор[Поле].ВидСравнения=ВидСравнения.Содержит; КонецПопытки; Отбор[Поле].Значение=Значение; Отбор[Поле].Использование=?(ОтключатьПустое,ЗначениеЗаполнено(Значение),Истина); Если ЗначениеЗаполнено(НастройкаОтбора) Тогда НастройкаОтбора[Поле].Доступность=Ложь; КонецЕсли; КонецПроцедуры Процедура ИзображенияОбработкаЗаписиНовогоОбъекта(Элемент, Объект, СтандартнаяОбработка) СтандартнаяОбработка = ложь; КонецПроцедуры функция ПолучитьКартинкиИзРегистра(объект) Запрос = Новый Запрос; Запрос.Текст = “ВЫБРАТЬ | ИзображенияНоменклатуры.Путь |ИЗ | РегистрСведений.ИзображенияНоменклатуры КАК ИзображенияНоменклатуры |ГДЕ | ИзображенияНоменклатуры.Объект = &Объект | |УПОРЯДОЧИТЬ ПО | ИзображенияНоменклатуры.Основное”; Запрос.УстановитьПараметр(“Объект”, Объект); Результат = Запрос.Выполнить().Выгрузить(); Возврат Результат; КонецФункции ПутьКСерверу = Константы.ПутьККартинкамНаСервере.Получить(); мКартинки = новый ТаблицаЗначений; 5. Идем в ФормуЭлемента номенклатуры и заменяем код в процедуре ОсновноеИзображениеНажатие(). Код в листинге 3.0//листинг 3.0 Процедура ОсновноеИзображениеНажатие(Элемент) //Если Не РаботаСДиалогами.ЗаписатьНовыйОбъектВФорме(ЭтаФорма) Тогда // Возврат; //КонецЕсли; //РаботаСФайлами.ОткрытьФормуИзображения(ЭтаФорма, ОсновноеИзображение, Ссылка); Форма = ОткрытьФорму(“ОбщаяФорма.ФормаИзображения”, , ЭтаФорма); КонецПроцедуры Осталось только написать запрос получения изображения из регистра для показа в формах. 6. Так как форм где необходимо отобразить изображение может быть много, функции из листинга 4.0 поместим в общий модуль. У меня общий модуль называется “Добавленные”.  

// листинг 4.0 

#Если Клиент Тогда функция ПолучитьКартинкиИзРегистра(объект) Экспорт Запрос = Новый Запрос; Запрос.Текст = “ВЫБРАТЬ | ИзображенияНоменклатуры.Путь |ИЗ | РегистрСведений.ИзображенияНоменклатуры КАК ИзображенияНоменклатуры |ГДЕ | ИзображенияНоменклатуры.Объект = &Объект | |УПОРЯДОЧИТЬ ПО | ИзображенияНоменклатуры.Основное УБЫВ”; Запрос.УстановитьПараметр(“Объект”, Объект); Результат = Запрос.Выполнить().Выгрузить(); Возврат Результат; КонецФункции Функция ПоказатьКартинкуИзРегистра(объект) Экспорт ПутьКСерверу = Константы.ПутьККартинкамНаСервере.Получить(); мКартинки = ПолучитьКартинкиИзРегистра(объект); Если мКартинки.количество() > 0 тогда ФайлКартинки = новый Файл(ПутьКСерверу+мКартинки[0].Путь); Если ФайлКартинки.Существует() и СтрДлина(мКартинки[0].Путь) > 0 тогда Картинка = новый Картинка(ПутьКСерверу+мКартинки[0].Путь); КонецЕсли; Иначе Картинка = новый Картинка(); КонецЕсли; Возврат картинка; КонецФункции #КонецЕсли
7. Пример из модуля формы элемента Номенклатуры в листинге 5.0
    // листинг 5.0 Процедура ПоказатьОсновноеИзображение() Экспорт Если ЭлементыФормы.ДействияФормы.Кнопки.Изображение.Пометка = Истина Тогда //Если мТекущееОсновноеИзображение = Неопределено Тогда // ЭлементыФормы.ОсновноеИзображение.Картинка = мПустаяКартинка; //Иначе // ЭлементыФормы.ОсновноеИзображение.Картинка = мТекущееОсновноеИзображение; //КонецЕсли; ЭлементыФормы.ОсновноеИзображение.Картинка = Добавленные.ПоказатьКартинкуИзРегистра(ЭтотОбъект.Ссылка); КонецЕсли; КонецПроцедуры // ПоказатьОсновноеИзображение() П.С. не забываем дать разрешение на чтение и запись в сетевой каталог для изображений.

Источник: https://infostart.ru/1c/articles/296744/

Как сохранять изображения в базу данных MS SQL и извлекать изображения из базы данных (C#)

Как хранить фото в бд

Разрабатывая инфраструктуру для автоматических тестов, а именно функционал отвечающий за хранения результатов тестирования в базе данных, мне необходимо было решить задачу хранения изображений в базе данных (Microsoft SQL Server). Изучив вопрос понял, что есть множество способов. Здесь рассмотрим два из них, которые я реализовал и выбрал оптимальный для себя.

Рассмотрим примеры записи картинок в базу данных и извлечение картинок из базы данных.

Хранение изображений в MS SQL в двоичном формате в ячейке с типом «image»

Создадим базу данных и таблицу:

USE [master] GO CREATE DATABASE [dbtest] ON PRIMARY ( NAME = N'dbtest', FILENAME = N'c:\DB\dbtest.mdf') LOG ON ( NAME = N'dbtest_log', FILENAME = N'c:\DB\dbtest.ldf') GO USE [dbtest] GO CREATE TABLE [report] ( [id] bigint NOT NULL PRIMARY KEY IDENTITY, [screen] IMAGE DEFAULT (0x), [screen_format] VARCHAR(5) DEFAULT NULL, );

Обратите внимание на тип поля «screen».

Поместим любую картинку на диск «С». У меня картинка в формате jpg — «primer.jpg».

Создадим в Visual Studio консольное приложение. Добавим в файл «Program.cs»

using System; using System.IO; using System.Collections.Generic; using System.Data.SqlClient; using System.Data; using System.Drawing; // в References подключить одноимённую библиотеку

Запишем изображение в базу данных методом PutImageBinaryInDb:

private static void PutImageBinaryInDb(string iFile) { // конвертация изображения в байты byte[] imageData = null; FileInfo fInfo = new FileInfo(iFile); long numBytes = fInfo.Length; FileStream fStream = new FileStream(iFile, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); imageData = br.ReadBytes((int)numBytes); // получение расширения файла изображения не забыв удалить точку перед расширением string iImageExtension = (Path.GetExtension(iFile)).Replace(“.”, “”).ToLower(); // запись изображения в БД using (SqlConnection sqlConnection = new SqlConnection(@”Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=dbtest; User Id=sa; Password=pass”)) // строка подключения к БД { string commandText = “INSERT INTO report (screen, screen_format) VALUES(@screen, @screen_format)”; // запрос на вставку SqlCommand command = new SqlCommand(commandText, sqlConnection); command.Parameters.AddWithValue(“@screen”, (object)imageData); // записываем само изображение command.Parameters.AddWithValue(“@screen_format”, iImageExtension); // записываем расширение изображения sqlConnection.Open(); command.ExecuteNonQuery(); sqlConnection.Close(); } }

Поместим вызов метода в Main:

static void Main(string[] args) { PutImageBinaryInDb(@”C:\primer.jpg”); // запись изображения в БД }

Запускаем приложение и проверяем базу данных. В базе должна появится запись:

Извлечём изображение из базы данных, для этого создадим метод GetImageBinaryFromDb:

private static void GetImageBinaryFromDb() { // получаем данные их БД List iScreen = new List(); // сделав запрос к БД мы получим множество строк в ответе, поэтому мы их сможем загнать в массив/List List iScreen_format = new List(); using (SqlConnection sqlConnection = new SqlConnection(@”Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=dbtest; User Id=sa; Password=pass”)) { sqlConnection.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = sqlConnection; sqlCommand.CommandText = @”SELECT [screen], [screen_format] FROM [report] WHERE [id] = 1″; // наша запись в БД под id=1, поэтому в запросе “WHERE [id] = 1” SqlDataReader sqlReader = sqlCommand.ExecuteReader(); byte[] iTrimByte = null; string iTrimText = null; while (sqlReader.Read()) // считываем и вносим в лист результаты { iTrimByte = (byte[])sqlReader[“screen”]; // читаем строки с изображениями iScreen.Add(iTrimByte); iTrimText = sqlReader[“screen_format”].ToString().TrimStart().TrimEnd(); // читаем строки с форматом изображения iScreen_format.Add(iTrimText); } sqlConnection.Close(); } // конвертируем бинарные данные в изображение byte[] imageData = iScreen[0]; // возвращает массив байт из БД. Так как у нас SQL вернёт одну запись и в ней хранится нужное нам изображение, то из листа берём единственное значение с индексом '0' MemoryStream ms = new MemoryStream(imageData); Image newImage = Image.FromStream(ms); // сохраняем изоражение на диск string iImageExtension = iScreen_format[0]; // получаем расширение текущего изображения хранящееся в БД string iImageName = @”C:\result_new” + “.” + iImageExtension; // задаём путь сохранения и имя нового изображения if (iImageExtension == “png”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Png); } else if (iImageExtension == “jpg” || iImageExtension == “jpeg”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Jpeg); } else if (iImageExtension == “gif”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Gif); } // и т.д., можно все if заменить на одну строку “newImage.Save(iImageName)”, насколько это правильно сказать не могу, но работает }

Поместим вызов метода в Main:

static void Main(string[] args) { GetImageBinaryFromDb(); }

Запускаем приложение и в указанное нами место сохраняется изображение из базы.

Данный метод я использую сейчас, так как в двоичном формате данные в базе занимают места меньше примерно в 100 раз по сравнению с методом, который я опишу дальше. Но возможно кому-то может понадобится описанный далее метод.

Хранение изображений в MS SQL в формате base64 в ячейке с типом «varchar»

В данном методе мы будем конвертировать изображения в base64. Создадим новую таблицу:

USE [dbtest] /* таблица для записи данных */ CREATE TABLE [report_base64] ( [id] bigint NOT NULL PRIMARY KEY IDENTITY, [screen] VARCHAR(MAX) DEFAULT NULL, [screen_format] VARCHAR(5) DEFAULT NULL, );

Обратите внимание на тип поля «screen».

Создадим метод PutImageBase64InDb:

private static void PutImageBase64InDb(string iFile) { // конвертация изображения в base64 string base64String = null; using (Image image = Image.FromFile(iFile)) { using (MemoryStream m = new MemoryStream()) { image.Save(m, image.RawFormat); byte[] imageBytes = m.ToArray(); base64String = Convert.ToBase64String(imageBytes); } } // получение расширения файла изображения не забыв удалить точку перед расширением string iImageExtension = (Path.GetExtension(iFile)).Replace(“.”, “”).ToLower(); // запись изображения в БД using (SqlConnection sqlConnection = new SqlConnection(@”Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=dbtest; User Id=sa; Password=saSA”)) // строка подключения к БД { string commandText = “INSERT INTO report_base64 (screen, screen_format) VALUES(@screen, @screen_format)”; // запрос на вставку SqlCommand command = new SqlCommand(commandText, sqlConnection); command.Parameters.AddWithValue(“@screen”, base64String); // записываем само изображение command.Parameters.AddWithValue(“@screen_format”, iImageExtension); // записываем расширение изображения sqlConnection.Open(); command.ExecuteNonQuery(); sqlConnection.Close(); } }

Поместим вызов метода в Main:

static void Main(string[] args) { PutImageBase64InDb(@”C:\primer.jpg”); // запись изображения в БД }

Запускаем приложение и проверяем базу данных. В базе должна появится запись:

Извлечём изображение из базы данных, для этого создадим метод GetImageBase64FromDb:

private static void GetImageBase64FromDb() { // получаем данные их БД List iScreen = new List(); // сделав запрос к БД мы получим множество строк в ответе, поэтому мы их сможем загнать в массив/List List iScreen_format = new List(); using (SqlConnection sqlConnection = new SqlConnection(@”Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=dbtest; User Id=sa; Password=saSA”)) { sqlConnection.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = sqlConnection; sqlCommand.CommandText = @”SELECT [screen], [screen_format] FROM [report_base64] WHERE [id] = 1″; // наша запись в БД под id=1, поэтому в запросе “WHERE [id] = 1” SqlDataReader sqlReader = sqlCommand.ExecuteReader(); string iTrimText = null; while (sqlReader.Read()) // считываем и вносим в лист результаты { iTrimText = sqlReader[“screen”].ToString().TrimStart().TrimEnd(); // читаем строки с изображениями iScreen.Add(iTrimText); iTrimText = sqlReader[“screen_format”].ToString().TrimStart().TrimEnd(); // читаем строки с форматом изображения iScreen_format.Add(iTrimText); } sqlConnection.Close(); } // конвертируем данные в изображение string base64StringImage = iScreen[0]; // возвращает массив байт из БД. Так как у нас SQL вернёт одну запись и в ней хранится нужное нам изображение, то из листа берём единственное значение с индексом '0' byte[] imageData = Convert.FromBase64String(base64StringImage); MemoryStream ms = new MemoryStream(imageData); Image newImage = Image.FromStream(ms); // сохраняем изоражение на диск string iImageExtension = iScreen_format[0]; // получаем расширение текущего изображения хранящееся в БД string iImageName = @”C:\result_new_base64″ + “.” + iImageExtension; // задаём путь сохранения и имя нового изображения if (iImageExtension == “png”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Png); } else if (iImageExtension == “jpg” || iImageExtension == “jpeg”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Jpeg); } else if (iImageExtension == “gif”) { newImage.Save(iImageName, System.Drawing.Imaging.ImageFormat.Gif); } // и т.д., можно все if заменить на одну строку “newImage.Save(iImageName)”, насколько это правильно сказать не могу, но работает }

Поместим вызов метода в Main:

static void Main(string[] args) { GetImageBase64FromDb(); }

Запускаем приложение и в указанное нами место сохраняется изображение из базы.

Вот и рассмотрели с вами методы сохранения изображения в базу данных MS SQL и извлечения изображения из базы данных. Есть ещё метод с использованием FILESTREAM, когда изображение пишется в файловую систему, но работа с ним идёт через обычное обращение к БД, но этот метод я не рассматривал, так как мне он пока не нужен.

Приложил для примера проект консольного приложения, которое содержит все описанные мной методы: скачать пример.

Источник: https://victorz.ru/20170924638

Поделиться:
Нет комментариев

    Добавить комментарий

    Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.